indent
This commit is contained in:
parent
23efed6966
commit
689f71d6e8
1 changed files with 385 additions and 385 deletions
|
@ -135,14 +135,14 @@ public:
|
||||||
UCHAR h[UDIHLEN];
|
UCHAR h[UDIHLEN];
|
||||||
|
|
||||||
UdiH(const string& udi)
|
UdiH(const string& udi)
|
||||||
{
|
{
|
||||||
MD5_CTX ctx;
|
MD5_CTX ctx;
|
||||||
MD5Init(&ctx);
|
MD5Init(&ctx);
|
||||||
MD5Update(&ctx, (const UCHAR*)udi.c_str(), udi.length());
|
MD5Update(&ctx, (const UCHAR*)udi.c_str(), udi.length());
|
||||||
UCHAR md[16];
|
UCHAR md[16];
|
||||||
MD5Final(md, &ctx);
|
MD5Final(md, &ctx);
|
||||||
memcpy(h, md, UDIHLEN);
|
memcpy(h, md, UDIHLEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
string asHexString() const {
|
string asHexString() const {
|
||||||
static const char hex[]="0123456789abcdef";
|
static const char hex[]="0123456789abcdef";
|
||||||
|
@ -154,22 +154,22 @@ public:
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
bool operator==(const UdiH& r) const
|
bool operator==(const UdiH& r) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < UDIHLEN; i++)
|
for (int i = 0; i < UDIHLEN; i++)
|
||||||
if (h[i] != r.h[i])
|
if (h[i] != r.h[i])
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool operator<(const UdiH& r) const
|
bool operator<(const UdiH& r) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < UDIHLEN; i++) {
|
for (int i = 0; i < UDIHLEN; i++) {
|
||||||
if (h[i] < r.h[i])
|
if (h[i] < r.h[i])
|
||||||
return true;
|
return true;
|
||||||
if (h[i] > r.h[i])
|
if (h[i] > r.h[i])
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
typedef multimap<UdiH, off_t> kh_type;
|
typedef multimap<UdiH, off_t> kh_type;
|
||||||
typedef multimap<UdiH, off_t>::value_type kh_value_type;
|
typedef multimap<UdiH, off_t>::value_type kh_value_type;
|
||||||
|
@ -209,415 +209,415 @@ public:
|
||||||
|
|
||||||
// Add udi->offset translation to map
|
// Add udi->offset translation to map
|
||||||
bool khEnter(const string& udi, off_t ofs)
|
bool khEnter(const string& udi, off_t ofs)
|
||||||
{
|
{
|
||||||
UdiH h(udi);
|
UdiH h(udi);
|
||||||
|
|
||||||
LOGDEB2(("Circache::khEnter: h %s offs %lu udi [%s]\n",
|
LOGDEB2(("Circache::khEnter: h %s offs %lu udi [%s]\n",
|
||||||
h.asHexString().c_str(), (ULONG)ofs, udi.c_str()));
|
h.asHexString().c_str(), (ULONG)ofs, udi.c_str()));
|
||||||
|
|
||||||
pair<kh_type::iterator, kh_type::iterator> p = m_ofskh.equal_range(h);
|
pair<kh_type::iterator, kh_type::iterator> p = m_ofskh.equal_range(h);
|
||||||
|
|
||||||
if (p.first != m_ofskh.end() && p.first->first == h) {
|
if (p.first != m_ofskh.end() && p.first->first == h) {
|
||||||
for (kh_type::iterator it = p.first; it != p.second; it++) {
|
for (kh_type::iterator it = p.first; it != p.second; it++) {
|
||||||
LOGDEB2(("Circache::khEnter: col h %s, ofs %lu\n",
|
LOGDEB2(("Circache::khEnter: col h %s, ofs %lu\n",
|
||||||
it->first.asHexString().c_str(),
|
it->first.asHexString().c_str(),
|
||||||
(ULONG)it->second));
|
(ULONG)it->second));
|
||||||
if (it->second == ofs) {
|
if (it->second == ofs) {
|
||||||
// (h,offs) already there. Happens
|
// (h,offs) already there. Happens
|
||||||
LOGDEB2(("Circache::khEnter: already there\n"));
|
LOGDEB2(("Circache::khEnter: already there\n"));
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_ofskh.insert(kh_value_type(h, ofs));
|
||||||
|
LOGDEB2(("Circache::khEnter: inserted\n"));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
m_ofskh.insert(kh_value_type(h, ofs));
|
|
||||||
LOGDEB2(("Circache::khEnter: inserted\n"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
void khDump()
|
void khDump()
|
||||||
{
|
{
|
||||||
for (kh_type::const_iterator it = m_ofskh.begin();
|
for (kh_type::const_iterator it = m_ofskh.begin();
|
||||||
it != m_ofskh.end(); it++) {
|
it != m_ofskh.end(); it++) {
|
||||||
LOGDEB(("Circache::KHDUMP: %s %d\n",
|
LOGDEB(("Circache::KHDUMP: %s %d\n",
|
||||||
it->first.asHexString().c_str(), (ULONG)it->second));
|
it->first.asHexString().c_str(), (ULONG)it->second));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Return vector of candidate offsets for udi (possibly several
|
// Return vector of candidate offsets for udi (possibly several
|
||||||
// because there may be hash collisions, and also multiple
|
// because there may be hash collisions, and also multiple
|
||||||
// instances).
|
// instances).
|
||||||
bool khFind(const string& udi, vector<off_t>& ofss)
|
bool khFind(const string& udi, vector<off_t>& ofss)
|
||||||
{
|
{
|
||||||
ofss.clear();
|
ofss.clear();
|
||||||
|
|
||||||
UdiH h(udi);
|
UdiH h(udi);
|
||||||
|
|
||||||
LOGDEB2(("Circache::khFind: h %s udi [%s]\n",
|
LOGDEB2(("Circache::khFind: h %s udi [%s]\n",
|
||||||
h.asHexString().c_str(), udi.c_str()));
|
h.asHexString().c_str(), udi.c_str()));
|
||||||
|
|
||||||
pair<kh_type::iterator, kh_type::iterator> p = m_ofskh.equal_range(h);
|
pair<kh_type::iterator, kh_type::iterator> p = m_ofskh.equal_range(h);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (p.first == m_ofskh.end()) LOGDEB(("KHFIND: FIRST END()\n"));
|
if (p.first == m_ofskh.end()) LOGDEB(("KHFIND: FIRST END()\n"));
|
||||||
if (p.second == m_ofskh.end()) LOGDEB(("KHFIND: SECOND END()\n"));
|
if (p.second == m_ofskh.end()) LOGDEB(("KHFIND: SECOND END()\n"));
|
||||||
if (!(p.first->first == h))
|
if (!(p.first->first == h))
|
||||||
LOGDEB(("KHFIND: NOKEY: %s %s\n",
|
LOGDEB(("KHFIND: NOKEY: %s %s\n",
|
||||||
p.first->first.asHexString().c_str(),
|
p.first->first.asHexString().c_str(),
|
||||||
p.second->first.asHexString().c_str()));
|
p.second->first.asHexString().c_str()));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (p.first == m_ofskh.end() || !(p.first->first == h))
|
if (p.first == m_ofskh.end() || !(p.first->first == h))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (kh_type::iterator it = p.first; it != p.second; it++) {
|
for (kh_type::iterator it = p.first; it != p.second; it++) {
|
||||||
ofss.push_back(it->second);
|
ofss.push_back(it->second);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// Clear entry for udi/offs
|
// Clear entry for udi/offs
|
||||||
bool khClear(const pair<string, off_t>& ref)
|
bool khClear(const pair<string, off_t>& ref)
|
||||||
{
|
{
|
||||||
UdiH h(ref.first);
|
UdiH h(ref.first);
|
||||||
pair<kh_type::iterator, kh_type::iterator> p = m_ofskh.equal_range(h);
|
pair<kh_type::iterator, kh_type::iterator> p = m_ofskh.equal_range(h);
|
||||||
if (p.first != m_ofskh.end() && (p.first->first == h)) {
|
if (p.first != m_ofskh.end() && (p.first->first == h)) {
|
||||||
for (kh_type::iterator it = p.first; it != p.second; ) {
|
for (kh_type::iterator it = p.first; it != p.second; ) {
|
||||||
kh_type::iterator tmp = it++;
|
kh_type::iterator tmp = it++;
|
||||||
if (tmp->second == ref.second)
|
if (tmp->second == ref.second)
|
||||||
m_ofskh.erase(tmp);
|
m_ofskh.erase(tmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// Clear entries for vector of udi/offs
|
// Clear entries for vector of udi/offs
|
||||||
bool khClear(const vector<pair<string, off_t> >& udis)
|
bool khClear(const vector<pair<string, off_t> >& udis)
|
||||||
{
|
{
|
||||||
for (vector<pair<string, off_t> >::const_iterator it = udis.begin();
|
for (vector<pair<string, off_t> >::const_iterator it = udis.begin();
|
||||||
it != udis.end(); it++)
|
it != udis.end(); it++)
|
||||||
khClear(*it);
|
khClear(*it);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Clear all entries for udi
|
// Clear all entries for udi
|
||||||
bool khClear(const string& udi)
|
bool khClear(const string& udi)
|
||||||
{
|
{
|
||||||
UdiH h(udi);
|
UdiH h(udi);
|
||||||
pair<kh_type::iterator, kh_type::iterator> p = m_ofskh.equal_range(h);
|
pair<kh_type::iterator, kh_type::iterator> p = m_ofskh.equal_range(h);
|
||||||
if (p.first != m_ofskh.end() && (p.first->first == h)) {
|
if (p.first != m_ofskh.end() && (p.first->first == h)) {
|
||||||
for (kh_type::iterator it = p.first; it != p.second; ) {
|
for (kh_type::iterator it = p.first; it != p.second; ) {
|
||||||
kh_type::iterator tmp = it++;
|
kh_type::iterator tmp = it++;
|
||||||
m_ofskh.erase(tmp);
|
m_ofskh.erase(tmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
CirCacheInternal()
|
CirCacheInternal()
|
||||||
: m_fd(-1), m_maxsize(-1), m_oheadoffs(-1),
|
: m_fd(-1), m_maxsize(-1), m_oheadoffs(-1),
|
||||||
m_nheadoffs(0), m_npadsize(0), m_uniquentries(false),
|
m_nheadoffs(0), m_npadsize(0), m_uniquentries(false),
|
||||||
m_buffer(0), m_bufsiz(0), m_ofskhcplt(false)
|
m_buffer(0), m_bufsiz(0), m_ofskhcplt(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
~CirCacheInternal()
|
~CirCacheInternal()
|
||||||
{
|
{
|
||||||
if (m_fd >= 0)
|
if (m_fd >= 0)
|
||||||
close(m_fd);
|
close(m_fd);
|
||||||
if (m_buffer)
|
if (m_buffer)
|
||||||
free(m_buffer);
|
free(m_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *buf(size_t sz)
|
char *buf(size_t sz)
|
||||||
{
|
{
|
||||||
if (m_bufsiz >= sz)
|
if (m_bufsiz >= sz)
|
||||||
|
return m_buffer;
|
||||||
|
if ((m_buffer = (char *)realloc(m_buffer, sz))) {
|
||||||
|
m_bufsiz = sz;
|
||||||
|
} else {
|
||||||
|
m_reason << "CirCache:: realloc(" << sz << ") failed";
|
||||||
|
m_bufsiz = 0;
|
||||||
|
}
|
||||||
return m_buffer;
|
return m_buffer;
|
||||||
if ((m_buffer = (char *)realloc(m_buffer, sz))) {
|
|
||||||
m_bufsiz = sz;
|
|
||||||
} else {
|
|
||||||
m_reason << "CirCache:: realloc(" << sz << ") failed";
|
|
||||||
m_bufsiz = 0;
|
|
||||||
}
|
}
|
||||||
return m_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name for the cache file
|
// Name for the cache file
|
||||||
string datafn(const string& d)
|
string datafn(const string& d)
|
||||||
{
|
{
|
||||||
return path_cat(d, "circache.crch");
|
return path_cat(d, "circache.crch");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool writefirstblock()
|
bool writefirstblock()
|
||||||
{
|
{
|
||||||
if (m_fd < 0) {
|
if (m_fd < 0) {
|
||||||
m_reason << "writefirstblock: not open ";
|
m_reason << "writefirstblock: not open ";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ostringstream s;
|
ostringstream s;
|
||||||
s <<
|
s <<
|
||||||
"maxsize = " << m_maxsize << "\n" <<
|
"maxsize = " << m_maxsize << "\n" <<
|
||||||
"oheadoffs = " << m_oheadoffs << "\n" <<
|
"oheadoffs = " << m_oheadoffs << "\n" <<
|
||||||
"nheadoffs = " << m_nheadoffs << "\n" <<
|
"nheadoffs = " << m_nheadoffs << "\n" <<
|
||||||
"npadsize = " << m_npadsize << "\n" <<
|
"npadsize = " << m_npadsize << "\n" <<
|
||||||
"unient = " << m_uniquentries << "\n" <<
|
"unient = " << m_uniquentries << "\n" <<
|
||||||
" " <<
|
" " <<
|
||||||
" " <<
|
" " <<
|
||||||
" " <<
|
" " <<
|
||||||
"\0";
|
"\0";
|
||||||
|
|
||||||
int sz = int(s.str().size());
|
int sz = int(s.str().size());
|
||||||
assert(sz < CIRCACHE_FIRSTBLOCK_SIZE);
|
assert(sz < CIRCACHE_FIRSTBLOCK_SIZE);
|
||||||
lseek(m_fd, 0, 0);
|
lseek(m_fd, 0, 0);
|
||||||
if (write(m_fd, s.str().c_str(), sz) != sz) {
|
if (write(m_fd, s.str().c_str(), sz) != sz) {
|
||||||
m_reason << "writefirstblock: write() failed: errno " << errno;
|
m_reason << "writefirstblock: write() failed: errno " << errno;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool readfirstblock()
|
bool readfirstblock()
|
||||||
{
|
{
|
||||||
if (m_fd < 0) {
|
if (m_fd < 0) {
|
||||||
m_reason << "readfirstblock: not open ";
|
m_reason << "readfirstblock: not open ";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
char bf[CIRCACHE_FIRSTBLOCK_SIZE];
|
char bf[CIRCACHE_FIRSTBLOCK_SIZE];
|
||||||
|
|
||||||
lseek(m_fd, 0, 0);
|
lseek(m_fd, 0, 0);
|
||||||
if (read(m_fd, bf, CIRCACHE_FIRSTBLOCK_SIZE) !=
|
if (read(m_fd, bf, CIRCACHE_FIRSTBLOCK_SIZE) !=
|
||||||
CIRCACHE_FIRSTBLOCK_SIZE) {
|
CIRCACHE_FIRSTBLOCK_SIZE) {
|
||||||
m_reason << "readfirstblock: read() failed: errno " << errno;
|
m_reason << "readfirstblock: read() failed: errno " << errno;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
string s(bf, CIRCACHE_FIRSTBLOCK_SIZE);
|
||||||
|
ConfSimple conf(s, 1);
|
||||||
|
string value;
|
||||||
|
if (!conf.get("maxsize", value, cstr_null)) {
|
||||||
|
m_reason << "readfirstblock: conf get maxsize failed";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_maxsize = atoll(value.c_str());
|
||||||
|
if (!conf.get("oheadoffs", value, cstr_null)) {
|
||||||
|
m_reason << "readfirstblock: conf get oheadoffs failed";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_oheadoffs = atoll(value.c_str());
|
||||||
|
if (!conf.get("nheadoffs", value, cstr_null)) {
|
||||||
|
m_reason << "readfirstblock: conf get nheadoffs failed";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_nheadoffs = atoll(value.c_str());
|
||||||
|
if (!conf.get("npadsize", value, cstr_null)) {
|
||||||
|
m_reason << "readfirstblock: conf get npadsize failed";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_npadsize = atoll(value.c_str());
|
||||||
|
if (!conf.get("unient", value, cstr_null)) {
|
||||||
|
m_uniquentries = false;
|
||||||
|
} else {
|
||||||
|
m_uniquentries = stringToBool(value);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
string s(bf, CIRCACHE_FIRSTBLOCK_SIZE);
|
|
||||||
ConfSimple conf(s, 1);
|
|
||||||
string value;
|
|
||||||
if (!conf.get("maxsize", value, cstr_null)) {
|
|
||||||
m_reason << "readfirstblock: conf get maxsize failed";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
m_maxsize = atoll(value.c_str());
|
|
||||||
if (!conf.get("oheadoffs", value, cstr_null)) {
|
|
||||||
m_reason << "readfirstblock: conf get oheadoffs failed";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
m_oheadoffs = atoll(value.c_str());
|
|
||||||
if (!conf.get("nheadoffs", value, cstr_null)) {
|
|
||||||
m_reason << "readfirstblock: conf get nheadoffs failed";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
m_nheadoffs = atoll(value.c_str());
|
|
||||||
if (!conf.get("npadsize", value, cstr_null)) {
|
|
||||||
m_reason << "readfirstblock: conf get npadsize failed";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
m_npadsize = atoll(value.c_str());
|
|
||||||
if (!conf.get("unient", value, cstr_null)) {
|
|
||||||
m_uniquentries = false;
|
|
||||||
} else {
|
|
||||||
m_uniquentries = stringToBool(value);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool writeEntryHeader(off_t offset, const EntryHeaderData& d)
|
bool writeEntryHeader(off_t offset, const EntryHeaderData& d)
|
||||||
{
|
{
|
||||||
if (m_fd < 0) {
|
if (m_fd < 0) {
|
||||||
m_reason << "writeEntryHeader: not open ";
|
m_reason << "writeEntryHeader: not open ";
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
char bf[CIRCACHE_HEADER_SIZE];
|
||||||
|
memset(bf, 0, CIRCACHE_HEADER_SIZE);
|
||||||
|
snprintf(bf, CIRCACHE_HEADER_SIZE,
|
||||||
|
headerformat, d.dicsize, d.datasize, d.padsize, d.flags);
|
||||||
|
if (lseek(m_fd, offset, 0) != offset) {
|
||||||
|
m_reason << "CirCache::weh: lseek(" << offset <<
|
||||||
|
") failed: errno " << errno;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (write(m_fd, bf, CIRCACHE_HEADER_SIZE) != CIRCACHE_HEADER_SIZE) {
|
||||||
|
m_reason << "CirCache::weh: write failed. errno " << errno;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
char bf[CIRCACHE_HEADER_SIZE];
|
|
||||||
memset(bf, 0, CIRCACHE_HEADER_SIZE);
|
|
||||||
snprintf(bf, CIRCACHE_HEADER_SIZE,
|
|
||||||
headerformat, d.dicsize, d.datasize, d.padsize, d.flags);
|
|
||||||
if (lseek(m_fd, offset, 0) != offset) {
|
|
||||||
m_reason << "CirCache::weh: lseek(" << offset <<
|
|
||||||
") failed: errno " << errno;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (write(m_fd, bf, CIRCACHE_HEADER_SIZE) != CIRCACHE_HEADER_SIZE) {
|
|
||||||
m_reason << "CirCache::weh: write failed. errno " << errno;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CCScanHook::status readEntryHeader(off_t offset, EntryHeaderData& d)
|
CCScanHook::status readEntryHeader(off_t offset, EntryHeaderData& d)
|
||||||
{
|
{
|
||||||
if (m_fd < 0) {
|
if (m_fd < 0) {
|
||||||
m_reason << "readEntryHeader: not open ";
|
m_reason << "readEntryHeader: not open ";
|
||||||
return CCScanHook::Error;
|
return CCScanHook::Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lseek(m_fd, offset, 0) != offset) {
|
if (lseek(m_fd, offset, 0) != offset) {
|
||||||
m_reason << "readEntryHeader: lseek(" << offset <<
|
m_reason << "readEntryHeader: lseek(" << offset <<
|
||||||
") failed: errno " << errno;
|
") failed: errno " << errno;
|
||||||
return CCScanHook::Error;
|
return CCScanHook::Error;
|
||||||
}
|
}
|
||||||
char bf[CIRCACHE_HEADER_SIZE];
|
char bf[CIRCACHE_HEADER_SIZE];
|
||||||
|
|
||||||
int ret = read(m_fd, bf, CIRCACHE_HEADER_SIZE);
|
int ret = read(m_fd, bf, CIRCACHE_HEADER_SIZE);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
// Eof
|
// Eof
|
||||||
m_reason << " Eof ";
|
m_reason << " Eof ";
|
||||||
return CCScanHook::Eof;
|
return CCScanHook::Eof;
|
||||||
|
}
|
||||||
|
if (ret != CIRCACHE_HEADER_SIZE) {
|
||||||
|
m_reason << " readheader: read failed errno " << errno;
|
||||||
|
return CCScanHook::Error;
|
||||||
|
}
|
||||||
|
if (sscanf(bf, headerformat, &d.dicsize, &d.datasize,
|
||||||
|
&d.padsize, &d.flags) != 4) {
|
||||||
|
m_reason << " readEntryHeader: bad header at " <<
|
||||||
|
offset << " [" << bf << "]";
|
||||||
|
return CCScanHook::Error;
|
||||||
|
}
|
||||||
|
LOGDEB2(("Circache:readEntryHeader: dcsz %u dtsz %u pdsz %u flgs %hu\n",
|
||||||
|
d.dicsize, d.datasize, d.padsize, d.flags));
|
||||||
|
return CCScanHook::Continue;
|
||||||
}
|
}
|
||||||
if (ret != CIRCACHE_HEADER_SIZE) {
|
|
||||||
m_reason << " readheader: read failed errno " << errno;
|
|
||||||
return CCScanHook::Error;
|
|
||||||
}
|
|
||||||
if (sscanf(bf, headerformat, &d.dicsize, &d.datasize,
|
|
||||||
&d.padsize, &d.flags) != 4) {
|
|
||||||
m_reason << " readEntryHeader: bad header at " <<
|
|
||||||
offset << " [" << bf << "]";
|
|
||||||
return CCScanHook::Error;
|
|
||||||
}
|
|
||||||
LOGDEB2(("Circache:readEntryHeader: dcsz %u dtsz %u pdsz %u flgs %hu\n",
|
|
||||||
d.dicsize, d.datasize, d.padsize, d.flags));
|
|
||||||
return CCScanHook::Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
CCScanHook::status scan(off_t startoffset, CCScanHook *user,
|
CCScanHook::status scan(off_t startoffset, CCScanHook *user,
|
||||||
bool fold = false)
|
bool fold = false)
|
||||||
{
|
{
|
||||||
if (m_fd < 0) {
|
if (m_fd < 0) {
|
||||||
m_reason << "scan: not open ";
|
m_reason << "scan: not open ";
|
||||||
return CCScanHook::Error;
|
return CCScanHook::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t so0 = startoffset;
|
||||||
|
bool already_folded = false;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (already_folded && startoffset == so0) {
|
||||||
|
m_ofskhcplt = true;
|
||||||
|
return CCScanHook::Eof;
|
||||||
|
}
|
||||||
|
|
||||||
|
EntryHeaderData d;
|
||||||
|
CCScanHook::status st;
|
||||||
|
switch ((st = readEntryHeader(startoffset, d))) {
|
||||||
|
case CCScanHook::Continue: break;
|
||||||
|
case CCScanHook::Eof:
|
||||||
|
if (fold && !already_folded) {
|
||||||
|
already_folded = true;
|
||||||
|
startoffset = CIRCACHE_FIRSTBLOCK_SIZE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
default:
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
string udi;
|
||||||
|
if (d.dicsize) {
|
||||||
|
// d.dicsize is 0 for erased entries
|
||||||
|
char *bf;
|
||||||
|
if ((bf = buf(d.dicsize+1)) == 0) {
|
||||||
|
return CCScanHook::Error;
|
||||||
|
}
|
||||||
|
bf[d.dicsize] = 0;
|
||||||
|
if (read(m_fd, bf, d.dicsize) != int(d.dicsize)) {
|
||||||
|
m_reason << "scan: read failed errno " << errno;
|
||||||
|
return CCScanHook::Error;
|
||||||
|
}
|
||||||
|
string b(bf, d.dicsize);
|
||||||
|
ConfSimple conf(b, 1);
|
||||||
|
|
||||||
|
if (!conf.get("udi", udi, cstr_null)) {
|
||||||
|
m_reason << "scan: no udi in dic";
|
||||||
|
return CCScanHook::Error;
|
||||||
|
}
|
||||||
|
khEnter(udi, startoffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call callback
|
||||||
|
CCScanHook::status a =
|
||||||
|
user->takeone(startoffset, udi, d);
|
||||||
|
switch (a) {
|
||||||
|
case CCScanHook::Continue:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
startoffset += CIRCACHE_HEADER_SIZE + d.dicsize +
|
||||||
|
d.datasize + d.padsize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t so0 = startoffset;
|
|
||||||
bool already_folded = false;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
if (already_folded && startoffset == so0) {
|
|
||||||
m_ofskhcplt = true;
|
|
||||||
return CCScanHook::Eof;
|
|
||||||
}
|
|
||||||
|
|
||||||
EntryHeaderData d;
|
|
||||||
CCScanHook::status st;
|
|
||||||
switch ((st = readEntryHeader(startoffset, d))) {
|
|
||||||
case CCScanHook::Continue: break;
|
|
||||||
case CCScanHook::Eof:
|
|
||||||
if (fold && !already_folded) {
|
|
||||||
already_folded = true;
|
|
||||||
startoffset = CIRCACHE_FIRSTBLOCK_SIZE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
default:
|
|
||||||
return st;
|
|
||||||
}
|
|
||||||
|
|
||||||
string udi;
|
|
||||||
if (d.dicsize) {
|
|
||||||
// d.dicsize is 0 for erased entries
|
|
||||||
char *bf;
|
|
||||||
if ((bf = buf(d.dicsize+1)) == 0) {
|
|
||||||
return CCScanHook::Error;
|
|
||||||
}
|
|
||||||
bf[d.dicsize] = 0;
|
|
||||||
if (read(m_fd, bf, d.dicsize) != int(d.dicsize)) {
|
|
||||||
m_reason << "scan: read failed errno " << errno;
|
|
||||||
return CCScanHook::Error;
|
|
||||||
}
|
|
||||||
string b(bf, d.dicsize);
|
|
||||||
ConfSimple conf(b, 1);
|
|
||||||
|
|
||||||
if (!conf.get("udi", udi, cstr_null)) {
|
|
||||||
m_reason << "scan: no udi in dic";
|
|
||||||
return CCScanHook::Error;
|
|
||||||
}
|
|
||||||
khEnter(udi, startoffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call callback
|
|
||||||
CCScanHook::status a =
|
|
||||||
user->takeone(startoffset, udi, d);
|
|
||||||
switch (a) {
|
|
||||||
case CCScanHook::Continue:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
startoffset += CIRCACHE_HEADER_SIZE + d.dicsize +
|
|
||||||
d.datasize + d.padsize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool readHUdi(off_t hoffs, EntryHeaderData& d, string& udi)
|
bool readHUdi(off_t hoffs, EntryHeaderData& d, string& udi)
|
||||||
{
|
{
|
||||||
if (readEntryHeader(hoffs, d) != CCScanHook::Continue)
|
if (readEntryHeader(hoffs, d) != CCScanHook::Continue)
|
||||||
return false;
|
return false;
|
||||||
string dic;
|
string dic;
|
||||||
if (!readDicData(hoffs, d, dic, 0))
|
if (!readDicData(hoffs, d, dic, 0))
|
||||||
return false;
|
return false;
|
||||||
if (d.dicsize == 0) {
|
if (d.dicsize == 0) {
|
||||||
// This is an erased entry
|
// This is an erased entry
|
||||||
udi.erase();
|
udi.erase();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
ConfSimple conf(dic);
|
||||||
|
if (!conf.get("udi", udi)) {
|
||||||
|
m_reason << "Bad file: no udi in dic";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
ConfSimple conf(dic);
|
|
||||||
if (!conf.get("udi", udi)) {
|
|
||||||
m_reason << "Bad file: no udi in dic";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool readDicData(off_t hoffs, EntryHeaderData& hd, string& dic,
|
bool readDicData(off_t hoffs, EntryHeaderData& hd, string& dic,
|
||||||
string* data)
|
string* data)
|
||||||
{
|
{
|
||||||
off_t offs = hoffs + CIRCACHE_HEADER_SIZE;
|
off_t offs = hoffs + CIRCACHE_HEADER_SIZE;
|
||||||
// This syscall could be avoided in some cases if we saved the offset
|
// This syscall could be avoided in some cases if we saved the offset
|
||||||
// at each seek. In most cases, we just read the header and we are
|
// at each seek. In most cases, we just read the header and we are
|
||||||
// at the right position
|
// at the right position
|
||||||
if (lseek(m_fd, offs, 0) != offs) {
|
if (lseek(m_fd, offs, 0) != offs) {
|
||||||
m_reason << "CirCache::get: lseek(" << offs << ") failed: " <<
|
m_reason << "CirCache::get: lseek(" << offs << ") failed: " <<
|
||||||
errno;
|
errno;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
char *bf = 0;
|
|
||||||
if (hd.dicsize) {
|
|
||||||
bf = buf(hd.dicsize);
|
|
||||||
if (bf == 0)
|
|
||||||
return false;
|
|
||||||
if (read(m_fd, bf, hd.dicsize) != int(hd.dicsize)) {
|
|
||||||
m_reason << "CirCache::get: read() failed: errno " << errno;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
dic.assign(bf, hd.dicsize);
|
char *bf = 0;
|
||||||
} else {
|
if (hd.dicsize) {
|
||||||
dic.erase();
|
bf = buf(hd.dicsize);
|
||||||
}
|
if (bf == 0)
|
||||||
if (data == 0)
|
return false;
|
||||||
return true;
|
if (read(m_fd, bf, hd.dicsize) != int(hd.dicsize)) {
|
||||||
|
m_reason << "CirCache::get: read() failed: errno " << errno;
|
||||||
if (hd.datasize) {
|
|
||||||
bf = buf(hd.datasize);
|
|
||||||
if (bf == 0)
|
|
||||||
return false;
|
|
||||||
if (read(m_fd, bf, hd.datasize) != int(hd.datasize)){
|
|
||||||
m_reason << "CirCache::get: read() failed: errno " << errno;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hd.flags & EFDataCompressed) {
|
|
||||||
LOGDEB1(("Circache:readdicdata: data compressed\n"));
|
|
||||||
void *uncomp;
|
|
||||||
unsigned int uncompsize;
|
|
||||||
if (!inflateToDynBuf(bf, hd.datasize, &uncomp, &uncompsize)) {
|
|
||||||
m_reason << "CirCache: decompression failed ";
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
data->assign((char *)uncomp, uncompsize);
|
dic.assign(bf, hd.dicsize);
|
||||||
free(uncomp);
|
|
||||||
} else {
|
} else {
|
||||||
LOGDEB1(("Circache:readdicdata: data NOT compressed\n"));
|
dic.erase();
|
||||||
data->assign(bf, hd.datasize);
|
|
||||||
}
|
}
|
||||||
} else {
|
if (data == 0)
|
||||||
data->erase();
|
return true;
|
||||||
|
|
||||||
|
if (hd.datasize) {
|
||||||
|
bf = buf(hd.datasize);
|
||||||
|
if (bf == 0)
|
||||||
|
return false;
|
||||||
|
if (read(m_fd, bf, hd.datasize) != int(hd.datasize)){
|
||||||
|
m_reason << "CirCache::get: read() failed: errno " << errno;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hd.flags & EFDataCompressed) {
|
||||||
|
LOGDEB1(("Circache:readdicdata: data compressed\n"));
|
||||||
|
void *uncomp;
|
||||||
|
unsigned int uncompsize;
|
||||||
|
if (!inflateToDynBuf(bf, hd.datasize, &uncomp, &uncompsize)) {
|
||||||
|
m_reason << "CirCache: decompression failed ";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
data->assign((char *)uncomp, uncompsize);
|
||||||
|
free(uncomp);
|
||||||
|
} else {
|
||||||
|
LOGDEB1(("Circache:readdicdata: data NOT compressed\n"));
|
||||||
|
data->assign(bf, hd.datasize);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data->erase();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -648,17 +648,17 @@ public:
|
||||||
off_t padsize;
|
off_t padsize;
|
||||||
CCScanHookRecord()
|
CCScanHookRecord()
|
||||||
: headoffs(0), padsize(0)
|
: headoffs(0), padsize(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
virtual status takeone(off_t offs, const string& udi,
|
virtual status takeone(off_t offs, const string& udi,
|
||||||
const EntryHeaderData& d)
|
const EntryHeaderData& d)
|
||||||
{
|
{
|
||||||
headoffs = offs;
|
headoffs = offs;
|
||||||
padsize = d.padsize;
|
padsize = d.padsize;
|
||||||
LOGDEB2(("CCScanHookRecord::takeone: offs %s padsize %s\n",
|
LOGDEB2(("CCScanHookRecord::takeone: offs %s padsize %s\n",
|
||||||
lltodecstr(headoffs).c_str(), lltodecstr(padsize).c_str()));
|
lltodecstr(headoffs).c_str(), lltodecstr(padsize).c_str()));
|
||||||
return Continue;
|
return Continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
string CirCache::getpath()
|
string CirCache::getpath()
|
||||||
|
@ -711,12 +711,12 @@ bool CirCache::create(off_t maxsize, int flags)
|
||||||
m_d->m_maxsize = maxsize;
|
m_d->m_maxsize = maxsize;
|
||||||
m_d->m_uniquentries = ((flags & CC_CRUNIQUE) != 0);
|
m_d->m_uniquentries = ((flags & CC_CRUNIQUE) != 0);
|
||||||
LOGDEB2(("CirCache::create: rewriting header with "
|
LOGDEB2(("CirCache::create: rewriting header with "
|
||||||
"maxsize %s oheadoffs %s nheadoffs %s "
|
"maxsize %s oheadoffs %s nheadoffs %s "
|
||||||
"npadsize %d unient %d\n",
|
"npadsize %d unient %d\n",
|
||||||
lltodecstr(m_d->m_maxsize).c_str(),
|
lltodecstr(m_d->m_maxsize).c_str(),
|
||||||
lltodecstr(m_d->m_oheadoffs).c_str(),
|
lltodecstr(m_d->m_oheadoffs).c_str(),
|
||||||
lltodecstr(m_d->m_nheadoffs).c_str(),
|
lltodecstr(m_d->m_nheadoffs).c_str(),
|
||||||
m_d->m_npadsize, int(m_d->m_uniquentries)));
|
m_d->m_npadsize, int(m_d->m_uniquentries)));
|
||||||
return m_d->writefirstblock();
|
return m_d->writefirstblock();
|
||||||
}
|
}
|
||||||
// Else fallthrough to create file
|
// Else fallthrough to create file
|
||||||
|
@ -767,13 +767,13 @@ class CCScanHookDump : public CCScanHook {
|
||||||
public:
|
public:
|
||||||
virtual status takeone(off_t offs, const string& udi,
|
virtual status takeone(off_t offs, const string& udi,
|
||||||
const EntryHeaderData& d)
|
const EntryHeaderData& d)
|
||||||
{
|
{
|
||||||
cout << "Scan: offs " << offs << " dicsize " << d.dicsize
|
cout << "Scan: offs " << offs << " dicsize " << d.dicsize
|
||||||
<< " datasize " << d.datasize << " padsize " << d.padsize <<
|
<< " datasize " << d.datasize << " padsize " << d.padsize <<
|
||||||
" flags " << d.flags <<
|
" flags " << d.flags <<
|
||||||
" udi [" << udi << "]" << endl;
|
" udi [" << udi << "]" << endl;
|
||||||
return Continue;
|
return Continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool CirCache::dump()
|
bool CirCache::dump()
|
||||||
|
@ -817,20 +817,20 @@ public:
|
||||||
|
|
||||||
virtual status takeone(off_t offs, const string& udi,
|
virtual status takeone(off_t offs, const string& udi,
|
||||||
const EntryHeaderData& d)
|
const EntryHeaderData& d)
|
||||||
{
|
{
|
||||||
LOGDEB2(("Circache:Scan: off %ld udi [%s] dcsz %u dtsz %u pdsz %u "
|
LOGDEB2(("Circache:Scan: off %ld udi [%s] dcsz %u dtsz %u pdsz %u "
|
||||||
" flgs %hu\n",
|
" flgs %hu\n",
|
||||||
long(offs), udi.c_str(), (UINT)d.dicsize,
|
long(offs), udi.c_str(), (UINT)d.dicsize,
|
||||||
(UINT)d.datasize, (UINT)d.padsize, d.flags));
|
(UINT)d.datasize, (UINT)d.padsize, d.flags));
|
||||||
if (!m_udi.compare(udi)) {
|
if (!m_udi.compare(udi)) {
|
||||||
m_instance++;
|
m_instance++;
|
||||||
m_offs = offs;
|
m_offs = offs;
|
||||||
m_hd = d;
|
m_hd = d;
|
||||||
if (m_instance == m_targinstance)
|
if (m_instance == m_targinstance)
|
||||||
return Stop;
|
return Stop;
|
||||||
|
}
|
||||||
|
return Continue;
|
||||||
}
|
}
|
||||||
return Continue;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// instance == -1 means get latest. Otherwise specify from 1+
|
// instance == -1 means get latest. Otherwise specify from 1+
|
||||||
|
@ -968,15 +968,15 @@ public:
|
||||||
|
|
||||||
virtual status takeone(off_t offs, const string& udi,
|
virtual status takeone(off_t offs, const string& udi,
|
||||||
const EntryHeaderData& d)
|
const EntryHeaderData& d)
|
||||||
{
|
{
|
||||||
LOGDEB2(("Circache:ScanSpacer:off %u dcsz %u dtsz %u pdsz %u udi[%s]\n",
|
LOGDEB2(("Circache:ScanSpacer:off %u dcsz %u dtsz %u pdsz %u udi[%s]\n",
|
||||||
(UINT)offs, d.dicsize, d.datasize, d.padsize, udi.c_str()));
|
(UINT)offs, d.dicsize, d.datasize, d.padsize, udi.c_str()));
|
||||||
sizeseen += CIRCACHE_HEADER_SIZE + d.dicsize + d.datasize + d.padsize;
|
sizeseen += CIRCACHE_HEADER_SIZE + d.dicsize + d.datasize + d.padsize;
|
||||||
squashed_udis.push_back(make_pair(udi, offs));
|
squashed_udis.push_back(make_pair(udi, offs));
|
||||||
if (sizeseen >= sizewanted)
|
if (sizeseen >= sizewanted)
|
||||||
return Stop;
|
return Stop;
|
||||||
return Continue;
|
return Continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool CirCache::put(const string& udi, const ConfSimple *iconf,
|
bool CirCache::put(const string& udi, const ConfSimple *iconf,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue