Example #1
0
File: keys.cpp Project: boreys/ardb
 int Ardb::DeleteKey(Context& ctx, const Slice& key)
 {
     ValueObject meta;
     meta.key.type = KEY_META;
     meta.key.db = ctx.currentDB;
     meta.key.key = key;
     if (0 != GetKeyValue(ctx, meta.key, &meta))
     {
         return 0;
     }
     switch (meta.type)
     {
         case SET_META:
         {
             SClear(ctx, meta);
             break;
         }
         case LIST_META:
         {
             LClear(ctx, meta);
             break;
         }
         case ZSET_META:
         {
             ZClear(ctx, meta);
             break;
         }
         case HASH_META:
         {
             HClear(ctx, meta);
             break;
         }
         case STRING_META:
         {
             DelKeyValue(ctx, meta.key);
             break;
         }
         case BITSET_META:
         {
             BitClear(ctx, meta);
             break;
         }
         default:
         {
             return 0;
         }
     }
     if (meta.meta.expireat > 0)
     {
         KeyObject expire;
         expire.type = KEY_EXPIRATION_ELEMENT;
         expire.db = ctx.currentDB;
         expire.key = key;
         expire.score.SetInt64(meta.meta.expireat);
         DelKeyValue(ctx, expire);
     }
     return 1;
 }
Example #2
0
File: t_hash.cpp Project: cvan/ardb
 int Ardb::HDel(Context& ctx, RedisCommandFrame& cmd)
 {
     ValueObject meta;
     int err = GetMetaValue(ctx, cmd.GetArguments()[0], HASH_META, meta);
     CHECK_ARDB_RETURN_VALUE(ctx.reply, err);
     int count = 0;
     if (err == 0)
     {
         BatchWriteGuard guard(GetKeyValueEngine());
         for (uint32 i = 1; i < cmd.GetArguments().size(); i++)
         {
             Data field(cmd.GetArguments()[i]);
             Data value;
             err = HashGet(ctx, meta, field, value);
             if (err == 0)
             {
                 if (meta.meta.encoding != COLLECTION_ECODING_ZIPMAP)
                 {
                     KeyObject k;
                     k.db = ctx.currentDB;
                     k.key = cmd.GetArguments()[0];
                     k.type = HASH_FIELD;
                     k.element = field;
                     DelKeyValue(ctx, k);
                     if (meta.meta.len > 0)
                     {
                         meta.meta.len--;
                     }
                 }
                 else
                 {
                     meta.meta.zipmap.erase(field);
                 }
                 count++;
             }
         }
         if (count > 0)
         {
             if (meta.meta.Length() != 0)
             {
                 SetKeyValue(ctx, meta);
             }
             else
             {
                 DelKeyValue(ctx, meta.key);
             }
         }
     }
     fill_int_reply(ctx.reply, count);
     return 0;
 }
Example #3
0
 int Ardb::LClear(Context& ctx, ValueObject& meta)
 {
     BatchWriteGuard guard(GetKeyValueEngine(), meta.meta.Encoding() != COLLECTION_ENCODING_ZIPLIST);
     if (meta.meta.Encoding() != COLLECTION_ENCODING_ZIPLIST)
     {
         ListIterator iter;
         meta.meta.len = 0;
         ListIter(ctx, meta, iter, false);
         while (iter.Valid())
         {
             KeyObject fk;
             fk.db = ctx.currentDB;
             fk.key = meta.key.key;
             fk.type = LIST_ELEMENT;
             fk.score = *(iter.Score());
             DelKeyValue(ctx, fk);
             iter.Next();
         }
     }
     DelKeyValue((ctx), meta.key);
     return 0;
 }
