kccachedb.h   kccachedb.h 
/************************************************************************** *********************** /************************************************************************** ***********************
* Cache database * Cache database
* Copyright (C) 2009- 2010 Mikio Hirabayashi * Copyright (C) 2009-2010 FAL Labs
* This file is part of Kyoto Cabinet. * This file is part of Kyoto Cabinet.
* This program is free software: you can redistribute it and/or modify it under the terms of * This program is free software: you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundat ion, either version * the GNU General Public License as published by the Free Software Foundat ion, either version
* 3 of the License, or any later version. * 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY; * This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with this program. * You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>. * If not, see <http://www.gnu.org/licenses/>.
************************************************************************** ***********************/ ************************************************************************** ***********************/
skipping to change at line 293 skipping to change at line 293
bnum_(CDBDEFBNUM), capcnt_(-1), capsiz_(-1), slots_(), tran_(false) { bnum_(CDBDEFBNUM), capcnt_(-1), capsiz_(-1), slots_(), tran_(false) {
_assert_(true); _assert_(true);
} }
/** /**
* Destructor. * Destructor.
* @note If the database is not closed, it is closed implicitly. * @note If the database is not closed, it is closed implicitly.
*/ */
virtual ~CacheDB() { virtual ~CacheDB() {
_assert_(true); _assert_(true);
if (omode_ != 0) close(); if (omode_ != 0) close();
if (curs_.size() > 0) { if (!curs_.empty()) {
CursorList::const_iterator cit = curs_.begin(); CursorList::const_iterator cit = curs_.begin();
CursorList::const_iterator citend = curs_.end(); CursorList::const_iterator citend = curs_.end();
while (cit != citend) { while (cit != citend) {
Cursor* cur = *cit; Cursor* cur = *cit;
cur->db_ = NULL; cur->db_ = NULL;
cit++; cit++;
} }
} }
} }
/** /**
skipping to change at line 813 skipping to change at line 813
entp = &rec->right; entp = &rec->right;
rec = rec->right; rec = rec->right;
} else { } else {
size_t vsiz; size_t vsiz;
const char* vbuf = visitor->visit_full(dbuf, rksiz, dbuf + rksiz, rec->vsiz, &vsiz); const char* vbuf = visitor->visit_full(dbuf, rksiz, dbuf + rksiz, rec->vsiz, &vsiz);
if (vbuf == Visitor::REMOVE) { if (vbuf == Visitor::REMOVE) {
if (tran_) { if (tran_) {
TranLog log(kbuf, ksiz, dbuf + rksiz, rec->vsiz); TranLog log(kbuf, ksiz, dbuf + rksiz, rec->vsiz);
slot->trlogs.push_back(log); slot->trlogs.push_back(log);
} }
if (curs_.size() > 0) escape_cursors(rec); if (!curs_.empty()) escape_cursors(rec);
if (rec == slot->first) slot->first = rec->next; if (rec == slot->first) slot->first = rec->next;
if (rec == slot->last) slot->last = rec->prev; if (rec == slot->last) slot->last = rec->prev;
if (rec->prev) rec->prev->next = rec->next; if (rec->prev) rec->prev->next = rec->next;
if (rec->next) rec->next->prev = rec->prev; if (rec->next) rec->next->prev = rec->prev;
if (rec->left && !rec->right) { if (rec->left && !rec->right) {
*entp = rec->left; *entp = rec->left;
} else if (!rec->left && rec->right) { } else if (!rec->left && rec->right) {
*entp = rec->right; *entp = rec->right;
} else if (!rec->left) { } else if (!rec->left) {
*entp = NULL; *entp = NULL;
skipping to change at line 860 skipping to change at line 860
slot->trlogs.push_back(log); slot->trlogs.push_back(log);
} else { } else {
adj = vsiz > rec->vsiz; adj = vsiz > rec->vsiz;
} }
slot->size -= rec->vsiz; slot->size -= rec->vsiz;
slot->size += vsiz; slot->size += vsiz;
if (vsiz > rec->vsiz) { if (vsiz > rec->vsiz) {
Record* old = rec; Record* old = rec;
rec = (Record*)xrealloc(rec, sizeof(*rec) + ksiz + vsiz); rec = (Record*)xrealloc(rec, sizeof(*rec) + ksiz + vsiz);
if (rec != old) { if (rec != old) {
if (curs_.size() > 0) adjust_cursors(old, rec); if (!curs_.empty()) adjust_cursors(old, rec);
if (slot->first == old) slot->first = rec; if (slot->first == old) slot->first = rec;
if (slot->last == old) slot->last = rec; if (slot->last == old) slot->last = rec;
*entp = rec; *entp = rec;
if (rec->prev) rec->prev->next = rec; if (rec->prev) rec->prev->next = rec;
if (rec->next) rec->next->prev = rec; if (rec->next) rec->next->prev = rec;
dbuf = (char*)rec + sizeof(*rec); dbuf = (char*)rec + sizeof(*rec);
} }
} }
std::memcpy(dbuf + ksiz, vbuf, vsiz); std::memcpy(dbuf + ksiz, vbuf, vsiz);
rec->vsiz = vsiz; rec->vsiz = vsiz;
} }
if (!isiter && slot->last != rec) { if (!isiter && slot->last != rec) {
if (curs_.size() > 0) escape_cursors(rec); if (!curs_.empty()) escape_cursors(rec);
if (slot->first == rec) slot->first = rec->next; if (slot->first == rec) slot->first = rec->next;
if (rec->prev) rec->prev->next = rec->next; if (rec->prev) rec->prev->next = rec->next;
if (rec->next) rec->next->prev = rec->prev; if (rec->next) rec->next->prev = rec->prev;
rec->prev = slot->last; rec->prev = slot->last;
rec->next = NULL; rec->next = NULL;
slot->last->next = rec; slot->last->next = rec;
slot->last = rec; slot->last = rec;
} }
if (adj) adjust_slot_capacity(slot); if (adj) adjust_slot_capacity(slot);
} }
skipping to change at line 1085 skipping to change at line 1085
int32_t compare_keys(const char* abuf, size_t asiz, const char* bbuf, siz e_t bsiz) { int32_t compare_keys(const char* abuf, size_t asiz, const char* bbuf, siz e_t bsiz) {
if (asiz != bsiz) return (int32_t)asiz - (int32_t)bsiz; if (asiz != bsiz) return (int32_t)asiz - (int32_t)bsiz;
return std::memcmp(abuf, bbuf, asiz); return std::memcmp(abuf, bbuf, asiz);
} }
/** /**
* Escape cursors on a shifted or removed records. * Escape cursors on a shifted or removed records.
* @param rec the record. * @param rec the record.
*/ */
void escape_cursors(Record* rec) { void escape_cursors(Record* rec) {
ScopedSpinLock lock(&flock_); ScopedSpinLock lock(&flock_);
if (curs_.size() < 1) return; if (curs_.empty()) return;
CursorList::const_iterator cit = curs_.begin(); CursorList::const_iterator cit = curs_.begin();
CursorList::const_iterator citend = curs_.end(); CursorList::const_iterator citend = curs_.end();
while (cit != citend) { while (cit != citend) {
Cursor* cur = *cit; Cursor* cur = *cit;
if (cur->rec_ == rec) cur->step_impl(); if (cur->rec_ == rec) cur->step_impl();
cit++; cit++;
} }
} }
/** /**
* Adjust cursors on re-allocated records. * Adjust cursors on re-allocated records.
* @param orec the old address. * @param orec the old address.
* @param nrec the new address. * @param nrec the new address.
*/ */
void adjust_cursors(Record* orec, Record* nrec) { void adjust_cursors(Record* orec, Record* nrec) {
ScopedSpinLock lock(&flock_); ScopedSpinLock lock(&flock_);
if (curs_.size() < 1) return; if (curs_.empty()) return;
CursorList::const_iterator cit = curs_.begin(); CursorList::const_iterator cit = curs_.begin();
CursorList::const_iterator citend = curs_.end(); CursorList::const_iterator citend = curs_.end();
while (cit != citend) { while (cit != citend) {
Cursor* cur = *cit; Cursor* cur = *cit;
if (cur->rec_ == orec) cur->rec_ = nrec; if (cur->rec_ == orec) cur->rec_ = nrec;
cit++; cit++;
} }
} }
/** /**
* Disable all cursors. * Disable all cursors.
 End of changes. 7 change blocks. 
7 lines changed or deleted 7 lines changed or added


 kccommon.h   kccommon.h 
/************************************************************************** *********************** /************************************************************************** ***********************
* Common symbols for the library * Common symbols for the library
* Copyright (C) 2009- 2010 Mikio Hirabayashi * Copyright (C) 2009-2010 FAL Labs
* This file is part of Kyoto Cabinet. * This file is part of Kyoto Cabinet.
* This program is free software: you can redistribute it and/or modify it under the terms of * This program is free software: you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundat ion, either version * the GNU General Public License as published by the Free Software Foundat ion, either version
* 3 of the License, or any later version. * 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY; * This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with this program. * You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>. * If not, see <http://www.gnu.org/licenses/>.
************************************************************************** ***********************/ ************************************************************************** ***********************/
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 kccompare.h   kccompare.h 
/************************************************************************** *********************** /************************************************************************** ***********************
* Comparator functions * Comparator functions
* Copyright (C) 2009- 2010 Mikio Hirabayashi * Copyright (C) 2009-2010 FAL Labs
* This file is part of Kyoto Cabinet. * This file is part of Kyoto Cabinet.
* This program is free software: you can redistribute it and/or modify it under the terms of * This program is free software: you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundat ion, either version * the GNU General Public License as published by the Free Software Foundat ion, either version
* 3 of the License, or any later version. * 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY; * This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with this program. * You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>. * If not, see <http://www.gnu.org/licenses/>.
************************************************************************** ***********************/ ************************************************************************** ***********************/
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 kccompress.h   kccompress.h 
/************************************************************************** *********************** /************************************************************************** ***********************
* Data compressor and decompressor * Data compressor and decompressor
* Copyright (C) 2009- 2010 Mikio Hirabayashi * Copyright (C) 2009-2010 FAL Labs
* This file is part of Kyoto Cabinet. * This file is part of Kyoto Cabinet.
* This program is free software: you can redistribute it and/or modify it under the terms of * This program is free software: you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundat ion, either version * the GNU General Public License as published by the Free Software Foundat ion, either version
* 3 of the License, or any later version. * 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY; * This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with this program. * You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>. * If not, see <http://www.gnu.org/licenses/>.
************************************************************************** ***********************/ ************************************************************************** ***********************/
skipping to change at line 74 skipping to change at line 74
/** /**
* Compression modes. * Compression modes.
*/ */
enum Mode { enum Mode {
RAW, ///< without any checksum RAW, ///< without any checksum
DEFLATE, ///< with Adler32 checksum DEFLATE, ///< with Adler32 checksum
GZIP ///< with CRC32 checksum and vario us meta data GZIP ///< with CRC32 checksum and vario us meta data
}; };
/** /**
* Compress a serial data. * Compress a serial data.
* @param mode the compression mode.
* @param buf the input buffer. * @param buf the input buffer.
* @param size the size of the input buffer. * @param size the size of the input buffer.
* @param sp the pointer to the variable into which the size of the regio n of the return * @param sp the pointer to the variable into which the size of the regio n of the return
* value is assigned. * value is assigned.
* @param mode the compression mode.
* @return the pointer to the result data, or NULL on failure. * @return the pointer to the result data, or NULL on failure.
* @note Because the region of the return value is allocated with the the new[] operator, it * @note Because the region of the return value is allocated with the the new[] operator, it
* should be released with the delete[] operator when it is no longer in use. * should be released with the delete[] operator when it is no longer in use.
*/ */
static char* compress(Mode mode, const void* buf, size_t size, size_t* sp ); static char* compress(const void* buf, size_t size, size_t* sp, Mode mode = RAW);
/** /**
* Decompress a serial data. * Decompress a serial data.
* @param mode the compression mode.
* @param buf the input buffer. * @param buf the input buffer.
* @param size the size of the input buffer. * @param size the size of the input buffer.
* @param sp the pointer to the variable into which the size of the regio n of the return * @param sp the pointer to the variable into which the size of the regio n of the return
* value is assigned. * value is assigned.
* @param mode the compression mode.
* @return the pointer to the result data, or NULL on failure. * @return the pointer to the result data, or NULL on failure.
* @note Because an additional zero code is appended at the end of the re gion of the return * @note Because an additional zero code is appended at the end of the re gion of the return
* value, the return value can be treated as a C-style string. Because t he region of the * value, the return value can be treated as a C-style string. Because t he region of the
* return value is allocated with the the new[] operator, it should be re leased with the * return value is allocated with the the new[] operator, it should be re leased with the
* delete[] operator when it is no longer in use. * delete[] operator when it is no longer in use.
*/ */
static char* decompress(Mode mode, const void* buf, size_t size, size_t* static char* decompress(const void* buf, size_t size, size_t* sp, Mode mo
sp); de = RAW);
/**
* Calculate the CRC32 checksum of a serial data.
* @param buf the input buffer.
* @param size the size of the input buffer.
* @param seed the cyclic seed value.
* @return the CRC32 checksum.
*/
static uint32_t calculate_crc(const void* buf, size_t size, uint32_t seed
= 0);
}; };
/** /**
* Compressor with the Zlib raw mode. * Compressor with the Zlib.
*/ */
class ZlibRawCompressor : public Compressor { template <Zlib::Mode MODE>
class ZlibCompressor : public Compressor {
private:
/**
* Compress a serial data.
*/
char* compress(const void* buf, size_t size, size_t* sp) { char* compress(const void* buf, size_t size, size_t* sp) {
_assert_(buf && sp); _assert_(buf && size <= MEMMAXSIZ && sp);
return Zlib::compress(Zlib::RAW, buf, size, sp); return Zlib::compress(buf, size, sp, MODE);
} }
/**
* Decompress a serial data.
*/
char* decompress(const void* buf, size_t size, size_t* sp) { char* decompress(const void* buf, size_t size, size_t* sp) {
_assert_(buf && sp); _assert_(buf && size <= MEMMAXSIZ && sp);
return Zlib::decompress(Zlib::RAW, buf, size, sp); return Zlib::decompress(buf, size, sp, MODE);
} }
}; };
/** /**
* Compressor with the Zlib deflate mode. * Compressor with the Arcfour cipher.
*/ */
class ZlibDeflateCompressor : public Compressor { class ArcfourCompressor : public Compressor {
char* compress(const void* buf, size_t size, size_t* sp) { public:
_assert_(buf && sp); /**
return Zlib::compress(Zlib::DEFLATE, buf, size, sp); * Constructor.
*/
ArcfourCompressor() : kbuf_(NULL), ksiz_(0), salt_(0), cycle_(false) {
_assert_(true);
kbuf_ = new char[0];
ksiz_ = 0;
} }
char* decompress(const void* buf, size_t size, size_t* sp) { /**
_assert_(buf && sp); * Destructor.
return Zlib::decompress(Zlib::DEFLATE, buf, size, sp); */
~ArcfourCompressor() {
_assert_(true);
delete[] kbuf_;
} }
}; /**
* Set the cipher key.
/** * @param kbuf the pointer to the region of the cipher key.
* Compressor with the Zlib gzip mode. * @param ksiz the size of the region of the cipher key.
*/ */
class ZlibGzipCompressor : public Compressor { void set_key(const void* kbuf, size_t ksiz) {
_assert_(kbuf && ksiz <= MEMMAXSIZ);
delete[] kbuf_;
if (ksiz > NUMBUFSIZ) ksiz = NUMBUFSIZ;
kbuf_ = new char[ksiz];
std::memcpy(kbuf_, kbuf, ksiz);
ksiz_ = ksiz;
}
/**
* Begin the cycle of ciper salt.
* @param salt the additional cipher salt.
*/
void begin_cycle(uint64_t salt = 0) {
salt_ = salt;
cycle_ = true;
}
private:
/**
* Compress a serial data.
*/
char* compress(const void* buf, size_t size, size_t* sp) { char* compress(const void* buf, size_t size, size_t* sp) {
_assert_(buf && sp); _assert_(buf && size <= MEMMAXSIZ && sp);
return Zlib::compress(Zlib::GZIP, buf, size, sp); uint64_t salt = cycle_ ? salt_.add(1) : 0;
char kbuf[NUMBUFSIZ*2];
writefixnum(kbuf, salt, sizeof(salt));
std::memcpy(kbuf + sizeof(salt), kbuf_, ksiz_);
char* zbuf = new char[NUMBUFSIZ+size];
char* wp = zbuf;
writefixnum(wp, salt, sizeof(salt));
wp += sizeof(salt);
arccipher(buf, size, kbuf, sizeof(salt) + ksiz_, wp);
if (cycle_) {
size_t range = size < sizeof(uint64_t) ? size : sizeof(uint64_t);
salt_.add(hashmurmur(wp, range) << 32);
}
*sp = sizeof(salt) + size;
return zbuf;
} }
/**
* Decompress a serial data.
*/
char* decompress(const void* buf, size_t size, size_t* sp) { char* decompress(const void* buf, size_t size, size_t* sp) {
_assert_(buf && sp); _assert_(buf && size <= MEMMAXSIZ && sp);
return Zlib::decompress(Zlib::GZIP, buf, size, sp); if (size < sizeof(uint64_t)) return NULL;
char kbuf[NUMBUFSIZ*2];
std::memcpy(kbuf, buf, sizeof(uint64_t));
std::memcpy(kbuf + sizeof(uint64_t), kbuf_, ksiz_);
buf = (char*)buf + sizeof(uint64_t);
size -= sizeof(uint64_t);
char* zbuf = new char[size];
arccipher(buf, size, kbuf, sizeof(uint64_t) + ksiz_, zbuf);
*sp = size;
return zbuf;
} }
/** The pointer to the key. */
char* kbuf_;
/** The size of the key. */
size_t ksiz_;
/** The cipher salt. */
AtomicInt64 salt_;
/** The flag of the salt cycle */
bool cycle_;
}; };
/** /**
* Prepared variable of the compressor with the Zlib raw mode. * Prepared variable of the compressor with the Zlib raw mode.
*/ */
extern ZlibRawCompressor ZLIBRAWCOMP; extern ZlibCompressor<Zlib::RAW> ZLIBRAWCOMP;
/**
* Prepared variable of the compressor with the Zlib deflate mode.
*/
extern ZlibDeflateCompressor ZLIBDEFLCOMP;
/**
* Prepared variable of the compressor with the Zlib gzip mode.
*/
extern ZlibGzipCompressor ZLIBGZIPCOMP;
} // common namespace } // common namespace
#endif // duplication check #endif // duplication check
// END OF FILE // END OF FILE
 End of changes. 21 change blocks. 
