kcdb.h | kcdb.h | |||
---|---|---|---|---|
skipping to change at line 340 | skipping to change at line 340 | |||
/** | /** | |||
* Set the value of a record. | * Set the value of a record. | |||
* @note Equal to the original DB::append method except that the paramete rs are std::string. | * @note Equal to the original DB::append method except that the paramete rs are std::string. | |||
*/ | */ | |||
virtual bool append(const std::string& key, const std::string& value) = 0 ; | virtual bool append(const std::string& key, const std::string& value) = 0 ; | |||
/** | /** | |||
* Add a number to the numeric integer value of a record. | * Add a number to the numeric integer 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 num the additional number. | * @param num the additional number. | |||
* @param orig the origin number if no record corresponds to the key. If | ||||
it is INT64MIN and | ||||
* no record corresponds, this function fails. If it is INT64MAX, the va | ||||
lue is set as the | ||||
* additional number regardless of the current value. | ||||
* @return the result value, or kyotocabinet::INT64MIN on failure. | * @return the result value, or kyotocabinet::INT64MIN on failure. | |||
* @note If no record corresponds to the key, a new record is created wit | * @note The value is serialized as an 8-byte binary integer in big-endia | |||
h the initial value | n order, not a decimal | |||
* set by the additional value. The value is serialized as an 8-byte bin | * string. If existing value is not 8-byte, this function fails. | |||
ary integer in | ||||
* big-endian order, not a decimal string. If existing value is not 8-by | ||||
te, this function | ||||
* fails. | ||||
*/ | */ | |||
virtual int64_t increment(const char* kbuf, size_t ksiz, int64_t num) = 0 ; | virtual int64_t increment(const char* kbuf, size_t ksiz, int64_t num, int 64_t orig = 0) = 0; | |||
/** | /** | |||
* Add a number to the numeric integer value of a record. | * Add a number to the numeric integer value of a record. | |||
* @note Equal to the original DB::increment method except that the param eter is std::string. | * @note Equal to the original DB::increment method except that the param eter is std::string. | |||
*/ | */ | |||
virtual int64_t increment(const std::string& key, int64_t num) = 0; | virtual int64_t increment(const std::string& key, int64_t num, int64_t or ig = 0) = 0; | |||
/** | /** | |||
* Add a number to the numeric double value of a record. | * Add a number to the numeric double 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 num the additional number. | * @param num the additional number. | |||
* @param orig the origin number if no record corresponds to the key. If | ||||
it is negative | ||||
* infinity and no record corresponds, this function fails. If it is pos | ||||
itive infinity, the | ||||
* value is set as the additional number regardless of the current value. | ||||
* @return the result value, or Not-a-number on failure. | * @return the result value, or Not-a-number on failure. | |||
* @note If no record corresponds to the key, a new record is created wit | * @note The value is serialized as an 16-byte binary fixed-point number | |||
h the initial value | in big-endian order, | |||
* set by the additional value. The value is serialized as an 16-byte bi | * not a decimal string. If existing value is not 16-byte, this function | |||
nary fixed-point | fails. | |||
* number in big-endian order, not a decimal string. If existing value i | ||||
s not 16-byte, this | ||||
* function fails. | ||||
*/ | */ | |||
virtual double increment_double(const char* kbuf, size_t ksiz, double num | virtual double increment_double(const char* kbuf, size_t ksiz, double num | |||
) = 0; | , | |||
double orig = 0) = 0; | ||||
/** | /** | |||
* Add a number to the numeric double value of a record. | * Add a number to the numeric double value of a record. | |||
* @note Equal to the original DB::increment_double method except that th e parameter is | * @note Equal to the original DB::increment_double method except that th e parameter is | |||
* std::string. | * std::string. | |||
*/ | */ | |||
virtual double increment_double(const std::string& key, double num) = 0; | virtual double increment_double(const std::string& key, double num, doubl e orig = 0) = 0; | |||
/** | /** | |||
* Perform compare-and-swap. | * Perform compare-and-swap. | |||
* @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 ovbuf the pointer to the old value region. NULL means that no record corresponds. | * @param ovbuf the pointer to the old value region. NULL means that no record corresponds. | |||
* @param ovsiz the size of the old value region. | * @param ovsiz the size of the old value region. | |||
* @param nvbuf the pointer to the new value region. NULL means that the record is removed. | * @param nvbuf the pointer to the new value region. NULL means that the record is removed. | |||
* @param nvsiz the size of new old value region. | * @param nvsiz the size of new old value region. | |||
* @return true on success, or false on failure. | * @return true on success, or false on failure. | |||
*/ | */ | |||
skipping to change at line 1479 | skipping to change at line 1482 | |||
*/ | */ | |||
bool append(const std::string& key, const std::string& value) { | bool append(const std::string& key, const std::string& value) { | |||
_assert_(true); | _assert_(true); | |||
return append(key.c_str(), key.size(), value.c_str(), value.size()); | return append(key.c_str(), key.size(), value.c_str(), value.size()); | |||
} | } | |||
/** | /** | |||
* Add a number to the numeric value of a record. | * Add a number to the numeric 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 num the additional number. | * @param num the additional number. | |||
* @param orig the origin number if no record corresponds to the key. If | ||||
it is INT64MIN and | ||||
* no record corresponds, this function fails. If it is INT64MAX, the va | ||||
lue is set as the | ||||
* additional number regardless of the current value. | ||||
* @return the result value, or kyotocabinet::INT64MIN on failure. | * @return the result value, or kyotocabinet::INT64MIN on failure. | |||
* @note If no record corresponds to the key, a new record is created wit | * @note The value is serialized as an 8-byte binary integer in big-endia | |||
h the initial value | n order, not a decimal | |||
* set by the additional value. The value is serialized as an 8-byte bin | * string. If existing value is not 8-byte, this function fails. | |||
ary integer in | ||||
* big-endian order, not a decimal string. If existing value is not 8-by | ||||
te, this function | ||||
* fails. | ||||
*/ | */ | |||
int64_t increment(const char* kbuf, size_t ksiz, int64_t num) { | int64_t increment(const char* kbuf, size_t ksiz, int64_t num, int64_t ori g = 0) { | |||
_assert_(kbuf && ksiz <= MEMMAXSIZ); | _assert_(kbuf && ksiz <= MEMMAXSIZ); | |||
class VisitorImpl : public Visitor { | class VisitorImpl : public Visitor { | |||
public: | public: | |||
explicit VisitorImpl(int64_t num) : num_(num), big_(0) {} | explicit VisitorImpl(int64_t num, int64_t orig) : num_(num), orig_(or ig), big_(0) {} | |||
int64_t num() { | int64_t num() { | |||
return num_; | return num_; | |||
} | } | |||
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) { | |||
if (vsiz != sizeof(num_)) { | if (vsiz != sizeof(num_)) { | |||
num_ = INT64MIN; | num_ = INT64MIN; | |||
return NOP; | return NOP; | |||
} | } | |||
int64_t onum; | int64_t onum; | |||
std::memcpy(&onum, vbuf, vsiz); | if (orig_ == INT64MAX) { | |||
onum = ntoh64(onum); | onum = 0; | |||
if (num_ == 0) { | } else { | |||
num_ = onum; | std::memcpy(&onum, vbuf, vsiz); | |||
return NOP; | onum = ntoh64(onum); | |||
if (num_ == 0) { | ||||
num_ = onum; | ||||
return NOP; | ||||
} | ||||
} | } | |||
num_ += onum; | num_ += onum; | |||
big_ = hton64(num_); | big_ = hton64(num_); | |||
*sp = sizeof(big_); | *sp = sizeof(big_); | |||
return (const char*)&big_; | return (const char*)&big_; | |||
} | } | |||
const char* visit_empty(const char* kbuf, size_t ksiz, size_t* sp) { | const char* visit_empty(const char* kbuf, size_t ksiz, size_t* sp) { | |||
if (orig_ == INT64MIN) { | ||||
num_ = INT64MIN; | ||||
return NOP; | ||||
} | ||||
if (orig_ != INT64MAX) num_ += orig_; | ||||
big_ = hton64(num_); | big_ = hton64(num_); | |||
*sp = sizeof(big_); | *sp = sizeof(big_); | |||
return (const char*)&big_; | return (const char*)&big_; | |||
} | } | |||
int64_t num_; | int64_t num_; | |||
int64_t orig_; | ||||
uint64_t big_; | uint64_t big_; | |||
}; | }; | |||
VisitorImpl visitor(num); | VisitorImpl visitor(num, orig); | |||
if (!accept(kbuf, ksiz, &visitor, true)) return INT64MIN; | if (!accept(kbuf, ksiz, &visitor, num != 0 || orig != INT64MIN)) return | |||
INT64MIN; | ||||
num = visitor.num(); | num = visitor.num(); | |||
if (num == INT64MIN) { | if (num == INT64MIN) { | |||
set_error(_KCCODELINE_, Error::LOGIC, "logical inconsistency"); | set_error(_KCCODELINE_, Error::LOGIC, "logical inconsistency"); | |||
return num; | return num; | |||
} | } | |||
return num; | return num; | |||
} | } | |||
/** | /** | |||
* Add a number to the numeric value of a record. | * Add a number to the numeric value of a record. | |||
* @note Equal to the original DB::increment method except that the param eter is std::string. | * @note Equal to the original DB::increment method except that the param eter is std::string. | |||
*/ | */ | |||
int64_t increment(const std::string& key, int64_t num) { | int64_t increment(const std::string& key, int64_t num, int64_t orig = 0) { | |||
_assert_(true); | _assert_(true); | |||
return increment(key.c_str(), key.size(), num); | return increment(key.c_str(), key.size(), num, orig); | |||
} | } | |||
/** | /** | |||
* Add a number to the numeric double value of a record. | * Add a number to the numeric double 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 num the additional number. | * @param num the additional number. | |||
* @param orig the origin number if no record corresponds to the key. If | ||||
it is negative | ||||
* infinity and no record corresponds, this function fails. If it is pos | ||||
itive infinity, the | ||||
* value is set as the additional number regardless of the current value. | ||||
* @return the result value, or Not-a-number on failure. | * @return the result value, or Not-a-number on failure. | |||
* @note If no record corresponds to the key, a new record is created wit | * @note The value is serialized as an 16-byte binary fixed-point number | |||
h the initial value | in big-endian order, | |||
* set by the additional value. The value is serialized as an 16-byte bi | * not a decimal string. If existing value is not 16-byte, this function | |||
nary fixed-point | fails. | |||
* number in big-endian order, not a decimal string. If existing value i | ||||
s not 16-byte, this | ||||
* function fails. | ||||
*/ | */ | |||
double increment_double(const char* kbuf, size_t ksiz, double num) { | double increment_double(const char* kbuf, size_t ksiz, double num, double orig = 0) { | |||
_assert_(kbuf && ksiz <= MEMMAXSIZ); | _assert_(kbuf && ksiz <= MEMMAXSIZ); | |||
class VisitorImpl : public Visitor { | class VisitorImpl : public Visitor { | |||
public: | public: | |||
explicit VisitorImpl(double num) : DECUNIT(1000000000000000LL), num_( | explicit VisitorImpl(double num, double orig) : | |||
num), buf_() {} | DECUNIT(1000000000000000LL), num_(num), orig_(orig), buf_() {} | |||
double num() { | double num() { | |||
return num_; | return num_; | |||
} | } | |||
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) { | |||
if (vsiz != sizeof(buf_)) { | if (vsiz != sizeof(buf_)) { | |||
num_ = nan(); | num_ = nan(); | |||
return NOP; | return NOP; | |||
} | } | |||
int64_t linteg, lfract; | int64_t linteg, lfract; | |||
std::memcpy(&linteg, vbuf, sizeof(linteg)); | if (chkinf(orig_) && orig_ >= 0) { | |||
linteg = ntoh64(linteg); | linteg = 0; | |||
std::memcpy(&lfract, vbuf + sizeof(linteg), sizeof(lfract)); | lfract = 0; | |||
lfract = ntoh64(lfract); | } else { | |||
std::memcpy(&linteg, vbuf, sizeof(linteg)); | ||||
linteg = ntoh64(linteg); | ||||
std::memcpy(&lfract, vbuf + sizeof(linteg), sizeof(lfract)); | ||||
lfract = ntoh64(lfract); | ||||
} | ||||
if (lfract == INT64MIN && linteg == INT64MIN) { | if (lfract == INT64MIN && linteg == INT64MIN) { | |||
num_ = nan(); | num_ = nan(); | |||
return NOP; | return NOP; | |||
} else if (linteg == INT64MAX) { | } else if (linteg == INT64MAX) { | |||
num_ = HUGE_VAL; | num_ = HUGE_VAL; | |||
return NOP; | return NOP; | |||
} else if (linteg == INT64MIN) { | } else if (linteg == INT64MIN) { | |||
num_ = -HUGE_VAL; | num_ = -HUGE_VAL; | |||
return NOP; | return NOP; | |||
} | } | |||
if (num_ == 0.0) { | if (num_ == 0.0 && !(chkinf(orig_) && orig_ >= 0)) { | |||
num_ = linteg + (double)lfract / DECUNIT; | num_ = linteg + (double)lfract / DECUNIT; | |||
return NOP; | return NOP; | |||
} | } | |||
long double dinteg; | long double dinteg; | |||
long double dfract = std::modfl(num_, &dinteg); | long double dfract = std::modfl(num_, &dinteg); | |||
if (chknan(dinteg)) { | if (chknan(dinteg)) { | |||
linteg = INT64MIN; | linteg = INT64MIN; | |||
lfract = INT64MIN; | lfract = INT64MIN; | |||
num_ = nan(); | num_ = nan(); | |||
} else if (chkinf(dinteg)) { | } else if (chkinf(dinteg)) { | |||
skipping to change at line 1609 | skipping to change at line 1630 | |||
num_ = linteg + (double)lfract / DECUNIT; | num_ = linteg + (double)lfract / DECUNIT; | |||
} | } | |||
linteg = hton64(linteg); | linteg = hton64(linteg); | |||
std::memcpy(buf_, &linteg, sizeof(linteg)); | std::memcpy(buf_, &linteg, sizeof(linteg)); | |||
lfract = hton64(lfract); | lfract = hton64(lfract); | |||
std::memcpy(buf_ + sizeof(linteg), &lfract, sizeof(lfract)); | std::memcpy(buf_ + sizeof(linteg), &lfract, sizeof(lfract)); | |||
*sp = sizeof(buf_); | *sp = sizeof(buf_); | |||
return buf_; | return buf_; | |||
} | } | |||
const char* visit_empty(const char* kbuf, size_t ksiz, size_t* sp) { | const char* visit_empty(const char* kbuf, size_t ksiz, size_t* sp) { | |||
if (chknan(orig_) || (chkinf(orig_) && orig_ < 0)) { | ||||
num_ = nan(); | ||||
return NOP; | ||||
} | ||||
if (!chkinf(orig_)) num_ += orig_; | ||||
long double dinteg; | long double dinteg; | |||
long double dfract = std::modfl(num_, &dinteg); | long double dfract = std::modfl(num_, &dinteg); | |||
int64_t linteg, lfract; | int64_t linteg, lfract; | |||
if (chknan(dinteg)) { | if (chknan(dinteg)) { | |||
linteg = INT64MIN; | linteg = INT64MIN; | |||
lfract = INT64MIN; | lfract = INT64MIN; | |||
} else if (chkinf(dinteg)) { | } else if (chkinf(dinteg)) { | |||
linteg = dinteg > 0 ? INT64MAX : INT64MIN; | linteg = dinteg > 0 ? INT64MAX : INT64MIN; | |||
lfract = 0; | lfract = 0; | |||
} else { | } else { | |||
skipping to change at line 1631 | skipping to change at line 1657 | |||
} | } | |||
linteg = hton64(linteg); | linteg = hton64(linteg); | |||
std::memcpy(buf_, &linteg, sizeof(linteg)); | std::memcpy(buf_, &linteg, sizeof(linteg)); | |||
lfract = hton64(lfract); | lfract = hton64(lfract); | |||
std::memcpy(buf_ + sizeof(linteg), &lfract, sizeof(lfract)); | std::memcpy(buf_ + sizeof(linteg), &lfract, sizeof(lfract)); | |||
*sp = sizeof(buf_); | *sp = sizeof(buf_); | |||
return buf_; | return buf_; | |||
} | } | |||
const int64_t DECUNIT; | const int64_t DECUNIT; | |||
double num_; | double num_; | |||
double orig_; | ||||
char buf_[sizeof(int64_t)*2]; | char buf_[sizeof(int64_t)*2]; | |||
}; | }; | |||
VisitorImpl visitor(num); | VisitorImpl visitor(num, orig); | |||
if (!accept(kbuf, ksiz, &visitor, true)) return nan(); | if (!accept(kbuf, ksiz, &visitor, true)) return nan(); | |||
num = visitor.num(); | num = visitor.num(); | |||
if (chknan(num)) { | if (chknan(num)) { | |||
set_error(_KCCODELINE_, Error::LOGIC, "logical inconsistency"); | set_error(_KCCODELINE_, Error::LOGIC, "logical inconsistency"); | |||
return nan(); | return nan(); | |||
} | } | |||
return num; | return num; | |||
} | } | |||
/** | /** | |||
* Add a number to the numeric double value of a record. | * Add a number to the numeric double value of a record. | |||
* @note Equal to the original DB::increment_double method except that th e parameter is | * @note Equal to the original DB::increment_double method except that th e parameter is | |||
* std::string. | * std::string. | |||
*/ | */ | |||
double increment_double(const std::string& key, double num) { | double increment_double(const std::string& key, double num, double orig) { | |||
_assert_(true); | _assert_(true); | |||
return increment_double(key.c_str(), key.size(), num); | return increment_double(key.c_str(), key.size(), num, orig); | |||
} | } | |||
/** | /** | |||
* Perform compare-and-swap. | * Perform compare-and-swap. | |||
* @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 ovbuf the pointer to the old value region. NULL means that no record corresponds. | * @param ovbuf the pointer to the old value region. NULL means that no record corresponds. | |||
* @param ovsiz the size of the old value region. | * @param ovsiz the size of the old value region. | |||
* @param nvbuf the pointer to the new value region. NULL means that the record is removed. | * @param nvbuf the pointer to the new value region. NULL means that the record is removed. | |||
* @param nvsiz the size of new old value region. | * @param nvsiz the size of new old value region. | |||
* @return true on success, or false on failure. | * @return true on success, or false on failure. | |||
End of changes. 29 change blocks. | ||||
55 lines changed or deleted | 84 lines changed or added | |||