kcplantdb.h   kcplantdb.h 
skipping to change at line 2567 skipping to change at line 2567
* Save a leaf node. * Save a leaf node.
* @param node the leaf node. * @param node the leaf node.
* @return true on success, or false on failure. * @return true on success, or false on failure.
*/ */
bool save_leaf_node(LeafNode* node) { bool save_leaf_node(LeafNode* node) {
_assert_(node); _assert_(node);
ScopedRWLock lock(&node->lock, false); ScopedRWLock lock(&node->lock, false);
if (!node->dirty) return true; if (!node->dirty) return true;
bool err = false; bool err = false;
char hbuf[NUMBUFSIZ]; char hbuf[NUMBUFSIZ];
size_t hsiz = std::sprintf(hbuf, "%c%llX", LNPREFIX, (long long)node->i d); size_t hsiz = write_key(hbuf, LNPREFIX, node->id);
if (node->dead) { if (node->dead) {
if (!db_.remove(hbuf, hsiz) && db_.error().code() != Error::NOREC) er r = true; if (!db_.remove(hbuf, hsiz) && db_.error().code() != Error::NOREC) er r = true;
} else { } else {
char* rbuf = new char[node->size]; char* rbuf = new char[node->size];
char* wp = rbuf; char* wp = rbuf;
wp += writevarnum(wp, node->prev); wp += writevarnum(wp, node->prev);
wp += writevarnum(wp, node->next); wp += writevarnum(wp, node->next);
typename RecordArray::const_iterator rit = node->recs.begin(); typename RecordArray::const_iterator rit = node->recs.begin();
typename RecordArray::const_iterator ritend = node->recs.end(); typename RecordArray::const_iterator ritend = node->recs.end();
while (rit != ritend) { while (rit != ritend) {
skipping to change at line 2622 skipping to change at line 2622
np = slot->warm->migrate(id, slot->hot, LeafCache::MLAST); np = slot->warm->migrate(id, slot->hot, LeafCache::MLAST);
if (np) { if (np) {
(*np)->hot = true; (*np)->hot = true;
return *np; return *np;
} }
} else { } else {
LeafNode** np = slot->warm->get(id, LeafCache::MLAST); LeafNode** np = slot->warm->get(id, LeafCache::MLAST);
if (np) return *np; if (np) return *np;
} }
char hbuf[NUMBUFSIZ]; char hbuf[NUMBUFSIZ];
size_t hsiz = std::sprintf(hbuf, "%c%llX", LNPREFIX, (long long)id); size_t hsiz = write_key(hbuf, LNPREFIX, id);
class VisitorImpl : public DB::Visitor { class VisitorImpl : public DB::Visitor {
public: public:
explicit VisitorImpl() : node_(NULL) {} explicit VisitorImpl() : node_(NULL) {}
LeafNode* pop() { LeafNode* pop() {
return node_; return node_;
} }
private: private:
const char* visit_full(const char* kbuf, size_t ksiz, const char* visit_full(const char* kbuf, size_t ksiz,
const char* vbuf, size_t vsiz, size_t* sp) { const char* vbuf, size_t vsiz, size_t* sp) {
uint64_t prev; uint64_t prev;
skipping to change at line 2945 skipping to change at line 2945
/** /**
* Save a inner node. * Save a inner node.
* @param node the inner node. * @param node the inner node.
* @return true on success, or false on failure. * @return true on success, or false on failure.
*/ */
bool save_inner_node(InnerNode* node) { bool save_inner_node(InnerNode* node) {
_assert_(true); _assert_(true);
if (!node->dirty) return true; if (!node->dirty) return true;
bool err = false; bool err = false;
char hbuf[NUMBUFSIZ]; char hbuf[NUMBUFSIZ];
size_t hsiz = std::sprintf(hbuf, "%c%llX", size_t hsiz = write_key(hbuf, INPREFIX, node->id - INIDBASE);
INPREFIX, (long long)(node->id - INIDBASE));
if (node->dead) { if (node->dead) {
if (!db_.remove(hbuf, hsiz) && db_.error().code() != Error::NOREC) er r = true; if (!db_.remove(hbuf, hsiz) && db_.error().code() != Error::NOREC) er r = true;
} else { } else {
char* rbuf = new char[node->size]; char* rbuf = new char[node->size];
char* wp = rbuf; char* wp = rbuf;
wp += writevarnum(wp, node->heir); wp += writevarnum(wp, node->heir);
typename LinkArray::const_iterator lit = node->links.begin(); typename LinkArray::const_iterator lit = node->links.begin();
typename LinkArray::const_iterator litend = node->links.end(); typename LinkArray::const_iterator litend = node->links.end();
while (lit != litend) { while (lit != litend) {
Link* link = *lit; Link* link = *lit;
skipping to change at line 2983 skipping to change at line 2982
* @return the loaded inner node. * @return the loaded inner node.
*/ */
InnerNode* load_inner_node(int64_t id) { InnerNode* load_inner_node(int64_t id) {
_assert_(id > 0); _assert_(id > 0);
int32_t sidx = id % SLOTNUM; int32_t sidx = id % SLOTNUM;
InnerSlot* slot = islots_ + sidx; InnerSlot* slot = islots_ + sidx;
ScopedMutex lock(&slot->lock); ScopedMutex lock(&slot->lock);
InnerNode** np = slot->warm->get(id, InnerCache::MLAST); InnerNode** np = slot->warm->get(id, InnerCache::MLAST);
if (np) return *np; if (np) return *np;
char hbuf[NUMBUFSIZ]; char hbuf[NUMBUFSIZ];
size_t hsiz = std::sprintf(hbuf, "%c%llX", INPREFIX, (long long)(id - I NIDBASE)); size_t hsiz = write_key(hbuf, INPREFIX, id - INIDBASE);
class VisitorImpl : public DB::Visitor { class VisitorImpl : public DB::Visitor {
public: public:
explicit VisitorImpl() : node_(NULL) {} explicit VisitorImpl() : node_(NULL) {}
InnerNode* pop() { InnerNode* pop() {
return node_; return node_;
} }
private: private:
const char* visit_full(const char* kbuf, size_t ksiz, const char* visit_full(const char* kbuf, size_t ksiz,
const char* vbuf, size_t vsiz, size_t* sp) { const char* vbuf, size_t vsiz, size_t* sp) {
uint64_t heir; uint64_t heir;
skipping to change at line 3834 skipping to change at line 3833
*/ */
bool fix_auto_synchronization() { bool fix_auto_synchronization() {
_assert_(true); _assert_(true);
bool err = false; bool err = false;
if (!flush_leaf_cache(true)) err = true; if (!flush_leaf_cache(true)) err = true;
if (!flush_inner_cache(true)) err = true; if (!flush_inner_cache(true)) err = true;
if (!dump_meta()) err = true; if (!dump_meta()) err = true;
if (!db_.synchronize(true, NULL)) err = true; if (!db_.synchronize(true, NULL)) err = true;
return !err; return !err;
} }
/**
* Write the key pattern into a buffer.
* @param kbuf the destination buffer.
* @param pc the prefix character.
* @param id the ID number of the page.
* @return the size of the key pattern.
*/
size_t write_key(char* kbuf, int32_t pc, int64_t num) {
_assert_(kbuf && num >= 0);
char* wp = kbuf;
*(wp++) = pc;
bool hit = false;
for (size_t i = 0; i < sizeof(num); i++) {
uint8_t c = num >> ((sizeof(num) - 1 - i) * 8);
uint8_t h = c >> 4;
if (h < 10) {
if (hit || h != 0) {
*(wp++) = '0' + h;
hit = true;
}
} else {
*(wp++) = 'A' - 10 + h;
hit = true;
}
uint8_t l = c & 0xf;
if (l < 10) {
if (hit || l != 0) {
*(wp++) = '0' + l;
hit = true;
}
} else {
*(wp++) = 'A' - 10 + l;
hit = true;
}
}
return wp - kbuf;
}
/** Dummy constructor to forbid the use. */ /** Dummy constructor to forbid the use. */
PlantDB(const PlantDB&); PlantDB(const PlantDB&);
/** Dummy Operator to forbid the use. */ /** Dummy Operator to forbid the use. */
PlantDB& operator =(const PlantDB&); PlantDB& operator =(const PlantDB&);
/** The method lock. */ /** The method lock. */
RWLock mlock_; RWLock mlock_;
/** The internal meta operation trigger. */ /** The internal meta operation trigger. */
MetaTrigger* mtrigger_; MetaTrigger* mtrigger_;
/** The open mode. */ /** The open mode. */
uint32_t omode_; uint32_t omode_;
 End of changes. 5 change blocks. 
5 lines changed or deleted 41 lines changed or added


 kctextdb.h   kctextdb.h 
skipping to change at line 62 skipping to change at line 62
/** /**
* Cursor to indicate a record. * Cursor to indicate a record.
*/ */
class Cursor : public BasicDB::Cursor { class Cursor : public BasicDB::Cursor {
friend class TextDB; friend class TextDB;
public: public:
/** /**
* Constructor. * Constructor.
* @param db the container database object. * @param db the container database object.
*/ */
explicit Cursor(TextDB* db) : db_(db), off_(INT64MAX), end_(0), queue_( ) { explicit Cursor(TextDB* db) : db_(db), off_(INT64MAX), end_(0), queue_( ), line_() {
_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 114 skipping to change at line 114
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;
} }
off_ = 0; off_ = 0;
end_ = db_->file_.size(); end_ = db_->file_.size();
queue_.clear(); queue_.clear();
line_.clear();
if (off_ >= end_) { if (off_ >= 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;
} }
/** /**
* 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.
skipping to change at line 136 skipping to change at line 137
bool jump(const char* kbuf, size_t ksiz) { bool jump(const char* kbuf, size_t ksiz) {
_assert_(kbuf && ksiz <= MEMMAXSIZ); _assert_(kbuf && ksiz <= MEMMAXSIZ);
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;
} }
off_ = atoin(kbuf, ksiz); off_ = atoin(kbuf, ksiz);
end_ = db_->file_.size(); end_ = db_->file_.size();
queue_.clear(); queue_.clear();
line_.clear();
if (off_ >= end_) { if (off_ >= 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;
} }
/** /**
* 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.
*/ */
skipping to change at line 244 skipping to change at line 246
bool accept_impl(Visitor* visitor, bool step) { bool accept_impl(Visitor* visitor, bool step) {
_assert_(visitor); _assert_(visitor);
if (queue_.empty() && !read_next()) return false; if (queue_.empty() && !read_next()) return false;
if (queue_.empty()) { if (queue_.empty()) {
db_->set_error(_KCCODELINE_, Error::NOREC, "no record"); db_->set_error(_KCCODELINE_, Error::NOREC, "no record");
return false; return false;
} }
bool err = false; bool err = false;
const Record& rec = queue_.front(); const Record& rec = queue_.front();
char kbuf[NUMBUFSIZ]; char kbuf[NUMBUFSIZ];
size_t ksiz = std::sprintf(kbuf, "%020lld", (long long)rec.first); size_t ksiz = db_->write_key(kbuf, rec.first);
size_t vsiz; size_t vsiz;
const char* vbuf = visitor->visit_full(kbuf, ksiz, const char* vbuf = visitor->visit_full(kbuf, ksiz,
rec.second.data(), rec.second. size(), &vsiz); rec.second.data(), rec.second. size(), &vsiz);
if (vbuf != Visitor::NOP && vbuf != Visitor::REMOVE) { if (vbuf != Visitor::NOP && vbuf != Visitor::REMOVE) {
char stack[IOBUFSIZ]; char stack[IOBUFSIZ];
size_t rsiz = vsiz + 1; size_t rsiz = vsiz + 1;
char* rbuf = rsiz > sizeof(stack) ? new char[rsiz] : stack; char* rbuf = rsiz > sizeof(stack) ? new char[rsiz] : stack;
std::memcpy(rbuf, vbuf, vsiz); std::memcpy(rbuf, vbuf, vsiz);
rbuf[vsiz] = '\n'; rbuf[vsiz] = '\n';
if (!db_->file_.append(rbuf, rsiz)) { if (!db_->file_.append(rbuf, rsiz)) {
skipping to change at line 273 skipping to change at line 275
} }
if (step) queue_.pop_front(); if (step) queue_.pop_front();
return !err; return !err;
} }
/** /**
* Read the next record. * Read the next record.
* @return true on success, or false on failure. * @return true on success, or false on failure.
*/ */
bool read_next() { bool read_next() {
_assert_(true); _assert_(true);
std::string line;
while (off_ < end_) { while (off_ < end_) {
char stack[IOBUFSIZ]; char stack[IOBUFSIZ];
int64_t rsiz = end_ - off_; int64_t rsiz = end_ - off_;
if (rsiz > (int64_t)IOBUFSIZ) rsiz = IOBUFSIZ; if (rsiz > (int64_t)sizeof(stack)) rsiz = sizeof(stack);
if (!db_->file_.read_fast(off_, stack, rsiz)) { if (!db_->file_.read_fast(off_, stack, rsiz)) {
db_->set_error(_KCCODELINE_, Error::SYSTEM, db_->file_.error()); db_->set_error(_KCCODELINE_, Error::SYSTEM, db_->file_.error());
return false; return false;
} }
const char* rp = stack; const char* rp = stack;
const char* pv = rp; const char* pv = rp;
const char* ep = rp + rsiz; const char* ep = rp + rsiz;
while (rp < ep) { while (rp < ep) {
if (*rp == '\n') { if (*rp == '\n') {
line.append(pv, rp - pv); line_.append(pv, rp - pv);
Record rec; Record rec;
rec.first = off_ + pv - stack; rec.first = off_ + pv - stack;
rec.second = line; rec.second = line_;
queue_.push_back(rec); queue_.push_back(rec);
line.clear(); line_.clear();
rp++; rp++;
pv = rp; pv = rp;
} else { } else {
rp++; rp++;
} }
} }
line_.append(pv, rp - pv);
off_ += rsiz; off_ += rsiz;
if (!queue_.empty()) break; if (!queue_.empty()) break;
} }
return true; return true;
} }
/** Dummy constructor to forbid the use. */ /** Dummy constructor to forbid the use. */
Cursor(const Cursor&); Cursor(const Cursor&);
/** 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. */
TextDB* db_; TextDB* db_;
/** The current offset. */ /** The current offset. */
int64_t off_; int64_t off_;
/** The end offset. */ /** The end offset. */
int64_t end_; int64_t end_;
/** The queue of read lines. */ /** The queue of read lines. */
std::deque<Record> queue_; std::deque<Record> queue_;
/** The current line. */
std::string line_;
}; };
/** /**
* Default constructor. * Default constructor.
*/ */
explicit TextDB() : explicit TextDB() :
error_(), logger_(NULL), logkinds_(0), mtrigger_(NULL), error_(), logger_(NULL), logkinds_(0), mtrigger_(NULL),
omode_(0), writer_(false), autotran_(false), autosync_(false), omode_(0), writer_(false), autotran_(false), autosync_(false),
file_(), curs_(), path_("") { file_(), curs_(), path_("") {
_assert_(true); _assert_(true);
} }
skipping to change at line 934 skipping to change at line 938
bool iterate_impl(Visitor* visitor, ProgressChecker* checker) { bool iterate_impl(Visitor* visitor, ProgressChecker* checker) {
_assert_(visitor); _assert_(visitor);
if (checker && !checker->check("iterate", "beginning", 0, -1)) { if (checker && !checker->check("iterate", "beginning", 0, -1)) {
set_error(_KCCODELINE_, Error::LOGIC, "checker failed"); set_error(_KCCODELINE_, Error::LOGIC, "checker failed");
return false; return false;
} }
int64_t off = 0; int64_t off = 0;
int64_t end = file_.size(); int64_t end = file_.size();
int64_t curcnt = 0; int64_t curcnt = 0;
std::string line; std::string line;
char stack[IOBUFSIZ]; char stack[IOBUFSIZ*4];
while (off < end) { while (off < end) {
int64_t rsiz = end - off; int64_t rsiz = end - off;
if (rsiz > (int64_t)IOBUFSIZ) rsiz = IOBUFSIZ; if (rsiz > (int64_t)sizeof(stack)) rsiz = sizeof(stack);
if (!file_.read_fast(off, stack, rsiz)) { if (!file_.read_fast(off, stack, rsiz)) {
set_error(_KCCODELINE_, Error::SYSTEM, file_.error()); set_error(_KCCODELINE_, Error::SYSTEM, file_.error());
return false; return false;
} }
const char* rp = stack; const char* rp = stack;
const char* pv = rp; const char* pv = rp;
const char* ep = rp + rsiz; const char* ep = rp + rsiz;
while (rp < ep) { while (rp < ep) {
if (*rp == '\n') { if (*rp == '\n') {
line.append(pv, rp - pv);
char kbuf[NUMBUFSIZ]; char kbuf[NUMBUFSIZ];
size_t ksiz = std::sprintf(kbuf, "%020lld", (long long)(off + pv size_t ksiz = write_key(kbuf, off + pv - stack);
- stack)); const char* vbuf;
size_t vsiz; size_t vsiz;
const char* vbuf = visitor->visit_full(kbuf, ksiz, line.data(), l if (line.empty()) {
ine.size(), &vsiz); vbuf = visitor->visit_full(kbuf, ksiz, pv, rp - pv, &vsiz);
} else {
line.append(pv, rp - pv);
vbuf = visitor->visit_full(kbuf, ksiz, line.data(), line.size()
, &vsiz);
line.clear();
}
if (vbuf != Visitor::NOP && vbuf != Visitor::REMOVE) { if (vbuf != Visitor::NOP && vbuf != Visitor::REMOVE) {
char tstack[IOBUFSIZ]; char tstack[IOBUFSIZ];
size_t trsiz = vsiz + 1; size_t trsiz = vsiz + 1;
char* trbuf = trsiz > sizeof(tstack) ? new char[trsiz] : tstack ; char* trbuf = trsiz > sizeof(tstack) ? new char[trsiz] : tstack ;
std::memcpy(trbuf, vbuf, vsiz); std::memcpy(trbuf, vbuf, vsiz);
trbuf[vsiz] = '\n'; trbuf[vsiz] = '\n';
if (!file_.append(trbuf, trsiz)) { if (!file_.append(trbuf, trsiz)) {
set_error(_KCCODELINE_, Error::SYSTEM, file_.error()); set_error(_KCCODELINE_, Error::SYSTEM, file_.error());
if (trbuf != stack) delete[] trbuf; if (trbuf != stack) delete[] trbuf;
return false; return false;
} }
if (trbuf != tstack) delete[] trbuf; if (trbuf != tstack) delete[] trbuf;
} }
curcnt++; curcnt++;
if (checker && !checker->check("iterate", "processing", curcnt, - 1)) { if (checker && !checker->check("iterate", "processing", curcnt, - 1)) {
set_error(_KCCODELINE_, Error::LOGIC, "checker failed"); set_error(_KCCODELINE_, Error::LOGIC, "checker failed");
return false; return false;
} }
line.clear();
rp++; rp++;
pv = rp; pv = rp;
} else { } else {
rp++; rp++;
} }
} }
line.append(pv, rp - pv); line.append(pv, rp - pv);
off += rsiz; off += rsiz;
} }
if (checker && !checker->check("iterate", "ending", -1, -1)) { if (checker && !checker->check("iterate", "ending", -1, -1)) {
skipping to change at line 1062 skipping to change at line 1071
} }
private: private:
void run() { void run() {
TextDB* db = db_; TextDB* db = db_;
File* file = &db->file_; File* file = &db->file_;
Visitor* visitor = visitor_; Visitor* visitor = visitor_;
ProgressChecker* checker = checker_; ProgressChecker* checker = checker_;
int64_t off = begoff_; int64_t off = begoff_;
int64_t end = endoff_; int64_t end = endoff_;
std::string line; std::string line;
char stack[IOBUFSIZ]; char stack[IOBUFSIZ*4];
while (off < end) { while (off < end) {
int64_t rsiz = end - off; int64_t rsiz = end - off;
if (rsiz > (int64_t)IOBUFSIZ) rsiz = IOBUFSIZ; if (rsiz > (int64_t)sizeof(stack)) rsiz = sizeof(stack);
if (!file->read_fast(off, stack, rsiz)) { if (!file->read_fast(off, stack, rsiz)) {
db->set_error(_KCCODELINE_, Error::SYSTEM, file->error()); db->set_error(_KCCODELINE_, Error::SYSTEM, file->error());
return; return;
} }
const char* rp = stack; const char* rp = stack;
const char* pv = rp; const char* pv = rp;
const char* ep = rp + rsiz; const char* ep = rp + rsiz;
while (rp < ep) { while (rp < ep) {
if (*rp == '\n') { if (*rp == '\n') {
line.append(pv, rp - pv);
char kbuf[NUMBUFSIZ]; char kbuf[NUMBUFSIZ];
size_t ksiz = std::sprintf(kbuf, "%020lld", (long long)(off size_t ksiz = db->write_key(kbuf, off + pv - stack);
+ pv - stack)); if (line.empty()) {
size_t vsiz; size_t vsiz;
const char* vbuf = visitor->visit_full(kbuf, ksiz, line.dat visitor->visit_full(kbuf, ksiz, pv, rp - pv, &vsiz);
a(), line.size(), } else {
&vsiz); line.append(pv, rp - pv);
if (vbuf != Visitor::NOP && vbuf != Visitor::REMOVE) { size_t vsiz;
char tstack[IOBUFSIZ]; visitor->visit_full(kbuf, ksiz, line.data(), line.size(),
size_t trsiz = vsiz + 1; &vsiz);
char* trbuf = trsiz > sizeof(tstack) ? new char[trsiz] : line.clear();
tstack;
std::memcpy(trbuf, vbuf, vsiz);
trbuf[vsiz] = '\n';
if (!file->append(trbuf, trsiz)) {
db->set_error(_KCCODELINE_, Error::SYSTEM, file->error(
));
if (trbuf != stack) delete[] trbuf;
return;
}
if (trbuf != tstack) delete[] trbuf;
} }
if (checker && !checker->check("iterate", "processing", -1, -1)) { if (checker && !checker->check("iterate", "processing", -1, -1)) {
db->set_error(_KCCODELINE_, Error::LOGIC, "checker failed "); db->set_error(_KCCODELINE_, Error::LOGIC, "checker failed ");
return; return;
} }
line.clear();
rp++; rp++;
pv = rp; pv = rp;
} else { } else {
rp++; rp++;
} }
} }
line.append(pv, rp - pv); line.append(pv, rp - pv);
off += rsiz; off += rsiz;
} }
} }
skipping to change at line 1187 skipping to change at line 1187
_assert_(true); _assert_(true);
if (curs_.empty()) 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_ = INT64MAX; cur->off_ = INT64MAX;
++cit; ++cit;
} }
} }
/**
* Write the key pattern into a buffer.
* @param kbuf the destination buffer.
* @param off the offset of the record.
* @return the size of the key pattern.
*/
size_t write_key(char* kbuf, int64_t off) {
_assert_(kbuf && off >= 0);
for (size_t i = 0; i < sizeof(off); i++) {
uint8_t c = off >> ((sizeof(off) - 1 - i) * 8);
uint8_t h = c >> 4;
if (h < 10) {
*(kbuf++) = '0' + h;
} else {
*(kbuf++) = 'A' - 10 + h;
}
uint8_t l = c & 0xf;
if (l < 10) {
*(kbuf++) = '0' + l;
} else {
*(kbuf++) = 'A' - 10 + l;
}
}
return sizeof(off) * 2;
}
/** Dummy constructor to forbid the use. */ /** Dummy constructor to forbid the use. */
TextDB(const TextDB&); TextDB(const TextDB&);
/** Dummy Operator to forbid the use. */ /** Dummy Operator to forbid the use. */
TextDB& operator =(const TextDB&); TextDB& operator =(const TextDB&);
/** The method lock. */ /** The method lock. */
RWLock mlock_; RWLock mlock_;
/** The last happened error. */ /** The last happened error. */
TSD<Error> error_; TSD<Error> error_;
/** The internal logger. */ /** The internal logger. */
Logger* logger_; Logger* logger_;
 End of changes. 23 change blocks. 
39 lines changed or deleted 60 lines changed or added


 kcutil.h   kcutil.h 
skipping to change at line 352 skipping to change at line 352
std::string* strtoupper(std::string* str); std::string* strtoupper(std::string* str);
/** /**
* Convert the letters of a string into lower case. * Convert the letters of a string into lower case.
* @param str the string to convert. * @param str the string to convert.
* @return the string itself. * @return the string itself.
*/ */
std::string* strtolower(std::string* str); std::string* strtolower(std::string* str);
/** /**
* Check whether a string begins with a key.
* @param str the string.
* @param key the forward matching key string.
* @return true if the target string begins with the key, else, it is false
.
*/
bool strfwm(const std::string& str, const std::string& key);
/**
* Check whether a string ends with a key.
* @param str the string.
* @param key the backward matching key string.
* @return true if the target string ends with the key, else, it is false.
*/
bool strbwm(const std::string& str, const std::string& key);
/**
* Cut space characters at head or tail of a string. * Cut space characters at head or tail of a string.
* @param str the string to convert. * @param str the string to convert.
* @return the string itself. * @return the string itself.
*/ */
std::string* strtrim(std::string* str); std::string* strtrim(std::string* str);
/** /**
* Convert a UTF-8 string into a UCS-4 vector. * Convert a UTF-8 string into a UCS-4 array.
* @param src the source object. * @param src the source object.
* @param dest the destination object. * @param dest the destination object.
*/ */
void strutftoucs(const std::string& src, std::vector<uint32_t>* dest); void strutftoucs(const std::string& src, std::vector<uint32_t>* dest);
/** /**
* Convert a UCS-4 vector into a UTF-8 string. * Convert a UCS-4 array into a UTF-8 string.
* @param src the source object. * @param src the source object.
* @param dest the destination object. * @param dest the destination object.
*/ */
void strucstoutf(const std::vector<uint32_t>& src, std::string* dest); void strucstoutf(const std::vector<uint32_t>& src, std::string* dest);
/** /**
* Serialize a string vector object into a string object. * Serialize a string vector object into a string object.
* @param src the source object. * @param src the source object.
* @param dest the destination object. * @param dest the destination object.
*/ */
skipping to change at line 639 skipping to change at line 655
/** /**
* Check whether a string ends with a key by case insensitive evaluation. * Check whether a string ends with a key by case insensitive evaluation.
* @param str the string. * @param str the string.
* @param key the backward matching key string. * @param key the backward matching key string.
* @return true if the target string ends with the key, else, it is false. * @return true if the target string ends with the key, else, it is false.
*/ */
bool stribwm(const char* str, const char* key); bool stribwm(const char* str, const char* key);
/** /**
* Convert a UTF-8 string into a UCS-4 vector. * Get the number of characters in a UTF-8 string.
* @param str the UTF-8 string.
* @return the number of characters in the string.
*/
size_t strutflen(const char* str);
/**
* Convert a UTF-8 string into a UCS-4 array.
* @param src the source object. * @param src the source object.
* @param dest the destination object. It must have enough size. * @param dest the destination object. It must have enough size.
* @param np the pointer to the variable into which the number of elements in the destination * @param np the pointer to the variable into which the number of elements in the destination
* object is assgined. * object is assgined.
*/ */
void strutftoucs(const char* src, uint32_t* dest, size_t* np); void strutftoucs(const char* src, uint32_t* dest, size_t* np);
/** /**
* Convert a UCS-4 vector into a UTF-8 string. * Convert a UCS-4 array into a UTF-8 string.
* @param src the source object. * @param src the source object.
* @param snum the number of elements in the source object. * @param snum the number of elements in the source object.
* @param dest the destination object. It must have enough size. * @param dest the destination object. It must have enough size.
* @return the size of the result string. * @return the size of the result string.
*/ */
size_t strucstoutf(const uint32_t* src, size_t snum, char* dest); size_t strucstoutf(const uint32_t* src, size_t snum, char* dest);
/** /**
* Allocate a region on memory. * Allocate a region on memory.
* @param size the size of the region. * @param size the size of the region.
skipping to change at line 1547 skipping to change at line 1570
_assert_(str); _assert_(str);
size_t size = str->size(); size_t size = str->size();
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
int32_t c = (unsigned char)(*str)[i]; int32_t c = (unsigned char)(*str)[i];
if (c >= 'A' && c <= 'Z') (*str)[i] = c + ('a' - 'A'); if (c >= 'A' && c <= 'Z') (*str)[i] = c + ('a' - 'A');
} }
return str; return str;
} }
/** /**
* Check whether a string begins with a key.
*/
inline bool strfwm(const std::string& str, const std::string& key) {
_assert_(true);
size_t ksiz = key.size();
if (ksiz > str.size()) return false;
return !std::memcmp(str.data(), key.data(), ksiz);
}
/**
* Check whether a string ends with a key.
*/
inline bool strbwm(const std::string& str, const std::string& key) {
_assert_(true);
size_t ksiz = key.size();
if (ksiz > str.size()) return false;
return !std::memcmp(str.data() + str.size() - ksiz, key.data(), ksiz);
}
/**
* Cut space characters at head or tail of a string. * Cut space characters at head or tail of a string.
*/ */
inline std::string* strtrim(std::string* str) { inline std::string* strtrim(std::string* str) {
_assert_(str); _assert_(str);
size_t size = str->size(); size_t size = str->size();
size_t wi = 0; size_t wi = 0;
size_t li = 0; size_t li = 0;
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
int32_t c = (unsigned char)(*str)[i]; int32_t c = (unsigned char)(*str)[i];
if (c >= '\0' && c <= ' ') { if (c >= '\0' && c <= ' ') {
skipping to change at line 1568 skipping to change at line 1611
} else { } else {
(*str)[wi++] = c; (*str)[wi++] = c;
li = wi; li = wi;
} }
} }
str->resize(li); str->resize(li);
return str; return str;
} }
/** /**
* Convert a UTF-8 string into a UCS-4 vector. * Convert a UTF-8 string into a UCS-4 array.
*/ */
inline void strutftoucs(const std::string& src, std::vector<uint32_t>* dest ) { inline void strutftoucs(const std::string& src, std::vector<uint32_t>* dest ) {
_assert_(dest); _assert_(dest);
dest->reserve(dest->size() + src.size()); dest->reserve(dest->size() + src.size());
size_t size = src.size(); size_t size = src.size();
size_t ri = 0; size_t ri = 0;
while (ri < size) { while (ri < size) {
uint32_t c = (unsigned char)src[ri]; uint32_t c = (unsigned char)src[ri];
if (c < 0x80) { if (c < 0x80) {
dest->push_back(c); dest->push_back(c);
} else if (c < 0xe0) { } else if (c < 0xe0) {
if (ri + 1 < size) { if (c >= 0xc0 && ri + 1 < size) {
dest->push_back(((c & 0x1f) << 6) | (src[ri+1] & 0x3f)); c = ((c & 0x1f) << 6) | (src[ri+1] & 0x3f);
if (c >= 0x80) dest->push_back(c);
ri++; ri++;
} }
} else if (c < 0xf0) { } else if (c < 0xf0) {
if (ri + 2 < size) { if (ri + 2 < size) {
dest->push_back(((c & 0x0f) << 12) | ((src[ri+1] & 0x3f) << 6) | (s c = ((c & 0x0f) << 12) | ((src[ri+1] & 0x3f) << 6) | (src[ri+2] & 0
rc[ri+2] & 0x3f)); x3f);
if (c >= 0x800) dest->push_back(c);
ri += 2; ri += 2;
} }
} else if (c < 0xf8) { } else if (c < 0xf8) {
if (ri + 3 < size) { if (ri + 3 < size) {
dest->push_back(((c & 0x07) << 18) | ((src[ri+1] & 0x3f) << 12) | c = ((c & 0x07) << 18) | ((src[ri+1] & 0x3f) << 12) | ((src[ri+2] &
((src[ri+2] & 0x3f) << 6) | (src[ri+3] & 0x3f)); 0x3f) << 6) |
(src[ri+3] & 0x3f);
if (c >= 0x10000) dest->push_back(c);
ri += 3; ri += 3;
} }
} else if (c < 0xfc) { } else if (c < 0xfc) {
if (ri + 4 < size) { if (ri + 4 < size) {
dest->push_back(((c & 0x03) << 24) | ((src[ri+1] & 0x3f) << 18) | c = ((c & 0x03) << 24) | ((src[ri+1] & 0x3f) << 18) | ((src[ri+2] &
((src[ri+2] & 0x3f) << 12) | ((src[ri+3] & 0x3f) << 0x3f) << 12) |
6) | ((src[ri+3] & 0x3f) << 6) | (src[ri+4] & 0x3f);
(src[ri+4] & 0x3f)); if (c >= 0x200000) dest->push_back(c);
ri += 4; ri += 4;
} }
} else if (c < 0xfe) { } else if (c < 0xfe) {
if (ri + 5 < size) { if (ri + 5 < size) {
dest->push_back(((c & 0x01) << 30) | ((src[ri+1] & 0x3f) << 24) | c = ((c & 0x01) << 30) | ((src[ri+1] & 0x3f) << 24) | ((src[ri+2] &
((src[ri+2] & 0x3f) << 18) | ((src[ri+3] & 0x3f) << 0x3f) << 18) |
12) | ((src[ri+3] & 0x3f) << 12) | ((src[ri+4] & 0x3f) << 6) | (src[r
((src[ri+4] & 0x3f) << 6) | (src[ri+5] & 0x3f)); i+5] & 0x3f);
if (c >= 0x4000000) dest->push_back(c);
ri += 5; ri += 5;
} }
} }
ri++; ri++;
} }
} }
/** /**
* Convert a UCS-4 array into a UTF-8 string. * Convert a UCS-4 array into a UTF-8 string.
*/ */
skipping to change at line 2434 skipping to change at line 2480
int32_t sc = str[slen-i]; int32_t sc = str[slen-i];
if (sc >= 'A' && sc <= 'Z') sc += 'a' - 'A'; if (sc >= 'A' && sc <= 'Z') sc += 'a' - 'A';
int32_t kc = key[klen-i]; int32_t kc = key[klen-i];
if (kc >= 'A' && kc <= 'Z') kc += 'a' - 'A'; if (kc >= 'A' && kc <= 'Z') kc += 'a' - 'A';
if (sc != kc) return false; if (sc != kc) return false;
} }
return true; return true;
} }
/** /**
* Convert a UTF-8 string into a UCS-4 vector. * Get the number of characters in a UTF-8 string.
*/
inline size_t strutflen(const char* str) {
_assert_(str);
size_t len = 0;
while (*str != '\0') {
len += (*(unsigned char*)str & 0xc0) != 0x80;
str++;
}
return len;
}
/**
* Convert a UTF-8 string into a UCS-4 array.
*/ */
inline void strutftoucs(const char* src, uint32_t* dest, size_t* np) { inline void strutftoucs(const char* src, uint32_t* dest, size_t* np) {
_assert_(src && dest && np); _assert_(src && dest && np);
const unsigned char* rp = (unsigned char*)src; const unsigned char* rp = (unsigned char*)src;
size_t dnum = 0; size_t dnum = 0;
while (*rp != '\0') { while (*rp != '\0') {
uint32_t c = *rp; uint32_t c = *rp;
if (c < 0x80) { if (c < 0x80) {
dest[dnum++] = c; dest[dnum++] = c;
} else if (c < 0xe0) { } else if (c < 0xe0) {
if (rp[1] != '\0') { if (rp[1] != '\0') {
dest[dnum++] = ((c & 0x1f) << 6) | (rp[1] & 0x3f); c = ((c & 0x1f) << 6) | (rp[1] & 0x3f);
if (c >= 0x80) dest[dnum++] = c;
rp++; rp++;
} }
} else if (c < 0xf0) { } else if (c < 0xf0) {
if (rp[1] != '\0' && rp[2] != '\0') { if (rp[1] != '\0' && rp[2] != '\0') {
dest[dnum++] = ((c & 0x0f) << 12) | ((rp[1] & 0x3f) << 6) | (rp[2] c = ((c & 0x0f) << 12) | ((rp[1] & 0x3f) << 6) | (rp[2] & 0x3f);
& 0x3f); if (c >= 0x800) dest[dnum++] = c;
rp += 2; rp += 2;
} }
} else if (c < 0xf8) { } else if (c < 0xf8) {
if (rp[1] != '\0' && rp[2] != '\0' && rp[3] != '\0') { if (rp[1] != '\0' && rp[2] != '\0' && rp[3] != '\0') {
dest[dnum++] = ((c & 0x07) << 18) | ((rp[1] & 0x3f) << 12) c = ((c & 0x07) << 18) | ((rp[1] & 0x3f) << 12) | ((rp[2] & 0x3f) <
| ((rp[2] & 0x3f) << 6) | (rp[3] & 0x3f); < 6) |
(rp[3] & 0x3f);
if (c >= 0x10000) dest[dnum++] = c;
rp += 3; rp += 3;
} }
} else if (c < 0xfc) { } else if (c < 0xfc) {
if (rp[1] != '\0' && rp[2] != '\0' && rp[3] != '\0' && rp[4] != '\0') { if (rp[1] != '\0' && rp[2] != '\0' && rp[3] != '\0' && rp[4] != '\0') {
dest[dnum++] = ((c & 0x03) << 24) | ((rp[1] & 0x3f) << 18) | c = ((c & 0x03) << 24) | ((rp[1] & 0x3f) << 18) | ((rp[2] & 0x3f) <
((rp[2] & 0x3f) << 12) | ((rp[3] & 0x3f) << 6) | (rp[4] & 0x3f) < 12) |
; ((rp[3] & 0x3f) << 6) | (rp[4] & 0x3f);
if (c >= 0x200000) dest[dnum++] = c;
rp += 4; rp += 4;
} }
} else if (c < 0xfe) { } else if (c < 0xfe) {
if (rp[1] != '\0' && rp[2] != '\0' && rp[3] != '\0' && rp[4] != '\0' && rp[5] != '\0') { if (rp[1] != '\0' && rp[2] != '\0' && rp[3] != '\0' && rp[4] != '\0' && rp[5] != '\0') {
dest[dnum++] = ((c & 0x01) << 30) | ((rp[1] & 0x3f) << 24) | c = ((c & 0x01) << 30) | ((rp[1] & 0x3f) << 24) | ((rp[2] & 0x3f) <
((rp[2] & 0x3f) << 18) | ((rp[3] & 0x3f) << 12) | < 18) |
((rp[4] & 0x3f) << 6) | (rp[5] & 0x3f); ((rp[3] & 0x3f) << 12) | ((rp[4] & 0x3f) << 6) | (rp[5] & 0x3f)
;
if (c >= 0x4000000) dest[dnum++] = c;
rp += 5; rp += 5;
} }
} }
rp++; rp++;
} }
*np = dnum; *np = dnum;
} }
/** /**
* Convert a UCS-4 array into a UTF-8 string. * Convert a UCS-4 array into a UTF-8 string.
 End of changes. 18 change blocks. 
31 lines changed or deleted 99 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/