41 lines changed or deleted 109 lines changed or added


 kcdb.h   kcdb.h 
/************************************************************************** *********************** /************************************************************************** ***********************
* Database interface * Database interface
* Copyright (C) 2009- 2010 Mikio Hirabayashi * Copyright (C) 2009-2010 FAL Labs
* This file is part of Kyoto Cabinet. * This file is part of Kyoto Cabinet.
* This program is free software: you can redistribute it and/or modify it under the terms of * This program is free software: you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundat ion, either version * the GNU General Public License as published by the Free Software Foundat ion, either version
* 3 of the License, or any later version. * 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY; * This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with this program. * You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>. * If not, see <http://www.gnu.org/licenses/>.
************************************************************************** ***********************/ ************************************************************************** ***********************/
skipping to change at line 419 skipping to change at line 419
* Database types. * Database types.
*/ */
enum Type { enum Type {
TYPEVOID = 0x00, ///< void database TYPEVOID = 0x00, ///< void database
TYPEPHASH = 0x01, ///< prototype hash database TYPEPHASH = 0x01, ///< prototype hash database
TYPEPTREE = 0x02, ///< prototype tree database TYPEPTREE = 0x02, ///< prototype tree database
TYPEPMISC = 0x08, ///< miscellaneous prototype datab ase TYPEPMISC = 0x08, ///< miscellaneous prototype datab ase
TYPECACHE = 0x09, ///< cache database TYPECACHE = 0x09, ///< cache database
TYPEHASH = 0x11, ///< file hash database TYPEHASH = 0x11, ///< file hash database
TYPETREE = 0x12, ///< file tree database TYPETREE = 0x12, ///< file tree database
TYPEDIR = 0x18, ///< directory database
TYPEMISC = 0x20 ///< miscellaneous database TYPEMISC = 0x20 ///< miscellaneous database
}; };
/** /**
* Interface of cursor to indicate a record. * Interface of cursor to indicate a record.
*/ */
class Cursor : public DB::Cursor { class Cursor : public DB::Cursor {
public: public:
/** /**
* Destructor. * Destructor.
*/ */
skipping to change at line 1695 skipping to change at line 1696
static const char* typestring(uint32_t type) { static const char* typestring(uint32_t type) {
_assert_(true); _assert_(true);
switch (type) { switch (type) {
case TYPEVOID: return "void"; case TYPEVOID: return "void";
case TYPEPHASH: return "prototype hash database"; case TYPEPHASH: return "prototype hash database";
case TYPEPTREE: return "prototype tree database"; case TYPEPTREE: return "prototype tree database";
case TYPEPMISC: return "miscellaneous prototype database"; case TYPEPMISC: return "miscellaneous prototype database";
case TYPECACHE: return "cache database"; case TYPECACHE: return "cache database";
case TYPEHASH: return "file hash database"; case TYPEHASH: return "file hash database";
case TYPETREE: return "file tree database"; case TYPETREE: return "file tree database";
case TYPEDIR: return "directory database";
case TYPEMISC: return "miscellaneous database"; case TYPEMISC: return "miscellaneous database";
} }
return "unknown"; return "unknown";
} }
}; };
} // common namespace } // common namespace
#endif // duplication check #endif // duplication check
 End of changes. 3 change blocks. 
1 lines changed or deleted 3 lines changed or added


 kcfile.h   kcfile.h 
/************************************************************************** *********************** /************************************************************************** ***********************
* Filesystem abstraction * Filesystem abstraction
* Copyright (C) 2009- 2010 Mikio Hirabayashi * Copyright (C) 2009-2010 FAL Labs
* This file is part of Kyoto Cabinet. * This file is part of Kyoto Cabinet.
* This program is free software: you can redistribute it and/or modify it under the terms of * This program is free software: you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundat ion, either version * the GNU General Public License as published by the Free Software Foundat ion, either version
* 3 of the License, or any later version. * 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY; * This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with this program. * You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>. * If not, see <http://www.gnu.org/licenses/>.
************************************************************************** ***********************/ ************************************************************************** ***********************/
skipping to change at line 240 skipping to change at line 240
* Get the path of the file. * Get the path of the file.
* @return the path of the file in bytes, or an empty string on failure. * @return the path of the file in bytes, or an empty string on failure.
*/ */
std::string path() const; std::string path() const;
/** /**
* Check whether the file was recovered or not. * Check whether the file was recovered or not.
* @return true if recovered, or false if not. * @return true if recovered, or false if not.
*/ */
bool recovered() const; bool recovered() const;
/** /**
* Read the whole data from a file.
* @param path the path of a file.
* @param sp the pointer to the variable into which the size of the regio
n of the return value
* is assigned.
* @param limit the limit length to read. If it is nagative, no limit is
specified.
* @return the pointer to the region of the read data, or NULL on failure
.
* @note Because an additional zero code is appended at the end of the re
gion of the return
* value, the return value can be treated as a C-style string. Because t
he region of the
* return value is allocated with the the new[] operator, it should be re
leased with the
* delete[] operator when it is no longer in use.
*/
static char* read_file(const std::string& path, int64_t* sp, int64_t limi
t = -1);
/**
* Write the whole data into a file.
* @param path the path of a file.
* @param buf the data buffer to write.
* @param size the size of the data buffer.
* @return true on success, or false on failure.
* @note The existing file corresponding to the path is overwritten. If
no file corresponds
* to the path, a new file is created.
*/
static bool write_file(const std::string& path, const char* buf, int64_t
size);
/**
* Get the status information of a file. * Get the status information of a file.
* @param path the path of a file. * @param path the path of a file.
* @param buf a structure of status information. * @param buf a structure of status information. If it is NULL, it is om itted.
* @return true on success, or false on failure. * @return true on success, or false on failure.
*/ */
static bool status(const std::string& path, Status* buf); static bool status(const std::string& path, Status* buf = NULL);
/** /**
* Get the absolute path of a file. * Get the absolute path of a file.
* @param path the path of a file. * @param path the path of a file.
* @return the absolute path of the file, or an empty string on failure. * @return the absolute path of the file, or an empty string on failure.
*/ */
static std::string absolute_path(const std::string& path); static std::string absolute_path(const std::string& path);
/** /**
* Remove a file. * Remove a file.
* @param path the path of a file. * @param path the path of a file.
* @return true on success, or false on failure. * @return true on success, or false on failure.
skipping to change at line 295 skipping to change at line 318
* Get the path of the current working directory. * Get the path of the current working directory.
* @return the path of the current working directory, or an empty string on failure. * @return the path of the current working directory, or an empty string on failure.
*/ */
static std::string get_current_directory(); static std::string get_current_directory();
/** /**
* Set the current working directory. * Set the current working directory.
* @param path the path of a directory. * @param path the path of a directory.
* @return true on success, or false on failure. * @return true on success, or false on failure.
*/ */
static bool set_current_directory(const std::string& path); static bool set_current_directory(const std::string& path);
/**
* Synchronize the whole of the file system with the device.
* @return true on success, or false on failure.
*/
static bool synchronize_whole();
private: private:
/** Dummy constructor to forbid the use. */ /** Dummy constructor to forbid the use. */
File(const File&); File(const File&);
/** Dummy Operator to forbid the use. */ /** Dummy Operator to forbid the use. */
File& operator =(const File&); File& operator =(const File&);
/** Opaque pointer. */ /** Opaque pointer. */
void* opq_; void* opq_;
}; };
/**
* Directory stream abstraction.
*/
class DirStream {
public:
/**
* Default constructor.
*/
explicit DirStream();
/**
* Destructor.
* @note If the file is not closed, it is closed implicitly.
*/
~DirStream();
/**
* Open a directory.
* @param path the path of a directory.
* @return true on success, or false on failure.
*/
bool open(const std::string& path);
/**
* Close the file.
* @return true on success, or false on failure.
*/
bool close();
/**
* Read the next file in the directory.
* @param path a string to store the file path.
* @return true on success, or false on failure.
*/
bool read(std::string* path);
private:
/** Dummy constructor to forbid the use. */
DirStream(const DirStream&);
/** Dummy Operator to forbid the use. */
DirStream& operator =(const DirStream&);
/** Opaque pointer. */
void* opq_;
};
} // common namespace } // common namespace
#endif // duplication check #endif // duplication check
// END OF FILE // END OF FILE
 End of changes. 6 change blocks. 
3 lines changed or deleted 80 lines changed or added


 kchashdb.h   kchashdb.h 
