Beispiel #1
0
	bool Ardb::DBExist(const DBID& db, DBID& nextdb)
	{
		KeyObject start(Slice(), KV, db);
		Iterator* iter = FindValue(start, false);
		bool found = false;
		nextdb = db;
		if (NULL != iter && iter->Valid())
		{
			Slice tmpkey = iter->Key();
			KeyObject* kk = decode_key(tmpkey, NULL);
			if (NULL != kk)
			{
				if (kk->db == db)
				{
					found = true;
				} else
				{
					nextdb = kk->db;
				}
			}
			DELETE(kk);
		}
		DELETE(iter);
		return found;
	}
Beispiel #2
0
	int Ardb::FlushScripts()
	{
		KeyObject start(Slice(), SCRIPT, ARDB_GLOBAL_DB);
		Iterator* iter = FindValue(start, false);
		BatchWriteGuard guard(GetEngine());
		while (NULL != iter && iter->Valid())
		{
			Slice tmpkey = iter->Key();
			KeyObject* kk = decode_key(tmpkey, NULL);
			if (NULL != kk)
			{
				if (kk->type == SCRIPT)
				{
					DelValue(*kk);
				} else
				{
					break;
				}
			}
			DELETE(kk);
			iter->Next();
		}
		DELETE(iter);
		return 0;
	}
Beispiel #3
0
	void Ardb::PrintDB(const DBID& db)
	{
		Slice empty;
		KeyObject start(empty, KV, db);
		Iterator* iter = FindValue(start);
		while (NULL != iter && iter->Valid())
		{
			Slice tmpkey = iter->Key();
			KeyObject* kk = decode_key(tmpkey, NULL);
			if (kk->db != db)
			{
				DELETE(kk);
				break;
			}
			ValueObject v;
			Buffer readbuf(const_cast<char*>(iter->Value().data()), 0, iter->Value().size());
			decode_value(readbuf, v, false);
			if (NULL != kk)
			{
				std::string str;
				DEBUG_LOG("[%d]Key=%s, Value=%s", kk->type, kk->key.data(), v.ToString(str).c_str());
			}
			DELETE(kk);
			iter->Next();
		}
		DELETE(iter);
	}
Beispiel #4
0
	void Ardb::Walk(WalkHandler* handler)
	{
		KeyObject start(Slice(), KV, 0);
		Iterator* iter = FindValue(start);
		uint32 cursor = 0;
		while (NULL != iter && iter->Valid())
		{
			Slice tmpkey = iter->Key();
			KeyObject* kk = decode_key(tmpkey, NULL);
			if (NULL == kk)
			{
				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;
			}
			iter->Next();
		}
		DELETE(iter);
	}
Beispiel #5
0
	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);
	}
Beispiel #6
0
	int Ardb::FirstDB(DBID& db)
	{
		int ret = -1;
		Iterator* iter = NewIterator();
		iter->SeekToFirst();
		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;
	}
Beispiel #7
0
	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;
	}
