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 | |||