static int rl_zset_get_objects(rlite *db, const unsigned char *key, long keylen, long *_levels_page_number, rl_btree **btree, long *btree_page, rl_skiplist **skiplist, long *skiplist_page, int update_version, int create) { long levels_page_number = 0, version = 0; int retval; unsigned long long expires = 0; if (create) { retval = rl_key_get_or_create(db, key, keylen, RL_TYPE_ZSET, &levels_page_number, &version); if (retval != RL_FOUND && retval != RL_NOT_FOUND) { goto cleanup; } else if (retval == RL_NOT_FOUND) { retval = rl_zset_create(db, levels_page_number, btree, btree_page, skiplist, skiplist_page); goto cleanup; } else { RL_CALL(rl_zset_read, RL_OK, db, levels_page_number, btree, btree_page, skiplist, skiplist_page); } } else { unsigned char type; retval = rl_key_get(db, key, keylen, &type, NULL, &levels_page_number, &expires, &version); if (retval != RL_FOUND) { goto cleanup; } if (type != RL_TYPE_ZSET) { retval = RL_WRONG_TYPE; goto cleanup; } RL_CALL(rl_zset_read, RL_OK, db, levels_page_number, btree, btree_page, skiplist, skiplist_page); } if (update_version) { RL_CALL(rl_key_set, RL_OK, db, key, keylen, RL_TYPE_ZSET, levels_page_number, expires, version + 1); } cleanup: if (_levels_page_number) { *_levels_page_number = levels_page_number; } return retval; }
int rl_key_get_or_create(struct rlite *db, const unsigned char *key, long keylen, unsigned char type, long *page, long *version) { unsigned char existing_type; int retval = rl_key_get(db, key, keylen, &existing_type, NULL, page, NULL, version); long _version; if (retval == RL_FOUND) { if (existing_type != type) { return RL_WRONG_TYPE; } } else if (retval == RL_NOT_FOUND) { _version = rand(); if (version) { *version = _version; } rl_alloc_page_number(db, page); RL_CALL(rl_key_set, RL_OK, db, key, keylen, type, *page, 0, _version); retval = RL_NOT_FOUND; } cleanup: return retval; }