Beispiel #8
0
    int Ardb::Scan(Context& ctx, RedisCommandFrame& cmd)
    {
        StringArray keys;
        std::string pattern;
        uint32 limit = 10000; //return max 10000 keys one time
        if (cmd.GetArguments().size() > 1)
        {
            for (uint32 i = 1; i < cmd.GetArguments().size(); i++)
            {
                if (!strcasecmp(cmd.GetArguments()[i].c_str(), "count"))
                {
                    if (i + 1 >= cmd.GetArguments().size() || !string_touint32(cmd.GetArguments()[i + 1], limit))
                    {
                        fill_error_reply(ctx.reply, "value is not an integer or out of range");
                        return 0;
                    }
                    i++;
                }
                else if (!strcasecmp(cmd.GetArguments()[i].c_str(), "match"))
                {
                    if (i + 1 >= cmd.GetArguments().size())
                    {
                        fill_error_reply(ctx.reply, "'MATCH' need one args followed");
                        return 0;
                    }
                    pattern = cmd.GetArguments()[i + 1];
                    i++;
                }
                else
                {
                    fill_error_reply(ctx.reply, "Syntax error, try scan 0 ");
                    return 0;
                }
            }
        }
        RedisReply& r1 = ctx.reply.AddMember();
        RedisReply& r2 = ctx.reply.AddMember();
        r2.type = REDIS_REPLY_ARRAY;

        KeyObject from;
        from.db = ctx.currentDB;
        from.type = KEY_META;
        const std::string& cursor = cmd.GetArguments()[0];
        std::string scan_start_cursor;
        if (cmd.GetArguments()[0] != "0")
        {
            if (m_cfg.scan_redis_compatible)
            {
                FindElementByRedisCursor(cursor, scan_start_cursor);
            }
            from.key = scan_start_cursor;
        }
        Iterator* iter = IteratorKeyValue(from, false);
        bool reachend = false;
        std::string tmpkey;
        while (NULL != iter && iter->Valid())
        {
            KeyObject kk;
            if (!decode_key(iter->Key(), kk) || kk.db != ctx.currentDB || kk.type != KEY_META)
            {
                reachend = true;
                break;
            }
            tmpkey.clear();
            tmpkey.assign(kk.key.data(), kk.key.size());
            if (r2.MemberSize() >= limit)
            {
                break;
            }
            if ((pattern.empty()
                    || stringmatchlen(pattern.c_str(), pattern.size(), tmpkey.c_str(), tmpkey.size(), 0) == 1))
            {
                RedisReply& rr1 = r2.AddMember();
                fill_str_reply(rr1, tmpkey);
            }
            iter->Next();
        }
        if (reachend || !iter->Valid())
        {
            fill_str_reply(r1, "0");
        }
        else
        {
            if (m_cfg.scan_redis_compatible)
            {
                uint64 newcursor = GetNewRedisCursor(tmpkey);
                fill_str_reply(r1, stringfromll(newcursor));
            }
            else
            {
                fill_str_reply(r1, tmpkey);
            }
        }
        DELETE(iter);
        return 0;
    }
Beispiel #9
0
    int Ardb::KeysOperation(Context& ctx, const KeysOptions& options)
    {
        KeyObject from;
        from.db = ctx.currentDB;
        from.type = KEY_META;

        std::string::size_type cursor = options.pattern.find("*");
        if (cursor == std::string::npos)
        {
            from.key = options.pattern;
        }
        else
        {
            if (options.pattern != "*" && cursor > 0)
            {
                from.key = options.pattern.substr(0, cursor);
            }
        }
        Iterator* iter = IteratorKeyValue(from, false);
        std::string tmpkey;
        uint32 count = 0;
        while (NULL != iter && iter->Valid())
        {
            KeyObject kk;
            if (!decode_key(iter->Key(), kk) || kk.db != ctx.currentDB || kk.type != KEY_META)
            {
                break;
            }
            tmpkey.clear();
            tmpkey.assign(kk.key.data(), kk.key.size());
            if ((options.pattern == "*"
                    || stringmatchlen(options.pattern.c_str(), options.pattern.size(), tmpkey.data(), tmpkey.size(), 0)
                            == 1))
            {
                if (options.op == OP_GET)
                {
                    RedisReply& r = ctx.reply.AddMember();
                    fill_str_reply(r, tmpkey);
                }
                else
                {
                    count++;
                }
            }
            else
            {
                /*
                 * If the '*' is the last char, we can break iteration now
                 */
                if (cursor == options.pattern.size() - 1)
                {
                    break;
                }
            }
            iter->Next();
        }
        DELETE(iter);
        if (options.op == OP_GET)
        {
            ctx.reply.type = REDIS_REPLY_ARRAY;
        }
        else
        {
            fill_int_reply(ctx.reply, count);
        }
        return 0;
    }
Beispiel #10
0
    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;
    }