void Ardb::Walk(KeyObject& key, bool reverse, WalkHandler* handler) { bool isFirstElement = true; Iterator* iter = FindValue(key); if (NULL != iter && !iter->Valid() && reverse) { iter->SeekToLast(); isFirstElement = false; } uint32 cursor = 0; while (NULL != iter && iter->Valid()) { Slice tmpkey = iter->Key(); KeyObject* kk = decode_key(tmpkey, &key); if (NULL == kk || kk->type != key.type || kk->key.compare(key.key) != 0) { DELETE(kk); if (reverse && isFirstElement) { iter->Prev(); isFirstElement = false; continue; } break; } ValueObject v; Buffer readbuf(const_cast<char*>(iter->Value().data()), 0, iter->Value().size()); decode_value(readbuf, v, false); int ret = handler->OnKeyValue(kk, &v, cursor++); DELETE(kk); if (ret < 0) { break; } if (reverse) { iter->Prev(); } else { iter->Next(); } } DELETE(iter); }
int Ardb::LastDB(DBID& db) { int ret = -1; Iterator* iter = NewIterator(ARDB_GLOBAL_DB); if (NULL != iter && iter->Valid()) { //Skip last KEY_END entry iter->Prev(); } if (NULL != iter && iter->Valid()) { Slice tmpkey = iter->Key(); KeyObject* kk = decode_key(tmpkey, NULL); if (NULL != kk) { db = kk->db; ret = 0; } DELETE(kk); } DELETE(iter); return ret; }
int Ardb::Randomkey(Context& ctx, RedisCommandFrame& cmd) { ctx.reply.type = REDIS_REPLY_NIL; KeyObject from; from.db = ctx.currentDB; from.type = KEY_META; std::string min_key, max_key, randkey; Iterator* iter = IteratorKeyValue(from, false); if (iter->Valid()) { KeyObject kk; if (!decode_key(iter->Key(), kk) || kk.db != ctx.currentDB || kk.type != KEY_META) { goto _end; } min_key.assign(kk.key.data(), kk.key.size()); max_key = min_key; from.type = SET_ELEMENT; //Refer comparator.cpp from.encode_buf.Clear(); IteratorSeek(iter, from); if (!iter->Valid()) { iter->SeekToLast(); } if (iter->Valid()) { iter->Prev(); if (iter->Valid()) { if (decode_key(iter->Key(), kk) && kk.db == ctx.currentDB && kk.type == KEY_META) { max_key.assign(kk.key.data(), kk.key.size()); } } } randkey = min_key; if (min_key < max_key) { randkey = random_between_string(min_key, max_key); from.type = KEY_META; from.db = ctx.currentDB; from.key = randkey; IteratorSeek(iter, from); if (iter->Valid()) { KeyObject kk; if (!decode_key(iter->Key(), kk) || kk.db != ctx.currentDB || kk.type != KEY_META) { goto _end; } randkey.assign(kk.key.data(), kk.key.size()); } } } if (!randkey.empty()) { fill_str_reply(ctx.reply, randkey); } _end: DELETE(iter); return 0; }