kcdb.h   kcdb.h 
skipping to change at line 795 skipping to change at line 795
} }
std::string* key_; std::string* key_;
std::string* value_; std::string* value_;
bool ok_; bool ok_;
}; };
VisitorImpl visitor(key, value); VisitorImpl visitor(key, value);
if (!accept(&visitor, false, step)) return false; if (!accept(&visitor, false, step)) return false;
return visitor.ok(); return visitor.ok();
} }
/** /**
* Get a pair of the key and the value of the current record and remove
it atomically.
* @param ksp the pointer to the variable into which the size of the re
gion of the return
* value is assigned.
* @param vbp the pointer to the variable into which the pointer to the
value region is
* assigned.
* @param vsp the pointer to the variable into which the size of the va
lue region is
* assigned.
* @return the pointer to the key region, or NULL on failure.
* @note If the cursor is invalidated, NULL is returned. Because an ad
ditional zero code is
* appended at the end of each region of the key and the value, each re
gion can be treated
* as a C-style string. The return value should be deleted explicitly
by the caller with
* the detele[] operator. The cursor is moved to the next record impli
citly.
*/
char* seize(size_t* ksp, const char** vbp, size_t* vsp) {
_assert_(ksp && vbp && vsp);
class VisitorImpl : public Visitor {
public:
explicit VisitorImpl() : kbuf_(NULL), ksiz_(0), vbuf_(NULL), vsiz_(
0) {}
char* pop(size_t* ksp, const char** vbp, size_t* vsp) {
*ksp = ksiz_;
*vbp = vbuf_;
*vsp = vsiz_;
return kbuf_;
}
void clear() {
delete[] kbuf_;
}
private:
const char* visit_full(const char* kbuf, size_t ksiz,
const char* vbuf, size_t vsiz, size_t* sp) {
size_t rsiz = ksiz + 1 + vsiz + 1;
kbuf_ = new char[rsiz];
std::memcpy(kbuf_, kbuf, ksiz);
kbuf_[ksiz] = '\0';
ksiz_ = ksiz;
vbuf_ = kbuf_ + ksiz + 1;
std::memcpy(vbuf_, vbuf, vsiz);
vbuf_[vsiz] = '\0';
vsiz_ = vsiz;
return REMOVE;
}
char* kbuf_;
size_t ksiz_;
char* vbuf_;
size_t vsiz_;
};
VisitorImpl visitor;
if (!accept(&visitor, true, false)) {
visitor.clear();
*ksp = 0;
*vbp = NULL;
*vsp = 0;
return NULL;
}
return visitor.pop(ksp, vbp, vsp);
}
/**
* Get a pair of the key and the value of the current record and remove
it atomically.
* @note Equal to the original Cursor::seize method except that paramet
ers are strings
* to contain the result and the return value is bool for success.
*/
bool seize(std::string* key, std::string* value) {
_assert_(key && value);
class VisitorImpl : public Visitor {
public:
explicit VisitorImpl(std::string* key, std::string* value) :
key_(key), value_(value), ok_(false) {}
bool ok() {
return ok_;
}
private:
const char* visit_full(const char* kbuf, size_t ksiz,
const char* vbuf, size_t vsiz, size_t* sp) {
key_->clear();
key_->append(kbuf, ksiz);
value_->clear();
value_->append(vbuf, vsiz);
ok_ = true;
return REMOVE;
}
std::string* key_;
std::string* value_;
bool ok_;
};
VisitorImpl visitor(key, value);
if (!accept(&visitor, true, false)) return false;
return visitor.ok();
}
/**
* Get the database object. * Get the database object.
* @return the database object. * @return the database object.
*/ */
virtual BasicDB* db() = 0; virtual BasicDB* db() = 0;
/** /**
* Get the last happened error. * Get the last happened error.
* @return the last happened error. * @return the last happened error.
*/ */
Error error() { Error error() {
_assert_(true); _assert_(true);
skipping to change at line 1846 skipping to change at line 1935
return vbuf; return vbuf;
} }
/** /**
* Retrieve the value of a record. * Retrieve the value of a record.
* @note Equal to the original DB::get method except that the first param eters is the key * @note Equal to the original DB::get method except that the first param eters is the key
* string and the second parameter is a string to contain the result and the return value is * string and the second parameter is a string to contain the result and the return value is
* bool for success. * bool for success.
*/ */
bool get(const std::string& key, std::string* value) { bool get(const std::string& key, std::string* value) {
_assert_(value); _assert_(value);
size_t vsiz; class VisitorImpl : public Visitor {
char* vbuf = get(key.c_str(), key.size(), &vsiz); public:
if (!vbuf) return false; explicit VisitorImpl(std::string* value) : value_(value), ok_(false)
value->clear(); {}
value->append(vbuf, vsiz); bool ok() {
delete[] vbuf; return ok_;
}
private:
const char* visit_full(const char* kbuf, size_t ksiz,
const char* vbuf, size_t vsiz, size_t* sp) {
value_->clear();
value_->append(vbuf, vsiz);
ok_ = true;
return NOP;
}
std::string* value_;
bool ok_;
};
VisitorImpl visitor(value);
if (!accept(key.data(), key.size(), &visitor, false)) return false;
if (!visitor.ok()) {
set_error(_KCCODELINE_, Error::NOREC, "no record");
return false;
}
return true; return true;
} }
/** /**
* Retrieve the value of a record. * Retrieve the value of 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 vbuf the pointer to the buffer into which the value of the corr esponding record is * @param vbuf the pointer to the buffer into which the value of the corr esponding record is
* written. * written.
* @param max the size of the buffer. * @param max the size of the buffer.
* @return the size of the value, or -1 on failure. * @return the size of the value, or -1 on failure.
skipping to change at line 1893 skipping to change at line 1999
VisitorImpl visitor(vbuf, max); VisitorImpl visitor(vbuf, max);
if (!accept(kbuf, ksiz, &visitor, false)) return -1; if (!accept(kbuf, ksiz, &visitor, false)) return -1;
int32_t vsiz = visitor.vsiz(); int32_t vsiz = visitor.vsiz();
if (vsiz < 0) { if (vsiz < 0) {
set_error(_KCCODELINE_, Error::NOREC, "no record"); set_error(_KCCODELINE_, Error::NOREC, "no record");
return -1; return -1;
} }
return vsiz; return vsiz;
} }
/** /**
* Retrieve the value of a record and remove it atomically.
* @param kbuf the pointer to the key region.
* @param ksiz the size of the key region.
* @param sp the pointer to the variable into which the size of the regio
n of the return
* value is assigned.
* @return the pointer to the value region of the corresponding record, o
r NULL on failure.
* @note If no record corresponds to the key, NULL is returned. Because
an additional zero
* code is appended at the end of the region of the return value, the ret
urn value can be
* treated as a C-style string. Because the region of the return value i
s allocated with the
* the new[] operator, it should be released with the delete[] operator w
hen it is no longer
* in use.
*/
char* seize(const char* kbuf, size_t ksiz, size_t* sp) {
_assert_(kbuf && ksiz <= MEMMAXSIZ && sp);
class VisitorImpl : public Visitor {
public:
explicit VisitorImpl() : vbuf_(NULL), vsiz_(0) {}
char* pop(size_t* sp) {
*sp = vsiz_;
return vbuf_;
}
private:
const char* visit_full(const char* kbuf, size_t ksiz,
const char* vbuf, size_t vsiz, size_t* sp) {
vbuf_ = new char[vsiz+1];
std::memcpy(vbuf_, vbuf, vsiz);
vbuf_[vsiz] = '\0';
vsiz_ = vsiz;
return REMOVE;
}
char* vbuf_;
size_t vsiz_;
};
VisitorImpl visitor;
if (!accept(kbuf, ksiz, &visitor, true)) {
*sp = 0;
return NULL;
}
size_t vsiz;
char* vbuf = visitor.pop(&vsiz);
if (!vbuf) {
set_error(_KCCODELINE_, Error::NOREC, "no record");
*sp = 0;
return NULL;
}
*sp = vsiz;
return vbuf;
}
/**
* Retrieve the value of a record and remove it atomically.
* @note Equal to the original DB::seize method except that the first par
ameters is the key
* string and the second parameter is a string to contain the result and
the return value is
* bool for success.
*/
bool seize(const std::string& key, std::string* value) {
_assert_(value);
class VisitorImpl : public Visitor {
public:
explicit VisitorImpl(std::string* value) : value_(value), ok_(false)
{}
bool ok() {
return ok_;
}
private:
const char* visit_full(const char* kbuf, size_t ksiz,
const char* vbuf, size_t vsiz, size_t* sp) {
value_->clear();
value_->append(vbuf, vsiz);
ok_ = true;
return REMOVE;
}
std::string* value_;
bool ok_;
};
VisitorImpl visitor(value);
if (!accept(key.data(), key.size(), &visitor, true)) return false;
if (!visitor.ok()) {
set_error(_KCCODELINE_, Error::NOREC, "no record");
return false;
}
return true;
}
/**
* Store records at once. * Store records at once.
* @param recs the records to store. * @param recs the records to store.
* @param atomic true to perform all operations atomically, or false for non-atomic operations. * @param atomic true to perform all operations atomically, or false for non-atomic operations.
* @return the number of stored records, or -1 on failure. * @return the number of stored records, or -1 on failure.
*/ */
int64_t set_bulk(const std::map<std::string, std::string>& recs, bool ato mic = true) { int64_t set_bulk(const std::map<std::string, std::string>& recs, bool ato mic = true) {
_assert_(true); _assert_(true);
if (atomic) { if (atomic) {
std::vector<std::string> keys; std::vector<std::string> keys;
keys.reserve(recs.size()); keys.reserve(recs.size());
 End of changes. 3 change blocks. 
6 lines changed or deleted 215 lines changed or added


 kclangc.h   kclangc.h 
skipping to change at line 535 skipping to change at line 535
* @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 vbuf the pointer to the buffer into which the value of the corres ponding record is * @param vbuf the pointer to the buffer into which the value of the corres ponding record is
* written. * written.
* @param max the size of the buffer. * @param max the size of the buffer.
* @return the size of the value, or -1 on failure. * @return the size of the value, or -1 on failure.
*/ */
int32_t kcdbgetbuf(KCDB* db, const char* kbuf, size_t ksiz, char* vbuf, siz e_t max); int32_t kcdbgetbuf(KCDB* db, const char* kbuf, size_t ksiz, char* vbuf, siz e_t max);
/** /**
* Retrieve the value of a record and remove it atomically.
* @param db a database object.
* @param kbuf the pointer to the key region.
* @param ksiz the size of the key region.
* @param sp the pointer to the variable into which the size of the region
of the return
* value is assigned.
* @return the pointer to the value region of the corresponding record, or
NULL on failure.
* @note If no record corresponds to the key, NULL is returned. Because an
additional zero
* code is appended at the end of the region of the return value, the retur
n value can be
* treated as a C-style string. The region of the return value should be r
eleased with the
* kcfree function when it is no longer in use.
*/
char* kcdbseize(KCDB* db, const char* kbuf, size_t ksiz, size_t* sp);
/**
* Store records at once. * Store records at once.
* @param db a database object. * @param db a database object.
* @param recs the records to store. * @param recs the records to store.
* @param rnum specifies the number of the records. * @param rnum specifies the number of the records.
* @param atomic true to perform all operations atomically, or false for no n-atomic operations. * @param atomic true to perform all operations atomically, or false for no n-atomic operations.
* @return the number of stored records, or -1 on failure. * @return the number of stored records, or -1 on failure.
*/ */
int64_t kcdbsetbulk(KCDB* db, const KCREC* recs, size_t rnum, int32_t atomi c); int64_t kcdbsetbulk(KCDB* db, const KCREC* recs, size_t rnum, int32_t atomi c);
/** /**
skipping to change at line 817 skipping to change at line 832
* @param step true to move the cursor to the next record, or false for no move. * @param step true to move the cursor to the next record, or false for no move.
* @return the pointer to the pair of the key region, or NULL on failure. * @return the pointer to the pair of the key region, or NULL on failure.
* @note If the cursor is invalidated, NULL is returned. Because an additi onal zero code is * @note If the cursor is invalidated, NULL is returned. Because an additi onal zero code is
* appended at the end of each region of the key and the value, each region can be treated * appended at the end of each region of the key and the value, each region can be treated
* as a C-style string. The region of the return value should be released with the kcfree * as a C-style string. The region of the return value should be released with the kcfree
* function when it is no longer in use. * function when it is no longer in use.
*/ */
char* kccurget(KCCUR* cur, size_t* ksp, const char** vbp, size_t* vsp, int3 2_t step); char* kccurget(KCCUR* cur, size_t* ksp, const char** vbp, size_t* vsp, int3 2_t step);
/** /**
* Get a pair of the key and the value of the current record and remove it
atomically.
* @param cur a cursor object.
* @param ksp the pointer to the variable into which the size of the region
of the return
* value is assigned.
* @param vbp the pointer to the variable into which the pointer to the val
ue region is
* assigned.
* @param vsp the pointer to the variable into which the size of the value
region is
* assigned.
* @return the pointer to the pair of the key region, or NULL on failure.
* @note If the cursor is invalidated, NULL is returned. Because an additi
onal zero code is
* appended at the end of each region of the key and the value, each region
can be treated
* as a C-style string. The region of the return value should be released
with the kcfree
* function when it is no longer in use. The cursor is moved to the next r
ecord implicitly.
*/
char* kccurseize(KCCUR* cur, size_t* ksp, const char** vbp, size_t* vsp);
/**
* Jump the cursor to the first record for forward scan. * Jump the cursor to the first record for forward scan.
* @param cur a cursor object. * @param cur a cursor object.
* @return true on success, or false on failure. * @return true on success, or false on failure.
*/ */
int32_t kccurjump(KCCUR* cur); int32_t kccurjump(KCCUR* cur);
/** /**
* Jump the cursor to a record for forward scan. * Jump the cursor to a record for forward scan.
* @param cur a cursor object. * @param cur a cursor object.
* @param kbuf the pointer to the key region. * @param kbuf the pointer to the key region.
 End of changes. 2 change blocks. 
0 lines changed or deleted 45 lines changed or added


 kcplantdb.h   kcplantdb.h 
skipping to change at line 123 skipping to change at line 123
/** /**
* Cursor to indicate a record. * Cursor to indicate a record.
*/ */
class Cursor : public BasicDB::Cursor { class Cursor : public BasicDB::Cursor {
friend class PlantDB; friend class PlantDB;
public: public:
/** /**
* Constructor. * Constructor.
* @param db the container database object. * @param db the container database object.
*/ */
explicit Cursor(PlantDB* db) : db_(db), stack_(), kbuf_(NULL), ksiz_(0) explicit Cursor(PlantDB* db) :
, lid_(0) { db_(db), stack_(), kbuf_(NULL), ksiz_(0), lid_(0), back_(false) {
_assert_(db); _assert_(db);
ScopedRWLock lock(&db_->mlock_, true); ScopedRWLock lock(&db_->mlock_, true);
db_->curs_.push_back(this); db_->curs_.push_back(this);
} }
/** /**
* Destructor. * Destructor.
*/ */
virtual ~Cursor() { virtual ~Cursor() {
_assert_(true); _assert_(true);
if (!db_) return; if (!db_) return;
skipping to change at line 206 skipping to change at line 209
bool jump() { bool jump() {
_assert_(true); _assert_(true);
ScopedRWLock lock(&db_->mlock_, false); ScopedRWLock lock(&db_->mlock_, false);
if (db_->omode_ == 0) { if (db_->omode_ == 0) {
db_->set_error(_KCCODELINE_, Error::INVALID, "not opened"); db_->set_error(_KCCODELINE_, Error::INVALID, "not opened");
return false; return false;
} }
if (kbuf_) clear_position(); if (kbuf_) clear_position();
bool err = false; bool err = false;
if (!set_position(db_->first_)) err = true; if (!set_position(db_->first_)) err = true;
back_ = false;
return !err; return !err;
} }
/** /**
* Jump the cursor to a record for forward scan. * Jump the cursor to a record for forward scan.
* @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.
* @return true on success, or false on failure. * @return true on success, or false on failure.
*/ */
bool jump(const char* kbuf, size_t ksiz) { bool jump(const char* kbuf, size_t ksiz) {
_assert_(kbuf && ksiz <= MEMMAXSIZ); _assert_(kbuf && ksiz <= MEMMAXSIZ);
skipping to change at line 228 skipping to change at line 232
db_->set_error(_KCCODELINE_, Error::INVALID, "not opened"); db_->set_error(_KCCODELINE_, Error::INVALID, "not opened");
return false; return false;
} }
if (kbuf_) clear_position(); if (kbuf_) clear_position();
set_position(kbuf, ksiz, 0); set_position(kbuf, ksiz, 0);
bool err = false; bool err = false;
if (!adjust_position()) { if (!adjust_position()) {
if (kbuf_) clear_position(); if (kbuf_) clear_position();
err = true; err = true;
} }
back_ = false;
return !err; return !err;
} }
/** /**
* Jump the cursor to a record for forward scan. * Jump the cursor to a record for forward scan.
* @note Equal to the original Cursor::jump method except that the para meter is std::string. * @note Equal to the original Cursor::jump method except that the para meter is std::string.
*/ */
bool jump(const std::string& key) { bool jump(const std::string& key) {
_assert_(true); _assert_(true);
return jump(key.c_str(), key.size()); return jump(key.c_str(), key.size());
} }
skipping to change at line 254 skipping to change at line 259
bool jump_back() { bool jump_back() {
_assert_(true); _assert_(true);
ScopedRWLock lock(&db_->mlock_, false); ScopedRWLock lock(&db_->mlock_, false);
if (db_->omode_ == 0) { if (db_->omode_ == 0) {
db_->set_error(_KCCODELINE_, Error::INVALID, "not opened"); db_->set_error(_KCCODELINE_, Error::INVALID, "not opened");
return false; return false;
} }
if (kbuf_) clear_position(); if (kbuf_) clear_position();
bool err = false; bool err = false;
if (!set_position_back(db_->last_)) err = true; if (!set_position_back(db_->last_)) err = true;
back_ = true;
return !err; return !err;
} }
/** /**
* Jump the cursor to a record for backward scan. * Jump the cursor to a record for backward scan.
* @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.
* @return true on success, or false on failure. * @return true on success, or false on failure.
*/ */
bool jump_back(const char* kbuf, size_t ksiz) { bool jump_back(const char* kbuf, size_t ksiz) {
_assert_(kbuf && ksiz <= MEMMAXSIZ); _assert_(kbuf && ksiz <= MEMMAXSIZ);
skipping to change at line 291 skipping to change at line 297
} else { } else {
db_->set_error(_KCCODELINE_, Error::NOREC, "no record"); db_->set_error(_KCCODELINE_, Error::NOREC, "no record");
err = true; err = true;
} }
} }
} }
} else { } else {
if (kbuf_) clear_position(); if (kbuf_) clear_position();
if (!set_position_back(db_->last_)) err = true; if (!set_position_back(db_->last_)) err = true;
} }
back_ = true;
return !err; return !err;
} }
/** /**
* Jump the cursor to a record for backward scan. * Jump the cursor to a record for backward scan.
* @note Equal to the original Cursor::jump_back method except that the parameter is * @note Equal to the original Cursor::jump_back method except that the parameter is
* std::string. * std::string.
*/ */
bool jump_back(const std::string& key) { bool jump_back(const std::string& key) {
_assert_(true); _assert_(true);
return jump_back(key.c_str(), key.size()); return jump_back(key.c_str(), key.size());
skipping to change at line 314 skipping to change at line 321
* @return true on success, or false on failure. * @return true on success, or false on failure.
*/ */
bool step() { bool step() {
_assert_(true); _assert_(true);
DB::Visitor visitor; DB::Visitor visitor;
if (!accept(&visitor, false, true)) return false; if (!accept(&visitor, false, true)) return false;
if (!kbuf_) { if (!kbuf_) {
db_->set_error(_KCCODELINE_, Error::NOREC, "no record"); db_->set_error(_KCCODELINE_, Error::NOREC, "no record");
return false; return false;
} }
back_ = false;
return true; return true;
} }
/** /**
* Step the cursor to the previous record. * Step the cursor to the previous record.
* @return true on success, or false on failure. * @return true on success, or false on failure.
*/ */
bool step_back() { bool step_back() {
_assert_(true); _assert_(true);
db_->mlock_.lock_reader(); db_->mlock_.lock_reader();
if (db_->omode_ == 0) { if (db_->omode_ == 0) {
skipping to change at line 347 skipping to change at line 355
db_->mlock_.unlock(); db_->mlock_.unlock();
db_->mlock_.lock_writer(); db_->mlock_.lock_writer();
if (kbuf_) { if (kbuf_) {
if (!back_position_atom()) err = true; if (!back_position_atom()) err = true;
} else { } else {
db_->set_error(_KCCODELINE_, Error::NOREC, "no record"); db_->set_error(_KCCODELINE_, Error::NOREC, "no record");
err = true; err = true;
} }
} }
db_->mlock_.unlock(); db_->mlock_.unlock();
back_ = true;
return !err; return !err;
} }
/** /**
* Get the database object. * Get the database object.
* @return the database object. * @return the database object.
*/ */
PlantDB* db() { PlantDB* db() {
_assert_(true); _assert_(true);
return db_; return db_;
} }
skipping to change at line 516 skipping to change at line 525
node->dirty = true; node->dirty = true;
if (recs.size() <= 1) { if (recs.size() <= 1) {
lsiz = sizeof(Link) + ksiz; lsiz = sizeof(Link) + ksiz;
lbuf = lsiz > sizeof(lstack) ? new char[lsiz] : lstack; lbuf = lsiz > sizeof(lstack) ? new char[lsiz] : lstack;
link = (Link*)lbuf; link = (Link*)lbuf;
link->child = 0; link->child = 0;
link->ksiz = ksiz; link->ksiz = ksiz;
std::memcpy(lbuf + sizeof(*link), kbuf, ksiz); std::memcpy(lbuf + sizeof(*link), kbuf, ksiz);
} }
xfree(rec); xfree(rec);
typename RecordArray::iterator ritnext = rit + 1; if (back_) {
if (ritnext != ritend) { if (rit == recs.begin()) {
clear_position(); step = true;
set_position(*ritnext, node->id); } else {
step = false; typename RecordArray::iterator ritprev = rit - 1;
set_position(*ritprev, node->id);
step = false;
}
} else {
typename RecordArray::iterator ritnext = rit + 1;
if (ritnext == ritend) {
step = true;
} else {
clear_position();
set_position(*ritnext, node->id);
step = false;
}
} }
recs.erase(rit); recs.erase(rit);
} 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;
skipping to change at line 545 skipping to change at line 566
if (node->size > db_->psiz_ && recs.size() > 1) { if (node->size > db_->psiz_ && recs.size() > 1) {
lsiz = sizeof(Link) + ksiz; lsiz = sizeof(Link) + ksiz;
lbuf = lsiz > sizeof(lstack) ? new char[lsiz] : lstack; lbuf = lsiz > sizeof(lstack) ? new char[lsiz] : lstack;
link = (Link*)lbuf; link = (Link*)lbuf;
link->child = 0; link->child = 0;
link->ksiz = ksiz; link->ksiz = ksiz;
std::memcpy(lbuf + sizeof(*link), kbuf, ksiz); std::memcpy(lbuf + sizeof(*link), kbuf, ksiz);
} }
} }
if (step) { if (step) {
++rit; if (back_) {
if (rit != ritend) { if (rit != recs.begin()) {
clear_position(); --rit;
set_position(*rit, node->id); set_position(*rit, node->id);
step = false; step = false;
}
} else {
++rit;
if (rit != ritend) {
clear_position();
set_position(*rit, node->id);
step = false;
}
} }
} }
} }
} }
} }
bool atran = db_->autotran_ && !db_->tran_ && node->dirty; bool atran = db_->autotran_ && !db_->tran_ && node->dirty;
bool async = db_->autosync_ && !db_->autotran_ && !db_->tran_ && no de->dirty; bool async = db_->autosync_ && !db_->autotran_ && !db_->tran_ && no de->dirty;
node->lock.unlock(); node->lock.unlock();
if (hit && step) { if (hit && step) {
clear_position(); clear_position();
set_position(node->next); if (back_) {
set_position_back(node->prev);
} else {
set_position(node->next);
}
} }
if (hit) { if (hit) {
bool flush = db_->cusage_ > db_->pccap_; bool flush = db_->cusage_ > db_->pccap_;
if (link || flush || async) { if (link || flush || async) {
int64_t id = node->id; int64_t id = node->id;
if (atran && !link && !db_->fix_auto_transaction_leaf(node)) er r = true; if (atran && !link && !db_->fix_auto_transaction_leaf(node)) er r = true;
db_->mlock_.unlock(); db_->mlock_.unlock();
db_->mlock_.lock_writer(); db_->mlock_.lock_writer();
if (link) { if (link) {
node = db_->search_tree(link, true, hist, &hnum); node = db_->search_tree(link, true, hist, &hnum);
skipping to change at line 682 skipping to change at line 715
size_t vsiz; size_t vsiz;
const char* vbuf = visitor->visit_full(kbuf, ksiz, kbuf + ksiz, const char* vbuf = visitor->visit_full(kbuf, ksiz, kbuf + ksiz,
rec->vsiz, &vsiz); rec->vsiz, &vsiz);
if (vbuf == Visitor::REMOVE) { if (vbuf == Visitor::REMOVE) {
rsiz = sizeof(*rec) + rec->ksiz + rec->vsiz; rsiz = sizeof(*rec) + rec->ksiz + rec->vsiz;
db_->count_ -= 1; db_->count_ -= 1;
db_->cusage_ -= rsiz; db_->cusage_ -= rsiz;
node->size -= rsiz; node->size -= rsiz;
node->dirty = true; node->dirty = true;
xfree(rec); xfree(rec);
typename RecordArray::iterator ritnext = rit + 1; step = false;
if (ritnext != ritend) { clear_position();
clear_position(); if (back_) {
set_position(*ritnext, node->id); if (rit == recs.begin()) {
step = false; set_position_back(node->prev);
} else {
typename RecordArray::iterator ritprev = rit - 1;
set_position(*ritprev, node->id);
}
} else {
typename RecordArray::iterator ritnext = rit + 1;
if (ritnext == ritend) {
set_position(node->next);
} else {
set_position(*ritnext, node->id);
}
} }
recs.erase(rit); recs.erase(rit);
if (recs.empty()) 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);
} }
std::memcpy(kbuf + rec->ksiz, vbuf, vsiz); std::memcpy(kbuf + rec->ksiz, vbuf, vsiz);
rec->vsiz = vsiz; rec->vsiz = vsiz;
if (node->size > db_->psiz_ && recs.size() > 1) reorg = true; if (node->size > db_->psiz_ && recs.size() > 1) reorg = true;
} }
if (step) { if (step) {
++rit; clear_position();
if (rit != ritend) { if (back_) {
clear_position(); if (rit == recs.begin()) {
set_position(*rit, node->id); set_position_back(node->prev);
} else {
--rit;
set_position(*rit, node->id);
}
} else { } else {
clear_position(); ++rit;
set_position(node->next); if (rit == ritend) {
set_position(node->next);
} else {
set_position(*rit, node->id);
}
} }
} }
bool atran = db_->autotran_ && !db_->tran_ && node->dirty; bool atran = db_->autotran_ && !db_->tran_ && node->dirty;
bool async = db_->autosync_ && !db_->autotran_ && !db_->tran_ && no de->dirty; bool async = db_->autosync_ && !db_->autotran_ && !db_->tran_ && no de->dirty;
if (atran && !reorg && !db_->fix_auto_transaction_leaf(node)) err = true; if (atran && !reorg && !db_->fix_auto_transaction_leaf(node)) err = true;
if (reorg) { if (reorg) {
if (!db_->reorganize_tree(node, hist, hnum)) err = true; if (!db_->reorganize_tree(node, hist, hnum)) err = true;
if (atran && !db_->fix_auto_transaction_tree()) err = true; if (atran && !db_->fix_auto_transaction_tree()) err = true;
} else if (db_->cusage_ > db_->pccap_) { } else if (db_->cusage_ > db_->pccap_) {
int32_t idx = node->id % SLOTNUM; int32_t idx = node->id % SLOTNUM;
LeafSlot* lslot = db_->lslots_ + idx; LeafSlot* lslot = db_->lslots_ + idx;
if (!db_->flush_leaf_cache_part(lslot)) err = true; if (!db_->flush_leaf_cache_part(lslot)) err = true;
InnerSlot* islot = db_->islots_ + idx; InnerSlot* islot = db_->islots_ + idx;
if (islot->warm->count() > lslot->warm->count() + lslot->hot->cou nt() + 1 && if (islot->warm->count() > lslot->warm->count() + lslot->hot->cou nt() + 1 &&
!db_->flush_inner_cache_part(islot)) err = true; !db_->flush_inner_cache_part(islot)) err = true;
} }
if (async && !db_->fix_auto_synchronization()) err = true; if (async && !db_->fix_auto_synchronization()) err = true;
} else { } else {
int64_t lid = lid_; int64_t lid = lid_;
clear_position(); clear_position();
if (set_position(node->next)) { if (back_) {
if (lid_ == lid) { if (set_position_back(node->prev)) {
db_->set_error(_KCCODELINE_, Error::BROKEN, "invalid leaf node" if (lid_ == lid) {
); db_->set_error(_KCCODELINE_, Error::BROKEN, "invalid leaf nod
err = true; e");
err = true;
} else {
*retryp = true;
}
} else { } else {
*retryp = true; db_->set_error(_KCCODELINE_, Error::NOREC, "no record");
err = true;
} }
} else { } else {
db_->set_error(_KCCODELINE_, Error::NOREC, "no record"); if (set_position(node->next)) {
err = true; if (lid_ == lid) {
db_->set_error(_KCCODELINE_, Error::BROKEN, "invalid leaf nod
e");
err = true;
} else {
*retryp = true;
}
} else {
db_->set_error(_KCCODELINE_, Error::NOREC, "no record");
err = true;
}
} }
} }
if (rbuf != rstack) delete[] rbuf; if (rbuf != rstack) delete[] rbuf;
if (lbuf != lstack) delete[] lbuf; if (lbuf != lstack) delete[] lbuf;
return !err; return !err;
} }
/** /**
* Adjust the position to an existing record. * Adjust the position to an existing record.
* @return true on success, or false on failure. * @return true on success, or false on failure.
*/ */
skipping to change at line 914 skipping to change at line 980
/** The inner database. */ /** The inner database. */
PlantDB* db_; PlantDB* db_;
/** The stack buffer for the key. */ /** The stack buffer for the key. */
char stack_[KCPDRECBUFSIZ]; char stack_[KCPDRECBUFSIZ];
/** The pointer to the key region. */ /** The pointer to the key region. */
char* kbuf_; char* kbuf_;
/** The size of the key region. */ /** The size of the key region. */
size_t ksiz_; size_t ksiz_;
/** The last visited leaf. */ /** The last visited leaf. */
int64_t lid_; int64_t lid_;
/** The backward flag. */
bool back_;
}; };
/** /**
* Tuning options. * Tuning options.
*/ */
enum Option { enum Option {
TSMALL = BASEDB::TSMALL, ///< use 32-bit addressing TSMALL = BASEDB::TSMALL, ///< use 32-bit addressing
TLINEAR = BASEDB::TLINEAR, ///< use linear collision chaining TLINEAR = BASEDB::TLINEAR, ///< use linear collision chaining
TCOMPRESS = BASEDB::TCOMPRESS ///< compress each record TCOMPRESS = BASEDB::TCOMPRESS ///< compress each record
}; };
/** /**
 End of changes. 17 change blocks. 
32 lines changed or deleted 98 lines changed or added


 kcprotodb.h   kcprotodb.h 
skipping to change at line 126 skipping to change at line 126
if (db_->tran_) { if (db_->tran_) {
TranLog log(key, value); TranLog log(key, value);
db_->trlogs_.push_back(log); db_->trlogs_.push_back(log);
} }
db_->size_ -= key.size() + value.size(); db_->size_ -= key.size() + value.size();
if (db_->curs_.size() > 1) { if (db_->curs_.size() > 1) {
typename CursorList::const_iterator cit = db_->curs_.begin(); typename CursorList::const_iterator cit = db_->curs_.begin();
typename CursorList::const_iterator citend = db_->curs_.end(); typename CursorList::const_iterator citend = db_->curs_.end();
while (cit != citend) { while (cit != citend) {
Cursor* cur = *cit; Cursor* cur = *cit;
if (cur != this && cur->it_ == it_) cur->it_++; if (cur != this && cur->it_ == it_) ++cur->it_;
++cit; ++cit;
} }
} }
db_->recs_.erase(it_++); db_->recs_.erase(it_++);
} else if (vbuf == Visitor::NOP) { } else if (vbuf == Visitor::NOP) {
if (step) it_++; if (step) ++it_;
} else { } else {
if (db_->tran_) { if (db_->tran_) {
TranLog log(key, value); TranLog log(key, value);
db_->trlogs_.push_back(log); db_->trlogs_.push_back(log);
} }
db_->size_ -= value.size(); db_->size_ -= value.size();
db_->size_ += vsiz; db_->size_ += vsiz;
it_->second = std::string(vbuf, vsiz); it_->second = std::string(vbuf, vsiz);
if (step) it_++; if (step) ++it_;
} }
return true; return true;
} }
/** /**
* Jump the cursor to the first record for forward scan. * Jump the cursor to the first record for forward scan.
* @return true on success, or false on failure. * @return true on success, or false on failure.
*/ */
bool jump() { bool jump() {
_assert_(true); _assert_(true);
ScopedRWLock lock(&db_->mlock_, true); ScopedRWLock lock(&db_->mlock_, true);
skipping to change at line 279 skipping to change at line 279
_assert_(true); _assert_(true);
ScopedRWLock lock(&db_->mlock_, true); ScopedRWLock lock(&db_->mlock_, true);
if (db_->omode_ == 0) { if (db_->omode_ == 0) {
db_->set_error(_KCCODELINE_, Error::INVALID, "not opened"); db_->set_error(_KCCODELINE_, Error::INVALID, "not opened");
return false; return false;
} }
if (it_ == db_->recs_.end()) { if (it_ == db_->recs_.end()) {
db_->set_error(_KCCODELINE_, Error::NOREC, "no record"); db_->set_error(_KCCODELINE_, Error::NOREC, "no record");
return false; return false;
} }
it_++; ++it_;
if (it_ == db_->recs_.end()) { if (it_ == db_->recs_.end()) {
db_->set_error(_KCCODELINE_, Error::NOREC, "no record"); db_->set_error(_KCCODELINE_, Error::NOREC, "no record");
return false; return false;
} }
return true; return true;
} }
/** /**
* Step the cursor to the previous record. * Step the cursor to the previous record.
* @return true on success, or false on failure. * @return true on success, or false on failure.
*/ */
skipping to change at line 414 skipping to change at line 414
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_.empty()) { 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) {
if (tran_) { if (tran_) {
TranLog log(key, value); TranLog log(key, value);
trlogs_.push_back(log); trlogs_.push_back(log);
} }
size_ -= value.size(); size_ -= value.size();
skipping to change at line 513 skipping to change at line 513
if (tran_) { if (tran_) {
TranLog log(key, value); TranLog log(key, value);
trlogs_.push_back(log); trlogs_.push_back(log);
} }
size_ -= key.size() + value.size(); size_ -= key.size() + value.size();
if (!curs_.empty()) { 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) {
if (tran_) { if (tran_) {
TranLog log(key, value); TranLog log(key, value);
trlogs_.push_back(log); trlogs_.push_back(log);
} }
size_ -= value.size(); size_ -= value.size();
 End of changes. 6 change blocks. 
6 lines changed or deleted 6 lines changed or added


 kcthread.h   kcthread.h 
skipping to change at line 1068 skipping to change at line 1068
/** /**
* Destructor. * Destructor.
*/ */
virtual ~Task() { virtual ~Task() {
_assert_(true); _assert_(true);
} }
/** /**
* Get the ID number of the task. * Get the ID number of the task.
* @return the ID number of the task, which is incremented from 1. * @return the ID number of the task, which is incremented from 1.
*/ */
uint64_t id() { uint64_t id() const {
_assert_(true); _assert_(true);
return id_; return id_;
} }
/** /**
* Get the ID number of the worker thread. * Get the ID number of the worker thread.
* @return the ID number of the worker thread. It is from 0 to less th an the number of * @return the ID number of the worker thread. It is from 0 to less th an the number of
* worker threads. * worker threads.
*/ */
uint32_t thread_id() { uint32_t thread_id() const {
_assert_(true); _assert_(true);
return thid_; return thid_;
} }
/** /**
* Check whether the thread is to be aborted. * Check whether the thread is to be aborted.
* @return true if the thread is to be aborted, or false if not. * @return true if the thread is to be aborted, or false if not.
*/ */
bool aborted() { bool aborted() const {
_assert_(true); _assert_(true);
return aborted_; return aborted_;
} }
private: private:
/** The task ID number. */ /** The task ID number. */
uint64_t id_; uint64_t id_;
/** The thread ID number. */ /** The thread ID number. */
uint64_t thid_; uint64_t thid_;
/** The flag to be aborted. */ /** The flag to be aborted. */
bool aborted_; bool aborted_;
skipping to change at line 1115 skipping to change at line 1115
*/ */
virtual ~TaskQueue() { virtual ~TaskQueue() {
_assert_(true); _assert_(true);
} }
/** /**
* Process a task. * Process a task.
* @param task a task object. * @param task a task object.
*/ */
virtual void do_task(Task* task) = 0; virtual void do_task(Task* task) = 0;
/** /**
* Process the starting event.
* @param task a task object.
* @note This is called for each thread on starting.
*/
virtual void do_start(const Task* task) {
_assert_(true);
}
/**
* Process the finishing event.
* @param task a task object.
* @note This is called for each thread on finishing.
*/
virtual void do_finish(const Task* task) {
_assert_(true);
}
/**
* Start the task queue. * Start the task queue.
* @param thnum the number of worker threads. * @param thnum the number of worker threads.
*/ */
void start(size_t thnum) { void start(size_t thnum) {
_assert_(thnum > 0 && thnum <= MEMMAXSIZ); _assert_(thnum > 0 && thnum <= MEMMAXSIZ);
thary_ = new WorkerThread[thnum]; thary_ = new WorkerThread[thnum];
for (size_t i = 0; i < thnum; i++) { for (size_t i = 0; i < thnum; i++) {
thary_[i].id_ = i; thary_[i].id_ = i;
thary_[i].queue_ = this; thary_[i].queue_ = this;
thary_[i].start(); thary_[i].start();
skipping to change at line 1205 skipping to change at line 1221
*/ */
class WorkerThread : public Thread { class WorkerThread : public Thread {
friend class TaskQueue; friend class TaskQueue;
public: public:
explicit WorkerThread() : id_(0), queue_(NULL), aborted_(false) { explicit WorkerThread() : id_(0), queue_(NULL), aborted_(false) {
_assert_(true); _assert_(true);
} }
private: private:
void run() { void run() {
_assert_(true); _assert_(true);
Task* stask = new Task;
stask->thid_ = id_;
queue_->do_start(stask);
delete stask;
bool empty = false; bool empty = false;
while (true) { while (true) {
queue_->mutex_.lock(); queue_->mutex_.lock();
if (aborted_) { if (aborted_) {
queue_->mutex_.unlock(); queue_->mutex_.unlock();
break; break;
} }
if (empty) queue_->cond_.wait(&queue_->mutex_, 1.0); if (empty) queue_->cond_.wait(&queue_->mutex_, 1.0);
Task * task = NULL; Task * task = NULL;
if (queue_->tasks_.empty()) { if (queue_->tasks_.empty()) {
skipping to change at line 1226 skipping to change at line 1246
} else { } else {
task = queue_->tasks_.front(); task = queue_->tasks_.front();
task->thid_ = id_; task->thid_ = id_;
queue_->tasks_.pop_front(); queue_->tasks_.pop_front();
queue_->count_--; queue_->count_--;
empty = false; empty = false;
} }
queue_->mutex_.unlock(); queue_->mutex_.unlock();
if (task) queue_->do_task(task); if (task) queue_->do_task(task);
} }
Task* ftask = new Task;
ftask->thid_ = id_;
ftask->aborted_ = true;
queue_->do_finish(ftask);
delete ftask;
} }
uint32_t id_; uint32_t id_;
TaskQueue* queue_; TaskQueue* queue_;
Task* task_; Task* task_;
bool aborted_; bool aborted_;
}; };
/** Dummy constructor to forbid the use. */ /** Dummy constructor to forbid the use. */
TaskQueue(const TaskQueue&); TaskQueue(const TaskQueue&);
/** Dummy Operator to forbid the use. */ /** Dummy Operator to forbid the use. */
TaskQueue& operator =(const TaskQueue&); TaskQueue& operator =(const TaskQueue&);
 End of changes. 6 change blocks. 
3 lines changed or deleted 28 lines changed or added

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