Example #4
0
File: t_hash.cpp Project: cvan/ardb
 int Ardb::HClear(Context& ctx, ValueObject& meta)
 {
     BatchWriteGuard guard(GetKeyValueEngine(), meta.meta.encoding != COLLECTION_ECODING_ZIPMAP);
     if (meta.meta.encoding != COLLECTION_ECODING_ZIPMAP)
     {
         HashIterator iter;
         HashIter(ctx, meta, "", iter, false);
         while (iter.Valid())
         {
             DelRaw(ctx, iter.CurrentRawKey());
             iter.Next();
         }
     }
     DelKeyValue(ctx, meta.key);
     return 0;
 }
Example #5
0
 int Ardb::RenameList(Context& ctx, DBID srcdb, const std::string& srckey, DBID dstdb, const std::string& dstkey)
 {
     Context tmpctx;
     tmpctx.currentDB = srcdb;
     ValueObject v;
     int err = GetMetaValue(tmpctx, srckey, LIST_META, v);
     CHECK_ARDB_RETURN_VALUE(ctx.reply, err);
     if (0 != err)
     {
         fill_error_reply(ctx.reply, "no such key or some error");
         return 0;
     }
     if (v.meta.Encoding() == COLLECTION_ENCODING_ZIPLIST)
     {
         DelKeyValue(tmpctx, v.key);
         v.key.encode_buf.Clear();
         v.key.db = dstdb;
         v.key.key = dstkey;
         v.meta.expireat = 0;
         SetKeyValue(ctx, v);
     }
     else
     {
         ListIterator iter;
         ListIter(ctx, v, iter, false);
         tmpctx.currentDB = dstdb;
         ValueObject dstmeta;
         dstmeta.key.type = KEY_META;
         dstmeta.key.key = dstkey;
         dstmeta.type = LIST_META;
         dstmeta.meta.SetFlag(COLLECTION_FLAG_SEQLIST);
         dstmeta.meta.SetEncoding(COLLECTION_ENCODING_ZIPLIST);
         BatchWriteGuard guard(GetKeyValueEngine());
         while (iter.Valid())
         {
             std::string tmpstr;
             ListInsert(tmpctx, dstmeta, NULL, iter.Element()->GetDecodeString(tmpstr), false, false);
             iter.Next();
         }
         SetKeyValue(tmpctx, dstmeta);
         tmpctx.currentDB = srcdb;
         DeleteKey(tmpctx, srckey);
     }
     ctx.data_change = true;
     return 0;
 }
Example #6
0
File: keys.cpp Project: boreys/ardb
    int Ardb::GenericExpire(Context& ctx, const Slice& key, uint64 ms)
    {
        if (ms > 0 && get_current_epoch_millis() >= ms)
        {
            return 0;
        }
        if (m_cfg.slave_ignore_expire && ctx.IsSlave())
        {
            /*
             * ignore expire setting, but issue data change event for replication
             */
            ctx.data_change = true;
            return 0;
        }

        ValueObject meta;
        int err = GetMetaValue(ctx, key, KEY_END, meta);
        if (0 != err)
        {
            return err;
        }
        BatchWriteGuard guard(GetKeyValueEngine());
        if (meta.meta.expireat != ms && meta.meta.expireat > 0)
        {
            KeyObject expire;
            expire.key = key;
            expire.type = KEY_EXPIRATION_ELEMENT;
            expire.db = ctx.currentDB;
            expire.score.SetInt64(meta.meta.expireat);
            DelKeyValue(ctx, expire);
        }
        meta.meta.expireat = ms;
        SetKeyValue(ctx, meta);

        if (meta.meta.expireat > 0)
        {
            ValueObject vv(KEY_EXPIRATION_ELEMENT);
            vv.key.key = key;
            vv.key.type = KEY_EXPIRATION_ELEMENT;
            vv.key.db = ctx.currentDB;
            vv.key.score.SetInt64(meta.meta.expireat);
            SetKeyValue(ctx, vv);
        }
        return 0;
    }
