int SSDBImpl::zlist(const Bytes &name_s, const Bytes &name_e, uint64_t limit, std::vector<std::string> *list){ std::string start; std::string end; start = encode_zsize_key(name_s); if(!name_e.empty()){ end = encode_zsize_key(name_e); } Iterator *it = this->iterator(start, end, limit); get_znames(it, list); delete it; return 0; }
int SSDB::zdel(const Bytes &name, const Bytes &key) const{ std::string old_score; int found = this->zget(name, key, &old_score); if(found != 1){ return 0; } leveldb::Status s; leveldb::WriteBatch batch; std::string k0, k1; // update zsize int64_t size = this->zsize(name); if(size == -1){ return -1; } size --; std::string size_key = encode_zsize_key(name); batch.Put(size_key, leveldb::Slice((char *)&size, sizeof(int64_t))); // delete score k0 = encode_zs_key(name, key); batch.Delete(k0); // delete zset key k1 = encode_z_key(name, key, old_score); batch.Delete(k1); s = db->Write(write_options, &batch); if(!s.ok()){ log_error("zdel error: %s", s.ToString().c_str()); return -1; } return 1; }
static int zset_incr_size(ldb_context_t *context, const ldb_slice_t* name, int64_t by){ uint64_t length = 0; zset_size(context, name, &length); int64_t size = (int64_t)length; size += by; ldb_slice_t *slice_key = NULL; encode_zsize_key(ldb_slice_data(name), ldb_slice_size(name), &slice_key); if(size <= 0){ ldb_context_writebatch_delete(context, ldb_slice_data(slice_key), ldb_slice_size(slice_key)); }else{ char buff[sizeof(uint64_t)] = {0}; length = size; leveldb_encode_fixed64(buff, length); ldb_context_writebatch_put(context, ldb_slice_data(slice_key), ldb_slice_size(slice_key), buff, sizeof(uint64_t)); } ldb_slice_destroy(slice_key); return 0; }
static int incr_zsize(SSDB *ssdb, const Bytes &name, int64_t incr){ int64_t size = ssdb->zsize(name); size += incr; std::string size_key = encode_zsize_key(name); if(size == 0){ ssdb->binlogs->Delete(size_key); }else{ ssdb->binlogs->Put(size_key, leveldb::Slice((char *)&size, sizeof(int64_t))); } return 0; }
int SSDB::zlist(const Bytes &name_s, const Bytes &name_e, uint64_t limit, std::vector<std::string> *list) const{ std::string start; std::string end; start = encode_zsize_key(name_s); if(!name_e.empty()){ end = encode_zsize_key(name_e); } Iterator *it = this->iterator(start, end, limit); while(it->next()){ Bytes ks = it->key(); //dump(ks.data(), ks.size()); if(ks.data()[0] != DataType::ZSIZE){ break; } std::string n; if(decode_zsize_key(ks, &n) == -1){ continue; } list->push_back(n); } delete it; return 0; }
int SSDB::zset(const Bytes &name, const Bytes &key, const Bytes &score) const{ if(name.size() > SSDB_KEY_LEN_MAX || key.size() > SSDB_KEY_LEN_MAX){ return -1; } std::string old_score; int found = this->zget(name, key, &old_score); if(found == 0 || old_score != score){ leveldb::Status s; leveldb::WriteBatch batch; std::string k0, k1, k2, v; if(found == 0){ // update zsize int64_t size = this->zsize(name); if(size == -1){ return -1; } size ++; std::string size_key = encode_zsize_key(name); batch.Put(size_key, leveldb::Slice((char *)&size, sizeof(int64_t))); } // delete zset key k1 = encode_z_key(name, key, old_score); batch.Delete(k1); // update score k0 = encode_zs_key(name, key); v.assign(score.data(), score.size()); batch.Put(k0, v); // add zset key k2 = encode_z_key(name, key, score); batch.Put(k2, ""); s = db->Write(write_options, &batch); if(!s.ok()){ log_error("zset error: %s", s.ToString().c_str()); return -1; } return 1; } return 0; }
int64_t SSDB::zsize(const Bytes &name) const{ std::string size_key = encode_zsize_key(name); std::string val; leveldb::Status s; s = db->Get(leveldb::ReadOptions(), size_key, &val); if(s.IsNotFound()){ return 0; }else if(!s.ok()){ return -1; }else{ if(val.size() != sizeof(uint64_t)){ return 0; } int64_t ret = *(int64_t *)val.data(); return ret < 0? 0 : ret; } }
int zset_size(ldb_context_t* context, const ldb_slice_t* name, uint64_t* size){ ldb_slice_t *slice_key = NULL; encode_zsize_key(ldb_slice_data(name), ldb_slice_size(name), &slice_key); char *val, *errptr = NULL; size_t vallen = 0; leveldb_readoptions_t* readoptions = leveldb_readoptions_create(); val = leveldb_get(context->database_, readoptions, ldb_slice_data(slice_key), ldb_slice_size(slice_key), &vallen, &errptr); leveldb_readoptions_destroy(readoptions); ldb_slice_destroy(slice_key); int retval = LDB_OK; if(errptr != NULL){ fprintf(stderr, "leveldb_get fail %s.\n", errptr); leveldb_free(errptr); retval = LDB_ERR; goto end; } if(val != NULL){ assert(vallen >= (sizeof(uint64_t) + LDB_VAL_META_SIZE)); uint8_t type = leveldb_decode_fixed8(val); if(type & LDB_VALUE_TYPE_VAL){ *size = leveldb_decode_fixed64(val + LDB_VAL_META_SIZE); retval = LDB_OK; }else{ retval = LDB_OK_NOT_EXIST; } }else{ retval = LDB_OK_NOT_EXIST; } end: if (val !=NULL){ leveldb_free(val); } return retval; }
int SSDBImpl::key_range(std::vector<std::string> *keys){ int ret = 0; std::string kstart, kend; std::string hstart, hend; std::string zstart, zend; std::string qstart, qend; Iterator *it; it = this->iterator(encode_kv_key(""), "", 1); if(it->next()){ Bytes ks = it->key(); if(ks.data()[0] == DataType::KV){ std::string n; if(decode_kv_key(ks, &n) == -1){ ret = -1; }else{ kstart = n; } } } delete it; it = this->rev_iterator(encode_kv_key("\xff"), "", 1); if(it->next()){ Bytes ks = it->key(); if(ks.data()[0] == DataType::KV){ std::string n; if(decode_kv_key(ks, &n) == -1){ ret = -1; }else{ kend = n; } } } delete it; it = this->iterator(encode_hsize_key(""), "", 1); if(it->next()){ Bytes ks = it->key(); if(ks.data()[0] == DataType::HSIZE){ std::string n; if(decode_hsize_key(ks, &n) == -1){ ret = -1; }else{ hstart = n; } } } delete it; it = this->rev_iterator(encode_hsize_key("\xff"), "", 1); if(it->next()){ Bytes ks = it->key(); if(ks.data()[0] == DataType::HSIZE){ std::string n; if(decode_hsize_key(ks, &n) == -1){ ret = -1; }else{ hend = n; } } } delete it; it = this->iterator(encode_zsize_key(""), "", 1); if(it->next()){ Bytes ks = it->key(); if(ks.data()[0] == DataType::ZSIZE){ std::string n; if(decode_hsize_key(ks, &n) == -1){ ret = -1; }else{ zstart = n; } } } delete it; it = this->rev_iterator(encode_zsize_key("\xff"), "", 1); if(it->next()){ Bytes ks = it->key(); if(ks.data()[0] == DataType::ZSIZE){ std::string n; if(decode_hsize_key(ks, &n) == -1){ ret = -1; }else{ zend = n; } } } delete it; it = this->iterator(encode_qsize_key(""), "", 1); if(it->next()){ Bytes ks = it->key(); if(ks.data()[0] == DataType::QSIZE){ std::string n; if(decode_qsize_key(ks, &n) == -1){ ret = -1; }else{ qstart = n; } } } delete it; it = this->rev_iterator(encode_qsize_key("\xff"), "", 1); if(it->next()){ Bytes ks = it->key(); if(ks.data()[0] == DataType::QSIZE){ std::string n; if(decode_qsize_key(ks, &n) == -1){ ret = -1; }else{ qend = n; } } } delete it; keys->push_back(kstart); keys->push_back(kend); keys->push_back(hstart); keys->push_back(hend); keys->push_back(zstart); keys->push_back(zend); keys->push_back(qstart); keys->push_back(qend); return ret; }