static int zdel_one(SSDB *ssdb, const Bytes &name, const Bytes &key, char log_type){ if(name.size() > SSDB_KEY_LEN_MAX ){ log_error("name too long!"); return -1; } if(key.size() > SSDB_KEY_LEN_MAX){ log_error("key too long!"); return -1; } std::string old_score; int found = ssdb->zget(name, key, &old_score); if(found != 1){ return 0; } std::string k0, k1; // delete zscore key k1 = encode_zscore_key(name, key, old_score); ssdb->binlogs->Delete(k1); // delete zset k0 = encode_zset_key(name, key); ssdb->binlogs->Delete(k0); ssdb->binlogs->add_log(log_type, BinlogCommand::ZDEL, k0); return 1; }
// returns the number of newly added items static int zset_one(SSDB *ssdb, const Bytes &name, const Bytes &key, const Bytes &score, char log_type){ if(name.size() > SSDB_KEY_LEN_MAX ){ log_error("name too long!"); return -1; } if(key.size() > SSDB_KEY_LEN_MAX){ log_error("key too long!"); return -1; } std::string new_score = filter_score(score); std::string old_score; int found = ssdb->zget(name, key, &old_score); if(found == 0 || old_score != new_score){ std::string k0, k1, k2; if(found){ // delete zscore key k1 = encode_zscore_key(name, key, old_score); ssdb->binlogs->Delete(k1); } // add zscore key k2 = encode_zscore_key(name, key, new_score); ssdb->binlogs->Put(k2, ""); // update zset k0 = encode_zset_key(name, key); ssdb->binlogs->Put(k0, new_score); ssdb->binlogs->add(log_type, BinlogCommand::ZSET, k0); return found? 0 : 1; } return 0; }
int SSDB::zget(const Bytes &name, const Bytes &key, std::string *score) const{ std::string buf = encode_zset_key(name, key); leveldb::Status s = db->Get(leveldb::ReadOptions(), buf, score); if(s.IsNotFound()){ return 0; } if(!s.ok()){ log_error("zget error: %s", s.ToString().c_str()); return -1; } return 1; }
static int zdel_one(ldb_context_t *context, const ldb_slice_t* name, const ldb_slice_t* key, const ldb_meta_t* meta){ if(ldb_slice_size(name) > LDB_DATA_TYPE_KEY_LEN_MAX){ fprintf(stderr, "name too long!"); return -1; } if(ldb_slice_size(key) > LDB_DATA_TYPE_KEY_LEN_MAX){ fprintf(stderr, "key too long!"); return -1; } int64_t old_score = 0; int found = zset_get(context, name, key, &old_score); if(found != LDB_OK){ return 0; } ldb_slice_t *slice_key0, *slice_key1 = NULL; encode_zscore_key(ldb_slice_data(name), ldb_slice_size(name), ldb_slice_data(key), ldb_slice_size(key), meta, old_score, &slice_key1); ldb_context_writebatch_delete(context, ldb_slice_data(slice_key1), ldb_slice_size(slice_key1)); encode_zset_key(ldb_slice_data(name), ldb_slice_size(name), ldb_slice_data(key), ldb_slice_size(key), meta, &slice_key0); ldb_context_writebatch_delete(context, ldb_slice_data(slice_key0), ldb_slice_size(slice_key0)); return 1; }
int zset_get(ldb_context_t* context, const ldb_slice_t* name, const ldb_slice_t* key, int64_t* score){ char *val, *errptr = NULL; size_t vallen = 0; leveldb_readoptions_t* readoptions = leveldb_readoptions_create(); ldb_slice_t *slice_key = NULL; encode_zset_key(ldb_slice_data(name), ldb_slice_size(name), ldb_slice_data(key), ldb_slice_size(key), NULL, &slice_key); 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 = 0; if(errptr != NULL){ fprintf(stderr, "leveldb_get fail %s.\n", errptr); leveldb_free(errptr); retval = LDB_ERR; goto end; } if(val != NULL){ assert(vallen >= LDB_VAL_META_SIZE); uint8_t type = leveldb_decode_fixed8(val); if(type & LDB_VALUE_TYPE_VAL){ if(type & LDB_VALUE_TYPE_LAT){ retval = LDB_OK_NOT_EXIST; goto end; } *score = 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; }
static int zset_one(ldb_context_t *context, const ldb_slice_t* name, const ldb_slice_t* key, const ldb_meta_t* meta, int64_t score){ if(ldb_slice_size(name)==0 || ldb_slice_size(key)==0){ fprintf(stderr, "empty name or key!"); return 0; } if(ldb_slice_size(name) > LDB_DATA_TYPE_KEY_LEN_MAX){ fprintf(stderr, "name too long!"); return -1; } if(ldb_slice_size(key) > LDB_DATA_TYPE_KEY_LEN_MAX){ fprintf(stderr, "key too long!"); return -1; } int64_t old_score = 0; int found = zset_get(context, name, key, &old_score); if(found == LDB_OK_NOT_EXIST || old_score != score){ if(found != LDB_OK_NOT_EXIST){ ldb_slice_t *slice_key1 = NULL; //delete zscore key encode_zscore_key(ldb_slice_data(name), ldb_slice_size(name), ldb_slice_data(key), ldb_slice_size(key), meta, old_score, &slice_key1); ldb_context_writebatch_delete(context, ldb_slice_data(slice_key1), ldb_slice_size(slice_key1)); ldb_slice_destroy(slice_key1); } ldb_slice_t *slice_key2 = NULL; //add zscore key encode_zscore_key(ldb_slice_data(name), ldb_slice_size(name), ldb_slice_data(key), ldb_slice_size(key), meta, score, &slice_key2); //add zscore key char buf0[sizeof(uint64_t)] = {0}; leveldb_encode_fixed64(buf0, ldb_meta_nextver(meta)); ldb_context_writebatch_put(context, ldb_slice_data(slice_key2), ldb_slice_size(slice_key2), buf0, sizeof(buf0)); ldb_slice_destroy(slice_key2); ldb_slice_t *slice_key0 = NULL; //update zset encode_zset_key(ldb_slice_data(name), ldb_slice_size(name), ldb_slice_data(key), ldb_slice_size(key), meta, &slice_key0); char buf1[sizeof(int64_t)] = {0}; leveldb_encode_fixed64(buf1, score); ldb_context_writebatch_put(context, ldb_slice_data(slice_key0), ldb_slice_size(slice_key0), buf1, sizeof(int64_t)); ldb_slice_destroy(slice_key0); return (found==LDB_OK) ? 0 : 1; } return 0; }