Example #7
0
File: t_hash.cpp Project: cvan/ardb
 int Ardb::RenameHash(Context& ctx, DBID srcdb, const std::string& srckey, DBID dstdb, const std::string& dstkey)
 {
     Context tmpctx;
     tmpctx.currentDB = srcdb;
     ValueObject v;
     int err = GetMetaValue(tmpctx, srckey, HASH_META, v);
     CHECK_ARDB_RETURN_VALUE(ctx.reply, err);
     if (0 != err)
     {
         fill_error_reply(ctx.reply, "no such key or some error");
         return 0;
     }
     if (v.meta.encoding == COLLECTION_ECODING_ZIPMAP)
     {
         DelKeyValue(tmpctx, v.key);
         v.key.encode_buf.Clear();
         v.key.db = dstdb;
         v.key.key = dstkey;
         v.meta.expireat = 0;
         SetKeyValue(ctx, v);
     }
     else
     {
         HashIterator iter;
         HashIter(ctx, v, "", iter, false);
         tmpctx.currentDB = dstdb;
         ValueObject dstmeta;
         dstmeta.key.type = KEY_META;
         dstmeta.key.key = dstkey;
         dstmeta.type = HASH_META;
         dstmeta.meta.encoding = COLLECTION_ECODING_ZIPMAP;
         BatchWriteGuard guard(GetKeyValueEngine());
         while (iter.Valid())
         {
             HashSet(tmpctx, dstmeta, *(iter.Field()), *(iter.Value()));
             iter.Next();
         }
         SetKeyValue(tmpctx, dstmeta);
         tmpctx.currentDB = srcdb;
         DeleteKey(tmpctx, srckey);
     }
     ctx.data_change = true;
     return 0;
 }
Example #8
0
    int Ardb::LTrim(Context& ctx, RedisCommandFrame& cmd)
    {
        int64 start, end;
        if (!GetInt64Value(ctx, cmd.GetArguments()[1], start) || !GetInt64Value(ctx, cmd.GetArguments()[2], end))
        {
            return 0;
        }
        ValueObject meta;
        int err = GetMetaValue(ctx, cmd.GetArguments()[0], LIST_META, meta);
        CHECK_ARDB_RETURN_VALUE(ctx.reply, err);
        if (0 != err)
        {
            fill_status_reply(ctx.reply, "OK");
            return 0;
        }
        /* convert negative indexes */
        if (start < 0)
            start = meta.meta.Length() + start;
        if (end < 0)
            end = meta.meta.Length() + end;
        if (start < 0)
            start = 0;
        if (end >= meta.meta.Length())
            end = meta.meta.Length() - 1;

        /* Invariant: start >= 0, so this test will be true when end < 0.
         * The range is empty when start > end or start >= length. */
        if (start > end || start >= meta.meta.Length())
        {
            /* Out of range start or start > end result in empty list */
            DeleteKey(ctx, cmd.GetArguments()[0]);
            return 0;
        }
        if (meta.meta.Encoding() == COLLECTION_ENCODING_ZIPLIST)
        {
            DataArray newzip;
            for (int64 i = start; i <= end; i++)
            {
                newzip.push_back(meta.meta.ziplist[i]);
            }
            meta.meta.ziplist = newzip;
            SetKeyValue(ctx, meta);
        }
        else
        {
            BatchWriteGuard guard(GetKeyValueEngine());
            if (meta.meta.IsSequentialList())
            {
                int64 listlen = meta.meta.Length();
                for (int64 s = 0; s < listlen; s++)
                {
                    if (s == start)
                    {
                        s = end;
                        continue;
                    }
                    KeyObject lk;
                    lk.db = meta.key.db;
                    lk.key = meta.key.key;
                    lk.type = LIST_ELEMENT;
                    lk.score = meta.meta.min_index.IncrBy(s);
                    meta.meta.len--;
                    DelKeyValue(ctx, lk);
                }
                meta.meta.max_index = meta.meta.min_index;
                meta.meta.min_index.IncrBy(start);
                meta.meta.max_index.IncrBy(end);
            }
            else
            {
                ListIterator iter;
                ListIter(ctx, meta, iter, false);
                int64 cursor = 0;
                while (iter.Valid())
                {
                    if (cursor < start || cursor > end)
                    {
                        DelRaw(ctx, iter.CurrentRawKey());
                        meta.meta.len--;
                    }
                    if (cursor == start)
                    {
                        meta.meta.min_index = *(iter.Element());
                    }
                    else if (cursor == end)
                    {
                        meta.meta.max_index = *(iter.Element());
                    }
                    cursor++;
                    iter.Next();
                }
            }
            SetKeyValue(ctx, meta);
        }
        return 0;
    }