/************************************************************************** *********************** /************************************************************************** ***********************
* File hash database * File hash database
* Copyright (C) 2009- 2010 Mikio Hirabayashi * Copyright (C) 2009-2010 FAL Labs
* This file is part of Kyoto Cabinet. * This file is part of Kyoto Cabinet.
* This program is free software: you can redistribute it and/or modify it under the terms of * This program is free software: you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundat ion, either version * the GNU General Public License as published by the Free Software Foundat ion, either version
* 3 of the License, or any later version. * 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY; * This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with this program. * You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>. * If not, see <http://www.gnu.org/licenses/>.
************************************************************************** ***********************/ ************************************************************************** ***********************/
skipping to change at line 436 skipping to change at line 436
tran_(false), trhard_(false), trfbp_() { tran_(false), trhard_(false), trfbp_() {
_assert_(true); _assert_(true);
} }
/** /**
* Destructor. * Destructor.
* @note If the database is not closed, it is closed implicitly. * @note If the database is not closed, it is closed implicitly.
*/ */
virtual ~HashDB() { virtual ~HashDB() {
_assert_(true); _assert_(true);
if (omode_ != 0) close(); if (omode_ != 0) close();
if (curs_.size() > 0) { if (!curs_.empty()) {
CursorList::const_iterator cit = curs_.begin(); CursorList::const_iterator cit = curs_.begin();
CursorList::const_iterator citend = curs_.end(); CursorList::const_iterator citend = curs_.end();
while (cit != citend) { while (cit != citend) {
Cursor* cur = *cit; Cursor* cur = *cit;
cur->db_ = NULL; cur->db_ = NULL;
cit++; cit++;
} }
} }
} }
/** /**
skipping to change at line 599 skipping to change at line 599
lsiz_ = roff_; lsiz_ = roff_;
if (!file_.truncate(lsiz_)) { if (!file_.truncate(lsiz_)) {
set_error(__FILE__, __LINE__, Error::SYSTEM, file_.error()); set_error(__FILE__, __LINE__, Error::SYSTEM, file_.error());
file_.close(); file_.close();
return false; return false;
} }
if (!dump_meta()) { if (!dump_meta()) {
file_.close(); file_.close();
return false; return false;
} }
if (autosync_ && !File::synchronize_whole()) {
set_error(__FILE__, __LINE__, Error::SYSTEM, "synchronizing the fil
e system failed");
file_.close();
return false;
}
} }
if (!load_meta()) { if (!load_meta()) {
file_.close(); file_.close();
return false; return false;
} }
calc_meta(); calc_meta();
uint8_t chksum = calc_checksum(); uint8_t chksum = calc_checksum();
if (chksum != chksum_) { if (chksum != chksum_) {
set_error(__FILE__, __LINE__, Error::INVALID, "invalid module checksu m"); set_error(__FILE__, __LINE__, Error::INVALID, "invalid module checksu m");
report(__FILE__, __LINE__, "info", "saved=%02X calculated=%02X", report(__FILE__, __LINE__, "info", "saved=%02X calculated=%02X",
(unsigned)chksum, (unsigned)chksum_); (unsigned)chksum_, (unsigned)chksum);
file_.close(); file_.close();
return false; return false;
} }
if (((flags_ & FOPEN) || (flags_ & FFATAL)) && !(mode & ONOREPAIR) && ! (mode & ONOLOCK) && if (((flags_ & FOPEN) || (flags_ & FFATAL)) && !(mode & ONOREPAIR) && ! (mode & ONOLOCK) &&
!reorganize_file(path)) { !reorganize_file(path)) {
file_.close(); file_.close();
return false; return false;
} }
if (type_ == 0 || apow_ > HDBMAXAPOW || fpow_ > HDBMAXFPOW || if (type_ == 0 || apow_ > HDBMAXAPOW || fpow_ > HDBMAXFPOW ||
bnum_ < 1 || count_ < 0 || lsiz_ < roff_) { bnum_ < 1 || count_ < 0 || lsiz_ < roff_) {
skipping to change at line 1156 skipping to change at line 1161
* @param file the file name of the epicenter. * @param file the file name of the epicenter.
* @param line the line number of the epicenter. * @param line the line number of the epicenter.
* @param type the type string. * @param type the type string.
* @param format the printf-like format string. * @param format the printf-like format string.
* @param ... used according to the format string. * @param ... used according to the format string.
*/ */
void report(const char* file, int32_t line, const char* type, void report(const char* file, int32_t line, const char* type,
const char* format, ...) { const char* format, ...) {
_assert_(file && line > 0 && type && format); _assert_(file && line > 0 && type && format);
if (!erstrm_) return; if (!erstrm_) return;
const std::string& path = path_.size() > 0 ? path_ : "-"; const std::string& path = path_.empty() ? "-" : path_;
std::string message; std::string message;
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
strprintf(&message, format, ap); strprintf(&message, format, ap);
va_end(ap); va_end(ap);
*erstrm_ << "[" << type << "]: " << path << ": " << file << ": " << lin e; *erstrm_ << "[" << type << "]: " << path << ": " << file << ": " << lin e;
*erstrm_ << ": " << message << std::endl; *erstrm_ << ": " << message << std::endl;
} }
/** /**
* Report the content of a binary buffer for debugging. * Report the content of a binary buffer for debugging.
skipping to change at line 1926 skipping to change at line 1931
if (fbpnum_ > 0) boff_ += width_ * 2 + sizeof(uint8_t) * 2; if (fbpnum_ > 0) boff_ += width_ * 2 + sizeof(uint8_t) * 2;
roff_ = boff_ + width_ * bnum_; roff_ = boff_ + width_ * bnum_;
int64_t rem = roff_ % align_; int64_t rem = roff_ % align_;
if (rem > 0) roff_ += align_ - rem; if (rem > 0) roff_ += align_ - rem;
dfcur_ = roff_; dfcur_ = roff_;
frgcnt_ = 0; frgcnt_ = 0;
tran_ = false; tran_ = false;
} }
/** /**
* Calculate the module checksum. * Calculate the module checksum.
* @return the module checksum.
*/ */
uint8_t calc_checksum() { uint8_t calc_checksum() {
_assert_(true); _assert_(true);
const char* kbuf = HDBCHKSUMSEED; const char* kbuf = HDBCHKSUMSEED;
size_t ksiz = sizeof(HDBCHKSUMSEED) - 1; size_t ksiz = sizeof(HDBCHKSUMSEED) - 1;
char* zbuf = NULL; char* zbuf = NULL;
size_t zsiz = 0; size_t zsiz = 0;
if (comp_) { if (comp_) {
zbuf = comp_->compress(kbuf, ksiz, &zsiz); zbuf = comp_->compress(kbuf, ksiz, &zsiz);
if (!zbuf) return 0; if (!zbuf) return 0;
skipping to change at line 2874 skipping to change at line 2880
} }
delete[] blocks; delete[] blocks;
delete[] rbuf; delete[] rbuf;
return true; return true;
} }
/** /**
* Disable all cursors. * Disable all cursors.
*/ */
void disable_cursors() { void disable_cursors() {
_assert_(true); _assert_(true);
if (curs_.size() < 1) return; if (curs_.empty()) return;
CursorList::const_iterator cit = curs_.begin(); CursorList::const_iterator cit = curs_.begin();
CursorList::const_iterator citend = curs_.end(); CursorList::const_iterator citend = curs_.end();
while (cit != citend) { while (cit != citend) {
Cursor* cur = *cit; Cursor* cur = *cit;
cur->off_ = 0; cur->off_ = 0;
cit++; cit++;
} }
} }
/** /**
* Escape cursors on a free block. * Escape cursors on a free block.
* @param off the offset of the free block. * @param off the offset of the free block.
* @param dest the destination offset. * @param dest the destination offset.
*/ */
void escape_cursors(int64_t off, int64_t dest) { void escape_cursors(int64_t off, int64_t dest) {
_assert_(off >= 0 && dest >= 0); _assert_(off >= 0 && dest >= 0);
if (curs_.size() < 1) return; if (curs_.empty()) return;
CursorList::const_iterator cit = curs_.begin(); CursorList::const_iterator cit = curs_.begin();
CursorList::const_iterator citend = curs_.end(); CursorList::const_iterator citend = curs_.end();
while (cit != citend) { while (cit != citend) {
Cursor* cur = *cit; Cursor* cur = *cit;
if (cur->end_ == off) { if (cur->end_ == off) {
cur->end_ = dest; cur->end_ = dest;
if (cur->off_ >= cur->end_) cur->off_ = 0; if (cur->off_ >= cur->end_) cur->off_ = 0;
} }
if (cur->off_ == off) { if (cur->off_ == off) {
cur->off_ = dest; cur->off_ = dest;
if (cur->off_ >= cur->end_) cur->off_ = 0; if (cur->off_ >= cur->end_) cur->off_ = 0;
} }
cit++; cit++;
} }
} }
/** /**
* Trim invalid cursors. * Trim invalid cursors.
*/ */
void trim_cursors() { void trim_cursors() {
_assert_(true); _assert_(true);
if (curs_.size() < 1) return; if (curs_.empty()) return;
int64_t end = lsiz_; int64_t end = lsiz_;
CursorList::const_iterator cit = curs_.begin(); CursorList::const_iterator cit = curs_.begin();
CursorList::const_iterator citend = curs_.end(); CursorList::const_iterator citend = curs_.end();
while (cit != citend) { while (cit != citend) {
Cursor* cur = *cit; Cursor* cur = *cit;
if (cur->off_ >= end) { if (cur->off_ >= end) {
cur->off_ = 0; cur->off_ = 0;
} else if (cur->end_ > end) { } else if (cur->end_ > end) {
cur->end_ = end; cur->end_ = end;
} }
 End of changes. 9 change blocks. 
7 lines changed or deleted 14 lines changed or added


 kclangc.h   kclangc.h 
/************************************************************************** *********************** /************************************************************************** ***********************
* C language binding * C language binding
* Copyright (C) 2009- 2010 Mikio Hirabayashi * Copyright (C) 2009-2010 FAL Labs
* This file is part of Kyoto Cabinet. * This file is part of Kyoto Cabinet.
* This program is free software: you can redistribute it and/or modify it under the terms of * This program is free software: you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundat ion, either version * the GNU General Public License as published by the Free Software Foundat ion, either version
* 3 of the License, or any later version. * 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY; * This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with this program. * You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>. * If not, see <http://www.gnu.org/licenses/>.
************************************************************************** ***********************/ ************************************************************************** ***********************/
skipping to change at line 244 skipping to change at line 244
*/ */
void kcdbdel(KCDB* db); void kcdbdel(KCDB* db);
/** /**
* Open a database file. * Open a database file.
* @param db a database object. * @param db a database object.
* @param path the path of a database file. If it is "-", the database wil l be a prototype * @param path the path of a database file. If it is "-", the database wil l be a prototype
* hash database. If it is "+", the database will be a prototype tree data base. If it is * hash database. If it is "+", the database will be a prototype tree data base. If it is
* "*", the database will be a cache database. If its suffix is ".kch", th e database will be * "*", the database will be a cache database. If its suffix is ".kch", th e database will be
* a file hash database. If its suffix is ".kct", the database will be a f ile tree database. * a file hash database. If its suffix is ".kct", the database will be a f ile tree database.
* Otherwise, this function fails. Tuning parameters can trail the name, s * If its suffix is ".kcd", the database will be a directory database. Oth
eparated by "#". erwise, this
* Each parameter is composed of the name and the value, separated by "=". * function fails. Tuning parameters can trail the name, separated by "#".
If the "type" Each parameter is
* parameter is specified, the database type is determined by the value in * composed of the name and the value, separated by "=". If the "type" par
"-", "+", "*", ameter is specified,
* "kch", and "kct". The prototype hash hash database and the prototype tr * the database type is determined by the value in "-", "+", "*", "kch", "k
ee database do not ct", and "kcd". The
* support any other tuning parameter. The cache database supports "bnum", * prototype hash database and the prototype tree database do not support a
"capcount", and ny other tuning
* "capsize". The file hash database supports "apow", "fpow", "opts", "bnu * parameter. The cache database supports "bnum", "capcount", and "capsize
m", "msiz", ". The file hash
* "dfunit", "erstrm", and "ervbs". The file tree database supports all pa * database supports "apow", "fpow", "opts", "bnum", "msiz", "dfunit", "zco
rameters of the mp", "erstrm",
* file hash database and "psiz", "rcomp", "pccap" in addition. * "ervbs", and "zkey". The file tree database supports all parameters of
the file hash
* database and "psiz", "rcomp", "pccap" in addition. The directory databa
se supports "opts",
* "zcomp", and "zkey".
* @param mode the connection mode. KCOWRITER as a writer, KCOREADER as a reader. * @param mode the connection mode. KCOWRITER as a writer, KCOREADER as a reader.
* The following may be added to the writer mode by bitwise-or: KCOCREATE, which means * The following may be added to the writer mode by bitwise-or: KCOCREATE, which means
* it creates a new database if the file does not exist, KCOTRUNCATE, which means it * it creates a new database if the file does not exist, KCOTRUNCATE, which means it
* creates a new database regardless if the file exists, KCOAUTOTRAN, which means each * creates a new database regardless if the file exists, KCOAUTOTRAN, which means each
* updating operation is performed in implicit transaction, KCOAUTOSYNC, wh ich means * updating operation is performed in implicit transaction, KCOAUTOSYNC, wh ich means
* each updating operation is followed by implicit synchronization with the file system. The * each updating operation is followed by implicit synchronization with the file system. The
* following may be added to both of the reader mode and the writer mode by bitwise-or: * following may be added to both of the reader mode and the writer mode by bitwise-or:
* KCONOLOCK, which means it opens the database file without file locking, * KCONOLOCK, which means it opens the database file without file locking,
* KCOTRYLOCK, which means locking is performed without blocking, KCONOREPA IR, which * KCOTRYLOCK, which means locking is performed without blocking, KCONOREPA IR, which
* means the database file is not repaired implicitly even if file destruct ion is detected. * means the database file is not repaired implicitly even if file destruct ion is detected.
* @return true on success, or false on failure. * @return true on success, or false on failure.
* @note The tuning parameter "bnum" corresponds to the original "tune_buck et" method. * @note The tuning parameter "bnum" corresponds to the original "tune_buck et" method.
* "capcount" is for "cap_count". "capsize" is for "cap_size". "apow" is * "capcount" is for "cap_count". "capsize" is for "cap_size". "apow" is
for "tune_alignment". for
* "fpow" is for "tune_fbp". "opts" is for "tune_options" and the value ca * "tune_alignment". "fpow" is for "tune_fbp". "opts" is for "tune_option
n contain "s" for s" and the value
* the small option, "l" for the linear option, and "c" for the copmress op * can contain "s" for the small option, "l" for the linear option, and "c"
tion. "msiz" is for for the compress
* "tune_map". "dfunit" is for "tune_defrag". "erstrm" and "ervbs" are fo * option. "msiz" is for "tune_map". "dfunit" is for "tune_defrag". "zco
r mp" is for
* "tune_error_reporter" and the formar value can be "stdout" or "stderr" a * "tune_compressor" and the value can be "zlib" for the Zlib raw compresso
nd the latter value r, "def" for the
* can be "true" or "false". "psiz" is for "tune_page". "rcomp" is for "t * Zlib deflate compressor, "gz" for the Zlib gzip compressor, or "arc" for
une_comparator" and the Arcfour cipher.
* the value can be "lex" for the lexical comparator or "dec" for the decim * "erstrm" and "ervbs" are for "tune_error_reporter" and the formar value
al comparator. can be "stdout" or
* "pccap" is for "tune_page_cache". Every opened database must be closed * "stderr" and the latter value can be "true" or "false". "zkey" specifie
by the kcdbclose s the cipher key of
* function when it is no longer in use. It is not allowed for two or more * the compressor. "psiz" is for "tune_page". "rcomp" is for "tune_compar
database objects in ator" and the value
* the same process to keep their connections to the same database file at * can be "lex" for the lexical comparator or "dec" for the decimal compara
the same time. tor. "pccap" is for
* "tune_page_cache". Every opened database must be closed by the PolyDB::
close method when it
* is no longer in use. It is not allowed for two or more database objects
in the same process
* to keep their connections to the same database file at the same time.
*/ */
int32_t kcdbopen(KCDB* db, const char* path, uint32_t mode); int32_t kcdbopen(KCDB* db, const char* path, uint32_t mode);
/** /**
* Close the database file. * Close the database file.
* @param db a database object. * @param db a database object.
* @return true on success, or false on failure. * @return true on success, or false on failure.
*/ */
int32_t kcdbclose(KCDB* db); int32_t kcdbclose(KCDB* db);
 End of changes. 3 change blocks. 
36 lines changed or deleted 45 lines changed or added


 kcmap.h   kcmap.h 
/************************************************************************** *********************** /************************************************************************** ***********************
* Data mapping structures * Data mapping structures
* Copyright (C) 2009- 2010 Mikio Hirabayashi * Copyright (C) 2009-2010 FAL Labs
* This file is part of Kyoto Cabinet. * This file is part of Kyoto Cabinet.
* This program is free software: you can redistribute it and/or modify it under the terms of * This program is free software: you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundat ion, either version * the GNU General Public License as published by the Free Software Foundat ion, either version
* 3 of the License, or any later version. * 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY; * This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with this program. * You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>. * If not, see <http://www.gnu.org/licenses/>.
************************************************************************** ***********************/ ************************************************************************** ***********************/
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 kcpolydb.h   kcpolydb.h 
/************************************************************************** *********************** /************************************************************************** ***********************
* Polymorphic database * Polymorphic database
* Copyright (C) 2009- 2010 Mikio Hirabayashi * Copyright (C) 2009-2010 FAL Labs
* This file is part of Kyoto Cabinet. * This file is part of Kyoto Cabinet.
* This program is free software: you can redistribute it and/or modify it under the terms of * This program is free software: you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundat ion, either version * the GNU General Public License as published by the Free Software Foundat ion, either version
* 3 of the License, or any later version. * 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY; * This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with this program. * You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>. * If not, see <http://www.gnu.org/licenses/>.
************************************************************************** ***********************/ ************************************************************************** ***********************/
skipping to change at line 30 skipping to change at line 30
#include <kcdb.h> #include <kcdb.h>
#include <kcthread.h> #include <kcthread.h>
#include <kcfile.h> #include <kcfile.h>
#include <kccompress.h> #include <kccompress.h>
#include <kccompare.h> #include <kccompare.h>
#include <kcmap.h> #include <kcmap.h>
#include <kcprotodb.h> #include <kcprotodb.h>
#include <kccachedb.h> #include <kccachedb.h>
#include <kchashdb.h> #include <kchashdb.h>
#include <kctreedb.h> #include <kctreedb.h>
#include <kcdirdb.h>
namespace kyotocabinet { // common namespace namespace kyotocabinet { // common namespace
/** /**
* Polymorphic database. * Polymorphic database.
*/ */
class PolyDB : public FileDB { class PolyDB : public FileDB {
public: public:
class Cursor; class Cursor;
public: public:
skipping to change at line 154 skipping to change at line 155
/** Dummy Operator to forbid the use. */ /** Dummy Operator to forbid the use. */
Cursor& operator =(const Cursor&); Cursor& operator =(const Cursor&);
/** The inner database. */ /** The inner database. */
PolyDB* db_; PolyDB* db_;
/** The inner cursor. */ /** The inner cursor. */
FileDB::Cursor* cur_; FileDB::Cursor* cur_;
}; };
/** /**
* Default constructor. * Default constructor.
*/ */
explicit PolyDB() : type_(TYPEVOID), db_(NULL), error_() { explicit PolyDB() : type_(TYPEVOID), db_(NULL), error_(), zcomp_(NULL) {
_assert_(true); _assert_(true);
} }
/** /**
* Constructor. * Constructor.
* @param db the internal database object. Its possession is transferred inside and the * @param db the internal database object. Its possession is transferred inside and the
* object is deleted automatically. * object is deleted automatically.
*/ */
explicit PolyDB(FileDB* db) : type_(TYPEMISC), db_(db), error_() { explicit PolyDB(FileDB* db) : type_(TYPEMISC), db_(db), error_(), zcomp_( NULL) {
_assert_(db); _assert_(db);
} }
/** /**
* Destructor. * Destructor.
* @note If the database is not closed, it is closed implicitly. * @note If the database is not closed, it is closed implicitly.
*/ */
virtual ~PolyDB() { virtual ~PolyDB() {
_assert_(true); _assert_(true);
if (type_ != TYPEVOID) close(); if (type_ != TYPEVOID) close();
delete zcomp_;
} }
/** /**
* Accept a visitor to a record. * Accept a visitor to a record.
* @param kbuf the pointer to the key region. * @param kbuf the pointer to the key region.
* @param ksiz the size of the key region. * @param ksiz the size of the key region.
* @param visitor a visitor object. * @param visitor a visitor object.
* @param writable true for writable operation, or false for read-only op eration. * @param writable true for writable operation, or false for read-only op eration.
* @return true on success, or false on failure. * @return true on success, or false on failure.
* @note the operation for each record is performed atomically and other threads accessing the * @note the operation for each record is performed atomically and other threads accessing the
* same record are blocked. * same record are blocked.
skipping to change at line 234 skipping to change at line 236
return; return;
} }
db_->set_error(code, message); db_->set_error(code, message);
} }
/** /**
* Open a database file. * Open a database file.
* @param path the path of a database file. If it is "-", the database w ill be a prototype * @param path the path of a database file. If it is "-", the database w ill be a prototype
* hash database. If it is "+", the database will be a prototype tree da tabase. If it is * hash database. If it is "+", the database will be a prototype tree da tabase. If it is
* "*", the database will be a cache database. If its suffix is ".kch", the database will be * "*", the database will be a cache database. If its suffix is ".kch", the database will be
* a file hash database. If its suffix is ".kct", the database will be a file tree database. * a file hash database. If its suffix is ".kct", the database will be a file tree database.
* Otherwise, this function fails. Tuning parameters can trail the name, * If its suffix is ".kcd", the database will be a directory database. O
separated by "#". therwise, this
* Each parameter is composed of the name and the value, separated by "=" * function fails. Tuning parameters can trail the name, separated by "#
. If the "type" ". Each parameter is
* parameter is specified, the database type is determined by the value i * composed of the name and the value, separated by "=". If the "type" p
n "-", "+", "*", arameter is specified,
* "kch", and "kct". The prototype hash hash database and the prototype * the database type is determined by the value in "-", "+", "*", "kch",
tree database do not "kct", and "kcd". The
* support any other tuning parameter. The cache database supports "bnum * prototype hash database and the prototype tree database do not support
", "capcount", and any other tuning
* "capsize". The file hash database supports "apow", "fpow", "opts", "b * parameter. The cache database supports "bnum", "capcount", and "capsi
num", "msiz", ze". The file hash
* "dfunit", "erstrm", and "ervbs". The file tree database supports all * database supports "apow", "fpow", "opts", "bnum", "msiz", "dfunit", "z
parameters of the comp", "erstrm",
* file hash database and "psiz", "rcomp", "pccap" in addition. * "ervbs", and "zkey". The file tree database supports all parameters o
f the file hash
* database and "psiz", "rcomp", "pccap" in addition. The directory data
base supports "opts",
* "zcomp", and "zkey".
* @param mode the connection mode. PolyDB::OWRITER as a writer, PolyDB: :OREADER as a * @param mode the connection mode. PolyDB::OWRITER as a writer, PolyDB: :OREADER as a
* reader. The following may be added to the writer mode by bitwise-or: PolyDB::OCREATE, * reader. The following may be added to the writer mode by bitwise-or: PolyDB::OCREATE,
* which means it creates a new database if the file does not exist, Poly DB::OTRUNCATE, which * which means it creates a new database if the file does not exist, Poly DB::OTRUNCATE, which
* means it creates a new database regardless if the file exists, PolyDB: :OAUTOTRAN, which * means it creates a new database regardless if the file exists, PolyDB: :OAUTOTRAN, which
* means each updating operation is performed in implicit transaction, Po lyDB::OAUTOSYNC, * means each updating operation is performed in implicit transaction, Po lyDB::OAUTOSYNC,
* which means each updating operation is followed by implicit synchroniz ation with the file * which means each updating operation is followed by implicit synchroniz ation with the file
* system. The following may be added to both of the reader mode and the writer mode by * system. The following may be added to both of the reader mode and the writer mode by
* bitwise-or: PolyDB::ONOLOCK, which means it opens the database file wi thout file locking, * bitwise-or: PolyDB::ONOLOCK, which means it opens the database file wi thout file locking,
* PolyDB::OTRYLOCK, which means locking is performed without blocking, P olyDB::ONOREPAIR, * PolyDB::OTRYLOCK, which means locking is performed without blocking, P olyDB::ONOREPAIR,
* which means the database file is not repaired implicitly even if file destruction is * which means the database file is not repaired implicitly even if file destruction is
* detected. * detected.
* @return true on success, or false on failure. * @return true on success, or false on failure.
* @note The tuning parameter "bnum" corresponds to the original "tune_bu cket" method. * @note The tuning parameter "bnum" corresponds to the original "tune_bu cket" method.
* "capcount" is for "cap_count". "capsize" is for "cap_size". "apow" i s for * "capcount" is for "cap_count". "capsize" is for "cap_size". "apow" i s for
* "tune_alignment". "fpow" is for "tune_fbp". "opts" is for "tune_opti ons" and the value * "tune_alignment". "fpow" is for "tune_fbp". "opts" is for "tune_opti ons" and the value
* can contain "s" for the small option, "l" for the linear option, and " * can contain "s" for the small option, "l" for the linear option, and "
c" for the copmress c" for the compress
* option. "msiz" is for "tune_map". "dfunit" is for "tune_defrag". "e * option. "msiz" is for "tune_map". "dfunit" is for "tune_defrag". "z
rstrm" and "ervbs" comp" is for
* are for "tune_error_reporter" and the formar value can be "stdout" or * "tune_compressor" and the value can be "zlib" for the Zlib raw compres
"stderr" and the sor, "def" for the
* latter value can be "true" or "false". "psiz" is for "tune_page". "r * Zlib deflate compressor, "gz" for the Zlib gzip compressor, or "arc" f
comp" is for or the Arcfour cipher.
* "tune_comparator" and the value can be "lex" for the lexical comparato * "erstrm" and "ervbs" are for "tune_error_reporter" and the formar valu
r or "dec" for the e can be "stdout" or
* decimal comparator. "pccap" is for "tune_page_cache". Every opened d * "stderr" and the latter value can be "true" or "false". "zkey" specif
atabase must be ies the cipher key of
* closed by the PolyDB::close method when it is no longer in use. It is * the compressor. "psiz" is for "tune_page". "rcomp" is for "tune_comp
not allowed for two arator" and the value
* or more database objects in the same process to keep their connections * can be "lex" for the lexical comparator or "dec" for the decimal compa
to the same rator. "pccap" is for
* database file at the same time. * "tune_page_cache". Every opened database must be closed by the PolyDB
::close method when it
* is no longer in use. It is not allowed for two or more database objec
ts in the same process
* to keep their connections to the same database file at the same time.
*/ */
bool open(const std::string& path, uint32_t mode = OWRITER | OCREATE) { bool open(const std::string& path, uint32_t mode = OWRITER | OCREATE) {
_assert_(true); _assert_(true);
if (type_ == TYPEMISC) return db_->open(path, mode); if (type_ == TYPEMISC) return db_->open(path, mode);
if (type_ != TYPEVOID) { if (type_ != TYPEVOID) {
set_error(Error::INVALID, "already opened"); set_error(Error::INVALID, "already opened");
return false; return false;
} }
std::vector<std::string> elems; std::vector<std::string> elems;
strsplit(path, '#', &elems); strsplit(path, '#', &elems);
skipping to change at line 288 skipping to change at line 294
int64_t bnum = -1; int64_t bnum = -1;
int64_t capcount = -1; int64_t capcount = -1;
int64_t capsize = -1; int64_t capsize = -1;
int32_t apow = -1; int32_t apow = -1;
int32_t fpow = -1; int32_t fpow = -1;
bool tsmall = false; bool tsmall = false;
bool tlinear = false; bool tlinear = false;
bool tcompress = false; bool tcompress = false;
int64_t msiz = -1; int64_t msiz = -1;
int64_t dfunit = -1; int64_t dfunit = -1;
Compressor *zcomp = NULL;
int64_t psiz = -1; int64_t psiz = -1;
Comparator *rcomp = NULL; Comparator *rcomp = NULL;
int64_t pccap = 0; int64_t pccap = 0;
std::ostream* erstrm = NULL; std::ostream* erstrm = NULL;
bool ervbs = false; bool ervbs = false;
std::string zkey = "";
ArcfourCompressor *arccomp = NULL;
std::vector<std::string>::iterator it = elems.begin(); std::vector<std::string>::iterator it = elems.begin();
std::vector<std::string>::iterator itend = elems.end(); std::vector<std::string>::iterator itend = elems.end();
if (it != itend) { if (it != itend) {
fpath = *it; fpath = *it;
it++; it++;
} }
const char* fstr = fpath.c_str(); const char* fstr = fpath.c_str();
const char* pv = std::strrchr(fstr, File::PATHCHR); const char* pv = std::strrchr(fstr, File::PATHCHR);
if (pv) fstr = pv + 1; if (pv) fstr = pv + 1;
if (!std::strcmp(fstr, "-")) { if (!std::strcmp(fstr, "-")) {
skipping to change at line 316 skipping to change at line 325
} else if (!std::strcmp(fstr, "*")) { } else if (!std::strcmp(fstr, "*")) {
type = TYPECACHE; type = TYPECACHE;
} else { } else {
pv = std::strrchr(fstr, File::EXTCHR); pv = std::strrchr(fstr, File::EXTCHR);
if (pv) { if (pv) {
pv++; pv++;
if (!std::strcmp(pv, "kch") || !std::strcmp(pv, "hdb")) { if (!std::strcmp(pv, "kch") || !std::strcmp(pv, "hdb")) {
type = TYPEHASH; type = TYPEHASH;
} else if (!std::strcmp(pv, "kct") || !std::strcmp(pv, "tdb")) { } else if (!std::strcmp(pv, "kct") || !std::strcmp(pv, "tdb")) {
type = TYPETREE; type = TYPETREE;
} else if (!std::strcmp(pv, "kcd") || !std::strcmp(pv, "ddb")) {
type = TYPEDIR;
} }
} }
} }
while (it != itend) { while (it != itend) {
std::vector<std::string> fields; std::vector<std::string> fields;
if (strsplit(*it, '=', &fields) > 1) { if (strsplit(*it, '=', &fields) > 1) {
const char* key = fields[0].c_str(); const char* key = fields[0].c_str();
const char* value = fields[1].c_str(); const char* value = fields[1].c_str();
if (!std::strcmp(key, "type")) { if (!std::strcmp(key, "type")) {
if (!std::strcmp(value, "-") || !std::strcmp(value, "phash")) { if (!std::strcmp(value, "-") || !std::strcmp(value, "phash")) {
skipping to change at line 337 skipping to change at line 348
} else if (!std::strcmp(value, "+") || !std::strcmp(value, "ptree ")) { } else if (!std::strcmp(value, "+") || !std::strcmp(value, "ptree ")) {
type = TYPEPTREE; type = TYPEPTREE;
} else if (!std::strcmp(value, "*") || !std::strcmp(value, "cache ")) { } else if (!std::strcmp(value, "*") || !std::strcmp(value, "cache ")) {
type = TYPECACHE; type = TYPECACHE;
} else if (!std::strcmp(value, "kch") || !std::strcmp(value, "hdb ") || } else if (!std::strcmp(value, "kch") || !std::strcmp(value, "hdb ") ||
!std::strcmp(value, "hash")) { !std::strcmp(value, "hash")) {
type = TYPEHASH; type = TYPEHASH;
} else if (!std::strcmp(value, "kct") || !std::strcmp(value, "tdb ") || } else if (!std::strcmp(value, "kct") || !std::strcmp(value, "tdb ") ||
!std::strcmp(value, "tree")) { !std::strcmp(value, "tree")) {
type = TYPETREE; type = TYPETREE;
} else if (!std::strcmp(value, "kcd") || !std::strcmp(value, "ddb
") ||
!std::strcmp(value, "dir")) {
type = TYPEDIR;
} }
} else if (!std::strcmp(key, "bnum") || !std::strcmp(key, "buckets" )) { } else if (!std::strcmp(key, "bnum") || !std::strcmp(key, "buckets" )) {
bnum = atoix(value); bnum = atoix(value);
} else if (!std::strcmp(key, "capcount") || !std::strcmp(key, "cap_ count")) { } else if (!std::strcmp(key, "capcount") || !std::strcmp(key, "cap_ count")) {
capcount = atoix(value); capcount = atoix(value);
} else if (!std::strcmp(key, "capsize") || !std::strcmp(key, "cap_s ize")) { } else if (!std::strcmp(key, "capsize") || !std::strcmp(key, "cap_s ize")) {
capsize = atoix(value); capsize = atoix(value);
} else if (!std::strcmp(key, "apow") || !std::strcmp(key, "alignmen t")) { } else if (!std::strcmp(key, "apow") || !std::strcmp(key, "alignmen t")) {
apow = atoix(value); apow = atoix(value);
} else if (!std::strcmp(key, "fpow") || !std::strcmp(key, "fbp")) { } else if (!std::strcmp(key, "fpow") || !std::strcmp(key, "fbp")) {
fpow = atoix(value); fpow = atoix(value);
} else if (!std::strcmp(key, "opts") || !std::strcmp(key, "options" )) { } else if (!std::strcmp(key, "opts") || !std::strcmp(key, "options" )) {
if (std::strchr(value, 's')) tsmall = true; if (std::strchr(value, 's')) tsmall = true;
if (std::strchr(value, 'l')) tlinear = true; if (std::strchr(value, 'l')) tlinear = true;
if (std::strchr(value, 'c')) tcompress = true; if (std::strchr(value, 'c')) tcompress = true;
} else if (!std::strcmp(key, "msiz") || !std::strcmp(key, "map")) { } else if (!std::strcmp(key, "msiz") || !std::strcmp(key, "map")) {
msiz = atoix(value); msiz = atoix(value);
} else if (!std::strcmp(key, "dfunit") || !std::strcmp(key, "defrag ")) { } else if (!std::strcmp(key, "dfunit") || !std::strcmp(key, "defrag ")) {
dfunit = atoix(value); dfunit = atoix(value);
} else if (!std::strcmp(key, "zcomp") || !std::strcmp(key, "compres
sor")) {
delete zcomp;
zcomp = NULL;
arccomp = NULL;
if (!std::strcmp(value, "zlib") || !std::strcmp(value, "raw")) {
zcomp = new ZlibCompressor<Zlib::RAW>;
} else if (!std::strcmp(value, "def") || !std::strcmp(value, "def
late")) {
zcomp = new ZlibCompressor<Zlib::DEFLATE>;
} else if (!std::strcmp(value, "gz") || !std::strcmp(value, "gzip
")) {
zcomp = new ZlibCompressor<Zlib::GZIP>;
} else if (!std::strcmp(value, "arc") || !std::strcmp(value, "rc4
")) {
arccomp = new ArcfourCompressor();
zcomp = arccomp;
}
} else if (!std::strcmp(key, "psiz") || !std::strcmp(key, "page")) { } else if (!std::strcmp(key, "psiz") || !std::strcmp(key, "page")) {
psiz = atoix(value); psiz = atoix(value);
} else if (!std::strcmp(key, "pccap") || !std::strcmp(key, "cache") ) { } else if (!std::strcmp(key, "pccap") || !std::strcmp(key, "cache") ) {
pccap = atoix(value); pccap = atoix(value);
} else if (!std::strcmp(key, "rcomp") || !std::strcmp(key, "compara tor")) { } else if (!std::strcmp(key, "rcomp") || !std::strcmp(key, "compara tor")) {
if (!std::strcmp(value, "lex") || !std::strcmp(value, "lexical")) { if (!std::strcmp(value, "lex") || !std::strcmp(value, "lexical")) {
rcomp = &LEXICALCOMP; rcomp = &LEXICALCOMP;
} else if (!std::strcmp(value, "dec") || !std::strcmp(value, "dec imal")) { } else if (!std::strcmp(value, "dec") || !std::strcmp(value, "dec imal")) {
rcomp = &DECIMALCOMP; rcomp = &DECIMALCOMP;
} }
} else if (!std::strcmp(key, "erstrm") || !std::strcmp(key, "report er")) { } else if (!std::strcmp(key, "erstrm") || !std::strcmp(key, "report er")) {
if (!std::strcmp(value, "stdout") || !std::strcmp(value, "cout") || if (!std::strcmp(value, "stdout") || !std::strcmp(value, "cout") ||
atoix(value) == 1) { atoix(value) == 1) {
erstrm = &std::cout; erstrm = &std::cout;
} else if (!std::strcmp(value, "stderr") || !std::strcmp(value, " cerr") || } else if (!std::strcmp(value, "stderr") || !std::strcmp(value, " cerr") ||
atoix(value) == 2) { atoix(value) == 2) {
erstrm = &std::cerr; erstrm = &std::cerr;
} }
} else if (!std::strcmp(key, "ervbs") || !std::strcmp(key, "erv")) { } else if (!std::strcmp(key, "ervbs") || !std::strcmp(key, "erv")) {
ervbs = !std::strcmp(value, "true") || atoix(value) > 0; ervbs = !std::strcmp(value, "true") || atoix(value) > 0;
} else if (!std::strcmp(key, "zkey") || !std::strcmp(key, "pass") |
|
!std::strcmp(key, "password")) {
zkey = value;
} }
} }
it++; it++;
} }
if (zcomp) {
delete zcomp_;
zcomp_ = zcomp;
tcompress = true;
}
FileDB *db; FileDB *db;
switch (type) { switch (type) {
default: { default: {
set_error(Error::INVALID, "unknown database type"); set_error(Error::INVALID, "unknown database type");
return false; return false;
} }
case TYPEPHASH: { case TYPEPHASH: {
ProtoHashDB* phdb = new ProtoHashDB(); ProtoHashDB* phdb = new ProtoHashDB();
db = phdb; db = phdb;
break; break;
skipping to change at line 416 skipping to change at line 452
if (tsmall) opts |= HashDB::TSMALL; if (tsmall) opts |= HashDB::TSMALL;
if (tlinear) opts |= HashDB::TLINEAR; if (tlinear) opts |= HashDB::TLINEAR;
if (tcompress) opts |= HashDB::TCOMPRESS; if (tcompress) opts |= HashDB::TCOMPRESS;
HashDB* hdb = new HashDB(); HashDB* hdb = new HashDB();
if (apow >= 0) hdb->tune_alignment(apow); if (apow >= 0) hdb->tune_alignment(apow);
if (fpow >= 0) hdb->tune_fbp(fpow); if (fpow >= 0) hdb->tune_fbp(fpow);
if (opts > 0) hdb->tune_options(opts); if (opts > 0) hdb->tune_options(opts);
if (bnum > 0) hdb->tune_buckets(bnum); if (bnum > 0) hdb->tune_buckets(bnum);
if (msiz >= 0) hdb->tune_map(msiz); if (msiz >= 0) hdb->tune_map(msiz);
if (dfunit > 0) hdb->tune_defrag(dfunit); if (dfunit > 0) hdb->tune_defrag(dfunit);
if (zcomp) hdb->tune_compressor(zcomp);
if (erstrm) hdb->tune_error_reporter(erstrm, ervbs); if (erstrm) hdb->tune_error_reporter(erstrm, ervbs);
db = hdb; db = hdb;
break; break;
} }
case TYPETREE: { case TYPETREE: {
int8_t opts = 0; int8_t opts = 0;
if (tsmall) opts |= TreeDB::TSMALL; if (tsmall) opts |= TreeDB::TSMALL;
if (tlinear) opts |= TreeDB::TLINEAR; if (tlinear) opts |= TreeDB::TLINEAR;
if (tcompress) opts |= TreeDB::TCOMPRESS; if (tcompress) opts |= TreeDB::TCOMPRESS;
TreeDB* tdb = new TreeDB(); TreeDB* tdb = new TreeDB();
if (apow >= 0) tdb->tune_alignment(apow); if (apow >= 0) tdb->tune_alignment(apow);
if (fpow >= 0) tdb->tune_fbp(fpow); if (fpow >= 0) tdb->tune_fbp(fpow);
if (opts > 0) tdb->tune_options(opts); if (opts > 0) tdb->tune_options(opts);
if (bnum > 0) tdb->tune_buckets(bnum); if (bnum > 0) tdb->tune_buckets(bnum);
if (psiz > 0) tdb->tune_page(psiz); if (psiz > 0) tdb->tune_page(psiz);
if (msiz >= 0) tdb->tune_map(msiz); if (msiz >= 0) tdb->tune_map(msiz);
if (dfunit > 0) tdb->tune_defrag(dfunit); if (dfunit > 0) tdb->tune_defrag(dfunit);
if (zcomp) tdb->tune_compressor(zcomp);
if (pccap > 0) tdb->tune_page_cache(pccap); if (pccap > 0) tdb->tune_page_cache(pccap);
if (rcomp) tdb->tune_comparator(rcomp); if (rcomp) tdb->tune_comparator(rcomp);
if (erstrm) tdb->tune_error_reporter(erstrm, ervbs); if (erstrm) tdb->tune_error_reporter(erstrm, ervbs);
db = tdb; db = tdb;
break; break;
} }
case TYPEDIR: {
int8_t opts = 0;
if (tcompress) opts |= DirDB::TCOMPRESS;
DirDB* ddb = new DirDB();
if (opts > 0) ddb->tune_options(opts);
if (zcomp) ddb->tune_compressor(zcomp);
db = ddb;
break;
}
} }
if (arccomp) arccomp->set_key(zkey.c_str(), zkey.size());
if (!db->open(fpath, mode)) { if (!db->open(fpath, mode)) {
const Error& error = db->error(); const Error& error = db->error();
set_error(error.code(), error.message()); set_error(error.code(), error.message());
delete db; delete db;
return false; return false;
} }
if (arccomp) {
const std::string& apath = File::absolute_path(fpath);
uint64_t hash = (hashmurmur(apath.c_str(), apath.size()) >> 16) << 40
;
hash += (uint64_t)(time() * 256);
arccomp->begin_cycle(hash);
}
type_ = type; type_ = type;
db_ = db; db_ = db;
return true; return true;
} }
/** /**
* Close the database file. * Close the database file.
* @return true on success, or false on failure. * @return true on success, or false on failure.
*/ */
bool close() { bool close() {
_assert_(true); _assert_(true);
if (type_ == TYPEVOID) { if (type_ == TYPEVOID) {
set_error(Error::INVALID, "not opened"); set_error(Error::INVALID, "not opened");
return false; return false;
} }
bool err = false; bool err = false;
if (!db_->close()) { if (!db_->close()) {
const Error& error = db_->error(); const Error& error = db_->error();
set_error(error.code(), error.message()); set_error(error.code(), error.message());
err = true; err = true;
} }
delete zcomp_;
delete db_; delete db_;
type_ = TYPEVOID; type_ = TYPEVOID;
db_ = NULL; db_ = NULL;
zcomp_ = NULL;
return !err; return !err;
} }
/** /**
* Synchronize updated contents with the file and the device. * Synchronize updated contents with the file and the device.
* @param hard true for physical synchronization with the device, or fals e for logical * @param hard true for physical synchronization with the device, or fals e for logical
* synchronization with the file system. * synchronization with the file system.
* @param proc a postprocessor object. If it is NULL, no postprocessing is performed. * @param proc a postprocessor object. If it is NULL, no postprocessing is performed.
* @return true on success, or false on failure. * @return true on success, or false on failure.
*/ */
bool synchronize(bool hard = false, FileProcessor* proc = NULL) { bool synchronize(bool hard = false, FileProcessor* proc = NULL) {
skipping to change at line 621 skipping to change at line 677
/** Dummy constructor to forbid the use. */ /** Dummy constructor to forbid the use. */
PolyDB(const PolyDB&); PolyDB(const PolyDB&);
/** Dummy Operator to forbid the use. */ /** Dummy Operator to forbid the use. */
PolyDB& operator =(const PolyDB&); PolyDB& operator =(const PolyDB&);
/** The database type. */ /** The database type. */
Type type_; Type type_;
/** The internal database. */ /** The internal database. */
FileDB* db_; FileDB* db_;
/** The last happened error. */ /** The last happened error. */
TSD<Error> error_; TSD<Error> error_;
/** The custom compressor. */
Compressor* zcomp_;
}; };
} // common namespace } // common namespace
#endif // duplication check #endif // duplication check
// END OF FILE // END OF FILE
 End of changes. 22 change blocks. 
35 lines changed or deleted 104 lines changed or added


 kcprotodb.h   kcprotodb.h 
/************************************************************************** *********************** /************************************************************************** ***********************
* Prototype database * Prototype database
* Copyright (C) 2009- 2010 Mikio Hirabayashi * Copyright (C) 2009-2010 FAL Labs
* This file is part of Kyoto Cabinet. * This file is part of Kyoto Cabinet.
* This program is free software: you can redistribute it and/or modify it under the terms of * This program is free software: you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundat ion, either version * the GNU General Public License as published by the Free Software Foundat ion, either version
* 3 of the License, or any later version. * 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY; * This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with this program. * You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>. * If not, see <http://www.gnu.org/licenses/>.
************************************************************************** ***********************/ ************************************************************************** ***********************/
skipping to change at line 275 skipping to change at line 275
_assert_(true); _assert_(true);
map_tune(&recs_); map_tune(&recs_);
} }
/** /**
* Destructor. * Destructor.
* @note If the database is not closed, it is closed implicitly. * @note If the database is not closed, it is closed implicitly.
*/ */
virtual ~ProtoDB() { virtual ~ProtoDB() {
_assert_(true); _assert_(true);
if (omode_ != 0) close(); if (omode_ != 0) close();
if (curs_.size() > 0) { if (!curs_.empty()) {
typename CursorList::const_iterator cit = curs_.begin(); typename CursorList::const_iterator cit = curs_.begin();
typename CursorList::const_iterator citend = curs_.end(); typename CursorList::const_iterator citend = curs_.end();
while (cit != citend) { while (cit != citend) {
Cursor* cur = *cit; Cursor* cur = *cit;
cur->db_ = NULL; cur->db_ = NULL;
cit++; cit++;
} }
} }
} }
/** /**
skipping to change at line 330 skipping to change at line 330
} else { } else {
const std::string& value = it->second; const std::string& value = it->second;
size_t vsiz; size_t vsiz;
const char* vbuf = visitor->visit_full(kbuf, ksiz, value.c_str(), v alue.size(), &vsiz); const char* vbuf = visitor->visit_full(kbuf, ksiz, value.c_str(), v alue.size(), &vsiz);
if (vbuf == Visitor::REMOVE) { if (vbuf == Visitor::REMOVE) {
if (tran_) { if (tran_) {
TranLog log(key, value); TranLog log(key, value);
trlogs_.push_back(log); trlogs_.push_back(log);
} }
size_ -= ksiz + value.size(); size_ -= ksiz + value.size();
if (curs_.size() > 0) { if (!curs_.empty()) {
typename CursorList::const_iterator cit = curs_.begin(); typename CursorList::const_iterator cit = curs_.begin();
typename CursorList::const_iterator citend = curs_.end(); typename CursorList::const_iterator citend = curs_.end();
while (cit != citend) { while (cit != citend) {
Cursor* cur = *cit; Cursor* cur = *cit;
if (cur->it_ == it) cur->it_++; if (cur->it_ == it) cur->it_++;
cit++; cit++;
} }
} }
recs_.erase(it); recs_.erase(it);
} else if (vbuf != Visitor::NOP) { } else if (vbuf != Visitor::NOP) {
skipping to change at line 479 skipping to change at line 479
bool close() { bool close() {
_assert_(true); _assert_(true);
ScopedSpinRWLock lock(&mlock_, true); ScopedSpinRWLock lock(&mlock_, true);
if (omode_ == 0) { if (omode_ == 0) {
set_error(Error::INVALID, "not opened"); set_error(Error::INVALID, "not opened");
return false; return false;
} }
tran_ = false; tran_ = false;
trlogs_.clear(); trlogs_.clear();
recs_.clear(); recs_.clear();
if (curs_.size() > 0) { if (!curs_.empty()) {
typename CursorList::const_iterator cit = curs_.begin(); typename CursorList::const_iterator cit = curs_.begin();
typename CursorList::const_iterator citend = curs_.end(); typename CursorList::const_iterator citend = curs_.end();
while (cit != citend) { while (cit != citend) {
Cursor* cur = *cit; Cursor* cur = *cit;
cur->it_ = recs_.end(); cur->it_ = recs_.end();
cit++; cit++;
} }
} }
path_.clear(); path_.clear();
omode_ = 0; omode_ = 0;
skipping to change at line 593 skipping to change at line 593
ScopedSpinRWLock lock(&mlock_, true); ScopedSpinRWLock lock(&mlock_, true);
if (omode_ == 0) { if (omode_ == 0) {
set_error(Error::INVALID, "not opened"); set_error(Error::INVALID, "not opened");
return false; return false;
} }
if (!tran_) { if (!tran_) {
set_error(Error::INVALID, "not in transaction"); set_error(Error::INVALID, "not in transaction");
return false; return false;
} }
if (!commit) { if (!commit) {
if (curs_.size() > 0) { if (!curs_.empty()) {
typename CursorList::const_iterator cit = curs_.begin(); typename CursorList::const_iterator cit = curs_.begin();
typename CursorList::const_iterator citend = curs_.end(); typename CursorList::const_iterator citend = curs_.end();
while (cit != citend) { while (cit != citend) {
Cursor* cur = *cit; Cursor* cur = *cit;
cur->it_ = recs_.end(); cur->it_ = recs_.end();
cit++; cit++;
} }
} }
const TranLogList& logs = trlogs_; const TranLogList& logs = trlogs_;
typename TranLogList::const_iterator lit = logs.end(); typename TranLogList::const_iterator lit = logs.end();
skipping to change at line 631 skipping to change at line 631
* @return true on success, or false on failure. * @return true on success, or false on failure.
*/ */
bool clear() { bool clear() {
_assert_(true); _assert_(true);
ScopedSpinRWLock lock(&mlock_, true); ScopedSpinRWLock lock(&mlock_, true);
if (omode_ == 0) { if (omode_ == 0) {
set_error(Error::INVALID, "not opened"); set_error(Error::INVALID, "not opened");
return false; return false;
} }
recs_.clear(); recs_.clear();
if (curs_.size() > 0) { if (!curs_.empty()) {
typename CursorList::const_iterator cit = curs_.begin(); typename CursorList::const_iterator cit = curs_.begin();
typename CursorList::const_iterator citend = curs_.end(); typename CursorList::const_iterator citend = curs_.end();
while (cit != citend) { while (cit != citend) {
Cursor* cur = *cit; Cursor* cur = *cit;
cur->it_ = recs_.end(); cur->it_ = recs_.end();
cit++; cit++;
} }
} }
return true; return true;
} }
 End of changes. 6 change blocks. 
6 lines changed or deleted 6 lines changed or added


 kcthread.h   kcthread.h 
/************************************************************************** *********************** /************************************************************************** ***********************
* Threading devices * Threading devices
* Copyright (C) 2009- 2010 Mikio Hirabayashi * Copyright (C) 2009-2010 FAL Labs
* This file is part of Kyoto Cabinet. * This file is part of Kyoto Cabinet.
* This program is free software: you can redistribute it and/or modify it under the terms of * This program is free software: you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundat ion, either version * the GNU General Public License as published by the Free Software Foundat ion, either version
* 3 of the License, or any later version. * 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY; * This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with this program. * You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>. * If not, see <http://www.gnu.org/licenses/>.
************************************************************************** ***********************/ ************************************************************************** ***********************/
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 kctreedb.h   kctreedb.h 
/************************************************************************** *********************** /************************************************************************** ***********************
* File tree database * File tree database
* Copyright (C) 2009- 2010 Mikio Hirabayashi * Copyright (C) 2009-2010 FAL Labs
* This file is part of Kyoto Cabinet. * This file is part of Kyoto Cabinet.
* This program is free software: you can redistribute it and/or modify it under the terms of * This program is free software: you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundat ion, either version * the GNU General Public License as published by the Free Software Foundat ion, either version
* 3 of the License, or any later version. * 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY; * This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with this program. * You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>. * If not, see <http://www.gnu.org/licenses/>.
************************************************************************** ***********************/ ************************************************************************** ***********************/
skipping to change at line 275 skipping to change at line 275
_assert_(true); _assert_(true);
while (id > 0) { while (id > 0) {
LeafNode* node = db_->load_leaf_node(id, false); LeafNode* node = db_->load_leaf_node(id, false);
if (!node) { if (!node) {
db_->set_error(__FILE__, __LINE__, Error::BROKEN, "missing leaf n ode"); db_->set_error(__FILE__, __LINE__, Error::BROKEN, "missing leaf n ode");
db_->hdb_.report(__FILE__, __LINE__, "info", "id=%ld", (long)id); db_->hdb_.report(__FILE__, __LINE__, "info", "id=%ld", (long)id);
return false; return false;
} }
ScopedSpinRWLock lock(&node->lock, false); ScopedSpinRWLock lock(&node->lock, false);
RecordArray& recs = node->recs; RecordArray& recs = node->recs;
if (recs.size() > 0) { if (!recs.empty()) {
set_position(recs.front(), id); set_position(recs.front(), id);
return true; return true;
} else { } else {
id = node->next; id = node->next;
} }
} }
db_->set_error(__FILE__, __LINE__, Error::NOREC, "no record"); db_->set_error(__FILE__, __LINE__, Error::NOREC, "no record");
return false; return false;
} }
/** /**
skipping to change at line 318 skipping to change at line 318
size_t lsiz = 0; size_t lsiz = 0;
Link* link = NULL; Link* link = NULL;
int64_t hist[TDBLEVELMAX]; int64_t hist[TDBLEVELMAX];
int32_t hnum = 0; int32_t hnum = 0;
if (writable) { if (writable) {
node->lock.lock_writer(); node->lock.lock_writer();
} else { } else {
node->lock.lock_reader(); node->lock.lock_reader();
} }
RecordArray& recs = node->recs; RecordArray& recs = node->recs;
if (recs.size() > 0) { if (!recs.empty()) {
Record* frec = recs.front(); Record* frec = recs.front();
Record* lrec = recs.back(); Record* lrec = recs.back();
if (!db_->reccomp_(rec, frec) && !db_->reccomp_(lrec, rec)) { if (!db_->reccomp_(rec, frec) && !db_->reccomp_(lrec, rec)) {
RecordArray::iterator ritend = recs.end(); RecordArray::iterator ritend = recs.end();
RecordArray::iterator rit = std::lower_bound(recs.begin(), rite nd, RecordArray::iterator rit = std::lower_bound(recs.begin(), rite nd,
rec, db_->reccomp_ ); rec, db_->reccomp_ );
if (rit != ritend) { if (rit != ritend) {
hit = true; hit = true;
if (db_->reccomp_(rec, *rit)) { if (db_->reccomp_(rec, *rit)) {
clear_position(); clear_position();
skipping to change at line 468 skipping to change at line 468
link->ksiz = ksiz_; link->ksiz = ksiz_;
std::memcpy(lbuf + sizeof(*link), kbuf_, ksiz_); std::memcpy(lbuf + sizeof(*link), kbuf_, ksiz_);
int64_t hist[TDBLEVELMAX]; int64_t hist[TDBLEVELMAX];
int32_t hnum = 0; int32_t hnum = 0;
LeafNode* node = db_->search_tree(link, true, hist, &hnum); LeafNode* node = db_->search_tree(link, true, hist, &hnum);
if (!node) { if (!node) {
db_->set_error(__FILE__, __LINE__, Error::BROKEN, "search failed"); db_->set_error(__FILE__, __LINE__, Error::BROKEN, "search failed");
if (lbuf != lstack) delete[] lbuf; if (lbuf != lstack) delete[] lbuf;
return false; return false;
} }
if (node->recs.size() < 1) { if (node->recs.empty()) {
if (lbuf != lstack) delete[] lbuf; if (lbuf != lstack) delete[] lbuf;
clear_position(); clear_position();
if (!set_position(node->next)) return false; if (!set_position(node->next)) return false;
node = db_->load_leaf_node(lid_, false); node = db_->load_leaf_node(lid_, false);
if (!node) { if (!node) {
db_->set_error(__FILE__, __LINE__, Error::BROKEN, "search failed" ); db_->set_error(__FILE__, __LINE__, Error::BROKEN, "search failed" );
return false; return false;
} }
lsiz = sizeof(Link) + ksiz_; lsiz = sizeof(Link) + ksiz_;
char* lbuf = lsiz > sizeof(lstack) ? new char[lsiz] : lstack; char* lbuf = lsiz > sizeof(lstack) ? new char[lsiz] : lstack;
skipping to change at line 533 skipping to change at line 533
node->size -= rsiz; node->size -= rsiz;
node->dirty = true; node->dirty = true;
xfree(rec); xfree(rec);
RecordArray::iterator ritnext = rit + 1; RecordArray::iterator ritnext = rit + 1;
if (ritnext != ritend) { if (ritnext != ritend) {
clear_position(); clear_position();
set_position(*ritnext, node->id); set_position(*ritnext, node->id);
step = false; step = false;
} }
recs.erase(rit); recs.erase(rit);
if (recs.size() < 1) reorg = true; if (recs.empty()) reorg = true;
} else if (vbuf != Visitor::NOP) { } else if (vbuf != Visitor::NOP) {
int64_t diff = (int64_t)vsiz - (int64_t)rec->vsiz; int64_t diff = (int64_t)vsiz - (int64_t)rec->vsiz;
db_->cusage_ += diff; db_->cusage_ += diff;
node->size += diff; node->size += diff;
node->dirty = true; node->dirty = true;
if (vsiz > rec->vsiz) { if (vsiz > rec->vsiz) {
*rit = (Record*)xrealloc(rec, sizeof(*rec) + rec->ksiz + vsiz); *rit = (Record*)xrealloc(rec, sizeof(*rec) + rec->ksiz + vsiz);
rec = *rit; rec = *rit;
kbuf = (char*)rec + sizeof(*rec); kbuf = (char*)rec + sizeof(*rec);
} }
skipping to change at line 685 skipping to change at line 685
lslots_(), islots_(), reccomp_(), linkcomp_(), tran_(false), trcnt_(0) { lslots_(), islots_(), reccomp_(), linkcomp_(), tran_(false), trcnt_(0) {
_assert_(true); _assert_(true);
} }
/** /**
* Destructor. * Destructor.
* @note If the database is not closed, it is closed implicitly. * @note If the database is not closed, it is closed implicitly.
*/ */
virtual ~TreeDB() { virtual ~TreeDB() {
_assert_(true); _assert_(true);
if (omode_ != 0) close(); if (omode_ != 0) close();
if (curs_.size() > 0) { if (!curs_.empty()) {
CursorList::const_iterator cit = curs_.begin(); CursorList::const_iterator cit = curs_.begin();
CursorList::const_iterator citend = curs_.end(); CursorList::const_iterator citend = curs_.end();
while (cit != citend) { while (cit != citend) {
Cursor* cur = *cit; Cursor* cur = *cit;
cur->db_ = NULL; cur->db_ = NULL;
cit++; cit++;
} }
} }
} }
/** /**
skipping to change at line 1972 skipping to change at line 1972
} }
/** /**
* Check whether a record is in the range of a leaf node. * Check whether a record is in the range of a leaf node.
* @param node the leaf node. * @param node the leaf node.
* @param rec the record containing the key only. * @param rec the record containing the key only.
* @return true for in range, or false for out of range. * @return true for in range, or false for out of range.
*/ */
bool check_leaf_node_range(LeafNode* node, Record* rec) { bool check_leaf_node_range(LeafNode* node, Record* rec) {
_assert_(node && rec); _assert_(node && rec);
RecordArray& recs = node->recs; RecordArray& recs = node->recs;
if (recs.size() < 1) return false; if (recs.empty()) return false;
Record* frec = recs.front(); Record* frec = recs.front();
Record* lrec = recs.back(); Record* lrec = recs.back();
return !reccomp_(rec, frec) && !reccomp_(lrec, rec); return !reccomp_(rec, frec) && !reccomp_(lrec, rec);
} }
/** /**
* Accept a visitor at a leaf node. * Accept a visitor at a leaf node.
* @param node the leaf node. * @param node the leaf node.
* @param rec the record containing the key only. * @param rec the record containing the key only.
* @param visitor a visitor object. * @param visitor a visitor object.
* @return true to reorganize the tree, or false if not. * @return true to reorganize the tree, or false if not.
skipping to change at line 2004 skipping to change at line 2004
size_t vsiz; size_t vsiz;
const char* vbuf = visitor->visit_full(kbuf, ksiz, kbuf + ksiz, rec-> vsiz, &vsiz); const char* vbuf = visitor->visit_full(kbuf, ksiz, kbuf + ksiz, rec-> vsiz, &vsiz);
if (vbuf == Visitor::REMOVE) { if (vbuf == Visitor::REMOVE) {
size_t rsiz = sizeof(*rec) + rec->ksiz + rec->vsiz; size_t rsiz = sizeof(*rec) + rec->ksiz + rec->vsiz;
count_ -= 1; count_ -= 1;
cusage_ -= rsiz; cusage_ -= rsiz;
node->size -= rsiz; node->size -= rsiz;
node->dirty = true; node->dirty = true;
xfree(rec); xfree(rec);
recs.erase(rit); recs.erase(rit);
if (recs.size() < 1) reorg = true; if (recs.empty()) reorg = true;
} else if (vbuf != Visitor::NOP) { } else if (vbuf != Visitor::NOP) {
int64_t diff = (int64_t)vsiz - (int64_t)rec->vsiz; int64_t diff = (int64_t)vsiz - (int64_t)rec->vsiz;
cusage_ += diff; cusage_ += diff;
node->size += diff; node->size += diff;
node->dirty = true; node->dirty = true;
if (vsiz > rec->vsiz) { if (vsiz > rec->vsiz) {
*rit = (Record*)xrealloc(rec, sizeof(*rec) + rec->ksiz + vsiz); *rit = (Record*)xrealloc(rec, sizeof(*rec) + rec->ksiz + vsiz);
rec = *rit; rec = *rit;
kbuf = (char*)rec + sizeof(*rec); kbuf = (char*)rec + sizeof(*rec);
} }
skipping to change at line 2417 skipping to change at line 2417
for (int32_t i = 0; i <= num; i++) { for (int32_t i = 0; i <= num; i++) {
Link* link = links.back(); Link* link = links.back();
size_t rsiz = sizeof(*link) + link->ksiz; size_t rsiz = sizeof(*link) + link->ksiz;
cusage_ -= rsiz; cusage_ -= rsiz;
inode->size -= rsiz; inode->size -= rsiz;
xfree(link); xfree(link);
links.pop_back(); links.pop_back();
} }
inode->dirty = true; inode->dirty = true;
} }
} else if (node->recs.size() < 1 && hnum > 0) { } else if (node->recs.empty() && hnum > 0) {
if (!escape_cursors(node->id, node->next)) return false; if (!escape_cursors(node->id, node->next)) return false;
InnerNode* inode = load_inner_node(hist[--hnum]); InnerNode* inode = load_inner_node(hist[--hnum]);
if (!inode) { if (!inode) {
set_error(__FILE__, __LINE__, Error::BROKEN, "missing inner node"); set_error(__FILE__, __LINE__, Error::BROKEN, "missing inner node");
hdb_.report(__FILE__, __LINE__, "info", "id=%ld", (long)hist[hnum]) ; hdb_.report(__FILE__, __LINE__, "info", "id=%ld", (long)hist[hnum]) ;
return false; return false;
} }
if (sub_link_tree(inode, node->id, hist, hnum)) { if (sub_link_tree(inode, node->id, hist, hnum)) {
if (node->prev > 0) { if (node->prev > 0) {
LeafNode* tnode = load_leaf_node(node->prev, false); LeafNode* tnode = load_leaf_node(node->prev, false);
skipping to change at line 2491 skipping to change at line 2491
* @param hnum the number of the history. * @param hnum the number of the history.
* @return true on success, or false on failure. * @return true on success, or false on failure.
*/ */
bool sub_link_tree(InnerNode* node, int64_t child, int64_t* hist, int32_t hnum) { bool sub_link_tree(InnerNode* node, int64_t child, int64_t* hist, int32_t hnum) {
_assert_(node && hist && hnum >= 0); _assert_(node && hist && hnum >= 0);
node->dirty = true; node->dirty = true;
LinkArray& links = node->links; LinkArray& links = node->links;
LinkArray::iterator lit = links.begin(); LinkArray::iterator lit = links.begin();
LinkArray::iterator litend = links.end(); LinkArray::iterator litend = links.end();
if (node->heir == child) { if (node->heir == child) {
if (links.size() > 0) { if (!links.empty()) {
Link* link = *lit; Link* link = *lit;
node->heir = link->child; node->heir = link->child;
xfree(link); xfree(link);
links.erase(lit); links.erase(lit);
return true; return true;
} else if (hnum > 0) { } else if (hnum > 0) {
InnerNode* pnode = load_inner_node(hist[--hnum]); InnerNode* pnode = load_inner_node(hist[--hnum]);
if (!pnode) { if (!pnode) {
set_error(__FILE__, __LINE__, Error::BROKEN, "missing inner node" ); set_error(__FILE__, __LINE__, Error::BROKEN, "missing inner node" );
hdb_.report(__FILE__, __LINE__, "info", "id=%ld", (long)hist[hnum ]); hdb_.report(__FILE__, __LINE__, "info", "id=%ld", (long)hist[hnum ]);
skipping to change at line 2705 skipping to change at line 2705
it++; it++;
} }
} }
return sum; return sum;
} }
/** /**
* Disable all cursors. * Disable all cursors.
*/ */
void disable_cursors() { void disable_cursors() {
_assert_(true); _assert_(true);
if (curs_.size() < 1) return; if (curs_.empty()) return;
CursorList::const_iterator cit = curs_.begin(); CursorList::const_iterator cit = curs_.begin();
CursorList::const_iterator citend = curs_.end(); CursorList::const_iterator citend = curs_.end();
while (cit != citend) { while (cit != citend) {
Cursor* cur = *cit; Cursor* cur = *cit;
if (cur->kbuf_) cur->clear_position(); if (cur->kbuf_) cur->clear_position();
cit++; cit++;
} }
} }
/** /**
* Escape cursors on a divided leaf node. * Escape cursors on a divided leaf node.
* @param src the ID of the source node. * @param src the ID of the source node.
* @param dest the ID of the destination node. * @param dest the ID of the destination node.
* @param rec the pivot record. * @param rec the pivot record.
* @return true on success, or false on failure. * @return true on success, or false on failure.
*/ */
void escape_cursors(int64_t src, int64_t dest, Record* rec) { void escape_cursors(int64_t src, int64_t dest, Record* rec) {
_assert_(src > 0 && dest >= 0 && rec); _assert_(src > 0 && dest >= 0 && rec);
if (curs_.size() < 1) return; if (curs_.empty()) return;
CursorList::const_iterator cit = curs_.begin(); CursorList::const_iterator cit = curs_.begin();
CursorList::const_iterator citend = curs_.end(); CursorList::const_iterator citend = curs_.end();
while (cit != citend) { while (cit != citend) {
Cursor* cur = *cit; Cursor* cur = *cit;
if (cur->lid_ == src) { if (cur->lid_ == src) {
char* dbuf = (char*)rec + sizeof(*rec); char* dbuf = (char*)rec + sizeof(*rec);
if (reccomp_.comp->compare(cur->kbuf_, cur->ksiz_, dbuf, rec->ksiz) >= 0) if (reccomp_.comp->compare(cur->kbuf_, cur->ksiz_, dbuf, rec->ksiz) >= 0)
cur->lid_ = dest; cur->lid_ = dest;
} }
cit++; cit++;
} }
} }
/** /**
* Escape cursors on a removed leaf node. * Escape cursors on a removed leaf node.
* @param src the ID of the source node. * @param src the ID of the source node.
* @param dest the ID of the destination node. * @param dest the ID of the destination node.
* @return true on success, or false on failure. * @return true on success, or false on failure.
*/ */
bool escape_cursors(int64_t src, int64_t dest) { bool escape_cursors(int64_t src, int64_t dest) {
_assert_(src > 0 && dest >= 0); _assert_(src > 0 && dest >= 0);
if (curs_.size() < 1) return true; if (curs_.empty()) return true;
bool err = false; bool err = false;
CursorList::const_iterator cit = curs_.begin(); CursorList::const_iterator cit = curs_.begin();
CursorList::const_iterator citend = curs_.end(); CursorList::const_iterator citend = curs_.end();
while (cit != citend) { while (cit != citend) {
Cursor* cur = *cit; Cursor* cur = *cit;
if (cur->lid_ == src) { if (cur->lid_ == src) {
cur->clear_position(); cur->clear_position();
if (!cur->set_position(dest) && hdb_.error().code() != Error::NOREC ) err = true; if (!cur->set_position(dest) && hdb_.error().code() != Error::NOREC ) err = true;
} }
cit++; cit++;
 End of changes. 13 change blocks. 
13 lines changed or deleted 13 lines changed or added


 kcutil.h   kcutil.h 
/************************************************************************** *********************** /************************************************************************** ***********************
* Utility functions * Utility functions
* Copyright (C) 2009- 2010 Mikio Hirabayashi * Copyright (C) 2009-2010 FAL Labs
* This file is part of Kyoto Cabinet. * This file is part of Kyoto Cabinet.
* This program is free software: you can redistribute it and/or modify it under the terms of * This program is free software: you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundat ion, either version * the GNU General Public License as published by the Free Software Foundat ion, either version
* 3 of the License, or any later version. * 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY; * This program is distributed in the hope that it will be useful, but WITH OUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PA RTICULAR PURPOSE.
* See the GNU General Public License for more details. * See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with this program. * You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>. * If not, see <http://www.gnu.org/licenses/>.
************************************************************************** ***********************/ ************************************************************************** ***********************/
skipping to change at line 175 skipping to change at line 175
/** /**
* Get the hash value by FNV hashing. * Get the hash value by FNV hashing.
* @param buf the source buffer. * @param buf the source buffer.
* @param size the size of the source buffer. * @param size the size of the source buffer.
* @return the hash value. * @return the hash value.
*/ */
uint64_t hashfnv(const void* buf, size_t size); uint64_t hashfnv(const void* buf, size_t size);
/** /**
* Get the hash value suitable for a file name.
* @param buf the source buffer.
* @param size the size of the source buffer.
* @param obuf the buffer into which the result hash string is written. It
must be more than
* NUMBUFSIZ.
* @return the auxiliary hash value.
*/
uint32_t hashpath(const void* buf, size_t size, char* obuf);
/**
* Get a prime number nearby a number. * Get a prime number nearby a number.
* @param num a natural number. * @param num a natural number.
* @return the result number. * @return the result number.
*/ */
uint64_t nearbyprime(uint64_t num); uint64_t nearbyprime(uint64_t num);
/** /**
* Get the quiet Not-a-Number value. * Get the quiet Not-a-Number value.
* @return the quiet Not-a-Number value. * @return the quiet Not-a-Number value.
*/ */
skipping to change at line 252 skipping to change at line 262
size_t strsplit(const std::string& str, char delim, std::vector<std::string >* elems); size_t strsplit(const std::string& str, char delim, std::vector<std::string >* elems);
/** /**
* Encode a serial object with hexadecimal encoding. * Encode a serial object with hexadecimal encoding.
* @param buf the pointer to the region. * @param buf the pointer to the region.
* @param size the size of the region. * @param size the size of the region.
* @return the result string. * @return the result string.
* @note Because the region of the return value is allocated with the the n ew[] operator, it * @note Because the region of the return value is allocated with the the n ew[] operator, it
* should be released with the delete[] operator when it is no longer in us e. * should be released with the delete[] operator when it is no longer in us e.
*/ */
char* hexencode(const char* buf, size_t size); char* hexencode(const void* buf, size_t size);
/** /**
* Decode a string encoded with hexadecimal encoding. * Decode a string encoded with hexadecimal encoding.
* @param str specifies the encoded string. * @param str specifies the encoded string.
* @param sp the pointer to the variable into which the size of the region of the return value * @param sp the pointer to the variable into which the size of the region of the return value
* is assigned. * is assigned.
* @return the pointer to the region of the result. * @return the pointer to the region of the result.
* @note Because an additional zero code is appended at the end of the regi on of the return * @note Because an additional zero code is appended at the end of the regi on of the return
* value, the return value can be treated as a character string. Because t he region of the * value, the return value can be treated as a character string. Because t he region of the
* return value is allocated with the the new[] operator, it should be rele ased with the delete[] * return value is allocated with the the new[] operator, it should be rele ased with the delete[]
* operator when it is no longer in use. * operator when it is no longer in use.
*/ */
char* hexdecode(const char* str, size_t* sp); char* hexdecode(const char* str, size_t* sp);
/** /**
* Cipher or decipher a serial object with the Arcfour stream cipher.
* @param ptr the pointer to the region.
* @param size the size of the region.
* @param kbuf the pointer to the region of the cipher key.
* @param ksiz the size of the region of the cipher key.
* @param obuf the pointer to the region into which the result data is writ
ten. The size of the
* buffer should be equal to or more than the input region. The region can
be the same as the
* source region.
*/
void arccipher(const void* ptr, size_t size, const void* kbuf, size_t ksiz,
void* obuf);
/**
* Allocate a region on memory. * Allocate a region on memory.
* @param size the size of the region. * @param size the size of the region.
* @return the pointer to the allocated region. * @return the pointer to the allocated region.
*/ */
void* xmalloc(size_t size); void* xmalloc(size_t size);
/** /**
* Allocate a nullified region on memory. * Allocate a nullified region on memory.
* @param nmemb the number of elements. * @param nmemb the number of elements.
* @param size the size of each element. * @param size the size of each element.
skipping to change at line 675 skipping to change at line 697
uint64_t hash = 14695981039346656037ULL; uint64_t hash = 14695981039346656037ULL;
const unsigned char* rp = (unsigned char*)buf; const unsigned char* rp = (unsigned char*)buf;
const unsigned char* ep = rp + size; const unsigned char* ep = rp + size;
while (rp < ep) { while (rp < ep) {
hash = (hash ^ *(rp++)) * 109951162811ULL; hash = (hash ^ *(rp++)) * 109951162811ULL;
} }
return hash; return hash;
} }
/** /**
* Get the hash value suitable for a file name.
*/
inline uint32_t hashpath(const void* buf, size_t size, char* obuf) {
_assert_(buf && size <= MEMMAXSIZ && obuf);
const unsigned char* rp = (const unsigned char*)buf;
uint32_t rv;
char* wp = obuf;
if (size <= 10) {
if (size > 0) {
const unsigned char* ep = rp + size;
while (rp < ep) {
int32_t num = *rp >> 4;
if (num < 10) {
*(wp++) = '0' + num;
} else {
*(wp++) = 'a' + num - 10;
}
num = *rp & 0x0f;
if (num < 10) {
*(wp++) = '0' + num;
} else {
*(wp++) = 'a' + num - 10;
}
rp++;
}
} else {
*(wp++) = '0';
}
uint64_t hash = hashmurmur(buf, size);
rv = (((hash & 0xffff000000000000ULL) >> 48) | ((hash & 0x0000ffff00000
000ULL) >> 16)) ^
(((hash & 0x000000000000ffffULL) << 16) | ((hash & 0x00000000ffff0000
ULL) >> 16));
} else {
*(wp++) = 'f' + 1 + (size & 0x0f);
int32_t num = (rp[0] >> 4) + (rp[1] & 0x01 ? 0x10 : 0);
if (num < 10) {
*(wp++) = '0' + num;
} else {
*(wp++) = 'a' + num - 10;
}
num = (rp[0] & 0x0f) + (rp[1] & 0x02 ? 0x10 : 0);
if (num < 10) {
*(wp++) = '0' + num;
} else {
*(wp++) = 'a' + num - 10;
}
num = (rp[1] >> 2) & 0x1f;
if (num < 10) {
*(wp++) = '0' + num;
} else {
*(wp++) = 'a' + num - 10;
}
uint64_t hash = hashmurmur(buf, size);
rv = (((hash & 0xffff000000000000ULL) >> 48) | ((hash & 0x0000ffff00000
000ULL) >> 16)) ^
(((hash & 0x000000000000ffffULL) << 16) | ((hash & 0x00000000ffff0000
ULL) >> 16));
uint64_t inc = hashfnv(buf, size);
inc = (((inc & 0xffff000000000000ULL) >> 48) | ((inc & 0x0000ffff000000
00ULL) >> 16)) ^
(((inc & 0x000000000000ffffULL) << 16) | ((inc & 0x00000000ffff0000UL
L) >> 16));
for (size_t i = 0; i < sizeof(hash); i++) {
uint32_t least = hash >> ((sizeof(hash) - 1) * 8);
num = least >> 4;
if (inc & 0x01) num += 0x10;
inc = inc >> 1;
if (num < 10) {
*(wp++) = '0' + num;
} else {
*(wp++) = 'a' + num - 10;
}
num = least & 0x0f;
if (inc & 0x01) num += 0x10;
inc = inc >> 1;
if (num < 10) {
*(wp++) = '0' + num;
} else {
*(wp++) = 'a' + num - 10;
}
hash = hash << 8;
}
}
*wp = '\0';
return rv;
}
/**
* Get a prime number nearby a number. * Get a prime number nearby a number.
*/ */
inline uint64_t nearbyprime(uint64_t num) { inline uint64_t nearbyprime(uint64_t num) {
_assert_(true); _assert_(true);
static uint64_t table[] = { static uint64_t table[] = {
2ULL, 3ULL, 5ULL, 7ULL, 11ULL, 13ULL, 17ULL, 19ULL, 23ULL, 29ULL, 31ULL , 37ULL, 41ULL, 2ULL, 3ULL, 5ULL, 7ULL, 11ULL, 13ULL, 17ULL, 19ULL, 23ULL, 29ULL, 31ULL , 37ULL, 41ULL,
43ULL, 47ULL, 53ULL, 59ULL, 61ULL, 67ULL, 71ULL, 79ULL, 97ULL, 107ULL, 131ULL, 157ULL, 43ULL, 47ULL, 53ULL, 59ULL, 61ULL, 67ULL, 71ULL, 79ULL, 97ULL, 107ULL, 131ULL, 157ULL,
181ULL, 223ULL, 257ULL, 307ULL, 367ULL, 431ULL, 521ULL, 613ULL, 727ULL, 863ULL, 1031ULL, 181ULL, 223ULL, 257ULL, 307ULL, 367ULL, 431ULL, 521ULL, 613ULL, 727ULL, 863ULL, 1031ULL,
1217ULL, 1451ULL, 1723ULL, 2053ULL, 2437ULL, 2897ULL, 3449ULL, 4099ULL, 4871ULL, 5801ULL, 1217ULL, 1451ULL, 1723ULL, 2053ULL, 2437ULL, 2897ULL, 3449ULL, 4099ULL, 4871ULL, 5801ULL,
6899ULL, 8209ULL, 9743ULL, 11587ULL, 13781ULL, 16411ULL, 19483ULL, 2317 3ULL, 27581ULL, 6899ULL, 8209ULL, 9743ULL, 11587ULL, 13781ULL, 16411ULL, 19483ULL, 2317 3ULL, 27581ULL,
skipping to change at line 897 skipping to change at line 1002
} }
it++; it++;
} }
elems->push_back(field); elems->push_back(field);
return elems->size(); return elems->size();
} }
/** /**
* Encode a serial object with hexadecimal encoding. * Encode a serial object with hexadecimal encoding.
*/ */
inline char* hexencode(const char* buf, size_t size) { inline char* hexencode(const void* buf, size_t size) {
_assert_(buf && size <= MEMMAXSIZ); _assert_(buf && size <= MEMMAXSIZ);
const unsigned char* rp = (const unsigned char* )buf; const unsigned char* rp = (const unsigned char*)buf;
char* zbuf = new char[size*2+1]; char* zbuf = new char[size*2+1];
char* wp = zbuf; char* wp = zbuf;
for (size_t i = 0; i < size; i++) { for (const unsigned char* ep = rp + size; rp < ep; rp++) {
wp += std::sprintf(wp, "%02x", rp[i]); int32_t num = (*rp >> 4);
if (num < 10) {
*(wp++) = '0' + num;
} else {
*(wp++) = 'a' + num - 10;
}
num = (*rp & 0x0f);
if (num < 10) {
*(wp++) = '0' + num;
} else {
*(wp++) = 'a' + num - 10;
}
} }
*wp = '\0'; *wp = '\0';
return zbuf; return zbuf;
} }
/** /**
* Decode a string encoded with hexadecimal encoding. * Decode a string encoded with hexadecimal encoding.
*/ */
inline char* hexdecode(const char* str, size_t* sp) { inline char* hexdecode(const char* str, size_t* sp) {
_assert_(str && sp); _assert_(str && sp);
skipping to change at line 951 skipping to change at line 1067
break; break;
} }
*(wp++) = num; *(wp++) = num;
} }
*wp = '\0'; *wp = '\0';
*sp = wp - zbuf; *sp = wp - zbuf;
return zbuf; return zbuf;
} }
/** /**
* Cipher or decipher a serial object with the Arcfour stream cipher.
*/
inline void arccipher(const void* ptr, size_t size, const void* kbuf, size_
t ksiz, void* obuf) {
_assert_(ptr && size <= MEMMAXSIZ && kbuf && ksiz <= MEMMAXSIZ && obuf);
if (ksiz < 1) {
kbuf = "";
ksiz = 1;
}
uint32_t sbox[0x100], kbox[0x100];
for(int32_t i = 0; i < 0x100; i++){
sbox[i] = i;
kbox[i] = ((uint8_t*)kbuf)[i%ksiz];
}
uint32_t sidx = 0;
for(int i = 0; i < 0x100; i++){
sidx = (sidx + sbox[i] + kbox[i]) & 0xff;
uint32_t swap = sbox[i];
sbox[i] = sbox[sidx];
sbox[sidx] = swap;
}
uint32_t x = 0;
uint32_t y = 0;
for(size_t i = 0; i < size; i++){
x = (x + 1) & 0xff;
y = (y + sbox[x]) & 0xff;
uint32_t swap = sbox[x];
sbox[x] = sbox[y];
sbox[y] = swap;
((uint8_t*)obuf)[i] = ((uint8_t*)ptr)[i] ^ sbox[(sbox[x]+sbox[y])&0xff]
;
}
}
/**
* Allocate a region on memory. * Allocate a region on memory.
*/ */
inline void* xmalloc(size_t size) { inline void* xmalloc(size_t size) {
_assert_(size <= MEMMAXSIZ); _assert_(size <= MEMMAXSIZ);
void* ptr = std::malloc(size); void* ptr = std::malloc(size);
if (!ptr) throw std::bad_alloc(); if (!ptr) throw std::bad_alloc();
return ptr; return ptr;
} }
/** /**
 End of changes. 9 change blocks. 
6 lines changed or deleted 167 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/