Example #9
0
 int Ardb::ListPop(Context& ctx, const std::string& key, bool lpop)
 {
     ValueObject meta;
     KeyLockerGuard keylock(m_key_lock, ctx.currentDB, key);
     int err = GetMetaValue(ctx, key, LIST_META, meta);
     CHECK_ARDB_RETURN_VALUE(ctx.reply, err);
     if (0 != err)
     {
         ctx.reply.type = REDIS_REPLY_NIL;
         return 0;
     }
     BatchWriteGuard guard(GetKeyValueEngine(), meta.meta.Encoding() != COLLECTION_ENCODING_ZIPLIST);
     if (meta.meta.Encoding() == COLLECTION_ENCODING_ZIPLIST)
     {
         if (!meta.meta.ziplist.empty())
         {
             if (lpop)
             {
                 Data& data = meta.meta.ziplist.front();
                 fill_value_reply(ctx.reply, data);
                 meta.meta.ziplist.pop_front();
             }
             else
             {
                 Data& data = meta.meta.ziplist.back();
                 fill_value_reply(ctx.reply, data);
                 meta.meta.ziplist.pop_back();
             }
             if (meta.meta.ziplist.empty())
             {
                 DelKeyValue(ctx, meta.key);
             }
             else
             {
                 SetKeyValue(ctx, meta);
             }
         }
         else
         {
             ctx.reply.type = REDIS_REPLY_NIL;
         }
         return 0;
     }
     else
     {
         bool poped = false;
         if (meta.meta.IsSequentialList())
         {
             if (meta.meta.Length() > 0)
             {
                 ValueObject lkv;
                 lkv.key.type = LIST_ELEMENT;
                 lkv.key.key = meta.key.key;
                 lkv.key.db = ctx.currentDB;
                 lkv.key.score = lpop ? meta.meta.min_index : meta.meta.max_index;
                 if (0 == GetKeyValue(ctx, lkv.key, &lkv))
                 {
                     DelKeyValue(ctx, lkv.key);
                     if (lpop)
                     {
                         meta.meta.min_index.IncrBy(1);
                     }
                     else
                     {
                         meta.meta.max_index.IncrBy(-1);
                     }
                     meta.meta.len--;
                     poped = true;
                     fill_value_reply(ctx.reply, lkv.element);
                 }
             }
         }
         else
         {
             ListIterator iter;
             err = ListIter(ctx, meta, iter, !lpop);
             while (iter.Valid())
             {
                 if (!poped)
                 {
                     fill_value_reply(ctx.reply, *(iter.Element()));
                     poped = true;
                     meta.meta.len--;
                     KeyObject k;
                     k.type = LIST_ELEMENT;
                     k.key = meta.key.key;
                     k.db = ctx.currentDB;
                     k.score = *(iter.Score());
                     DelKeyValue(ctx, k);
                 }
                 else
                 {
                     if (lpop)
                     {
                         meta.meta.min_index = *(iter.Score());
                     }
                     else
                     {
                         meta.meta.max_index = *(iter.Score());
                     }
                     break;
                 }
                 if (lpop)
                 {
                     iter.Next();
                 }
                 else
                 {
                     iter.Prev();
                 }
             }
         }
         if (poped)
         {
             if (meta.meta.Length() > 0)
             {
                 SetKeyValue(ctx, meta);
             }
             else
             {
                 DelKeyValue(ctx, meta.key);
             }
         }
         else
         {
             ctx.reply.type = REDIS_REPLY_NIL;
         }
         return 0;
     }
 }