Exemple #1
0
bool Level::refreshBackgroundMusic(vector playerPos)
{
    if(bgmusicActivated)
    {
        if(actualBackgroundMusic != NULL && vectorInCube(playerPos, actualBackgroundMusic->location))
            return false;

        if(backgroundMusics->IsEmpty())
            return false;

        ListIterator<locationMusic> i = ListIterator<locationMusic>(backgroundMusics);
        i.SetFirst();

        do
        {
            if(vectorInCube(playerPos, i.GetCurrent()->location))
            {
                actualBackgroundMusic = i.GetCurrent();
                bgmusic->selectMusic(actualBackgroundMusic->musicname, -1);
                bgmusic->toggle();
                return true;
            }

            i.Next();
        }while(!i.IsLast());

        if(actualBackgroundMusic != NULL)
                bgmusic->toggle();

        actualBackgroundMusic = NULL;
    }

    return false;
}
Exemple #2
0
/**
* @date     2011/12/21
*
*  Handler of a request. The WebService request si built from the request, and
*  forwarded to the correct WsInterface.
*
******************************************************************************/
int32_t  WsHandler::RequestReceived(const HttpdRequest &Request,
                                    HttpdRequest *Answer)
{
   int32_t i_Ret = -1;
   ListIterator<AList<WsInterface*>, WsInterface*>  Iterator;
   WsInterface    *p_Interface = NULL;
   const String   *RequestInterface;

   if(HandleCors(Request, Answer) == 0)
      return(0);

   DynObject   Params;
   const uint8_t *Payload;
   uint32_t i_Length;
   i_Ret = Request.GetPayload(&Payload, &i_Length);
   if(i_Ret == 0)
   {
      JsonFlattener Flattener;
      const String PayloadString((const char*)(Payload), i_Length);

      i_Ret = Flattener.UnFlatten(&PayloadString, &Params);
      if(i_Ret == 0)
      {
         i_Ret = Params.FindString("InterfaceName", &RequestInterface);
      }
   }
   if(i_Ret != 0)
      return(-1);

   Iterator.SetTo(&InterfaceList);
   Iterator.First();
   while(Iterator.IsDone() == false)
   {
      if( (Iterator.GetItem(&p_Interface) == 0) && (p_Interface != NULL) )
      {
         if(p_Interface->GetName() == *RequestInterface)
         {
            String   AnswerString;
            i_Ret = p_Interface->Call(Params, &AnswerString);
            if(i_Ret == 0)
            {
               i_Ret = Answer->SetPayload((const uint8_t*)AnswerString.GetString(),
                                          AnswerString.GetSize());
            }
            break;
         }
      }
      Iterator.Next();
   }

   return(i_Ret);
}
Exemple #3
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;
 }
void main() {
    Recipe myRecipe1 =  Recipe("Fish Filets in Hot Chili Oil");
    Recipe myRecipe2 =  Recipe("Boiled Fish with Pickled Cabbage and Chili ");
    Recipe myRecipe3 =  Recipe("Coke Chicken");
    Recipe myRecipe4 =  Recipe("Fish ball soup");
    List<Recipe>* myRecipeList = new List<Recipe>();
    myRecipeList->Append(myRecipe1);
    myRecipeList->Append(myRecipe2);
    myRecipeList->Append(myRecipe3);
    myRecipeList->Append(myRecipe4);
    ListIterator<Recipe> myIterator = ListIterator<Recipe>(myRecipeList);
    for(myIterator.First(); !myIterator.IsDone(); myIterator.Next()) {
        myIterator.CurrentItem().Print();
    }
    while(1) {
        ;
    }
}
Exemple #5
0
ObjectType *ObjectTypeCache::searchObjectType(const char *objtypename)
{
    ObjectType *result = NULL;

    ListIterator<ObjectType> i = ListIterator<ObjectType>(cachedObjectTypes);
    i.SetFirst();

    while(!(i.IsLast()))
    {
        result = i.GetCurrent();

        if(!strncmp(result->objectTypeName, objtypename, MAX_STRING_LENGTH))
            break;
        else
            result = NULL;

        i.Next();
    }

    return result;
}
Exemple #6
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;
 }
Exemple #7
0
bool ObjectTypeCache::unloadObjectType(const char *objtypename)
{
    ObjectType *objTypeToDelete = NULL;

    ListIterator<ObjectType> i = ListIterator<ObjectType>(cachedObjectTypes);
    i.SetFirst();

    while(!(i.IsLast()))
    {
        objTypeToDelete = i.GetCurrent();

        if(!strncmp(objTypeToDelete->objectTypeName, objtypename, MAX_STRING_LENGTH))
        {
            i.Remove();
            return true;
        }

        i.Next();
    }

    return false;
}
Exemple #8
0
TEST(HttpdRequestTestGroup, Basic)
{
   String   SetPath(PATH1 );
   HttpdRequest Obj1;

   /* Path */
   const String   &GetPath1 = Obj1.GetPath();
   CHECK(GetPath1 == "");
   CHECK(Obj1.SetPath(SetPath) == 0);

   const String   &GetPath2 = Obj1.GetPath();
   CHECK(GetPath2 == SetPath);

   /* Status */
   CHECK(Obj1.GetStatus() == 200);
   Obj1.SetStatus(404);
   CHECK(Obj1.GetStatus() == 404);

   /* Method */
   CHECK(Obj1.GetMethod() == HttpdRequest::NONE);
   Obj1.SetMethod(HttpdRequest::POST);
   CHECK(Obj1.GetMethod() == HttpdRequest::POST);

   /* payload */
   uint8_t SetPayload[326];
   const uint8_t *GetPayload;
   uint32_t i_Length;
   CHECK(Obj1.SetPayload(SetPayload, 326) == 0);
   CHECK(Obj1.GetPayload(&GetPayload, &i_Length) == 0);
   CHECK(i_Length == 326);
   CHECK(memcmp(GetPayload, SetPayload, i_Length) == 0);


   /* Header */
   String Header1Name(HEADER1), Header2Name(HEADER2);
   String Header1Val(HEADER1VAL), Header2Val(HEADER2VAL);
   String HeaderVal;

   CHECK(Obj1.GetHeader(Header1Name, &HeaderVal) == -1);
   CHECK(Obj1.SetHeader(Header1Name, Header1Val) == 0);
   CHECK(Obj1.GetHeader(Header1Name, &HeaderVal) == 0);
   CHECK(HeaderVal == Header1Val);

   CHECK(Obj1.SetHeader(Header2Name, Header2Val) == 0);
   CHECK(Obj1.GetHeader(Header2Name, &HeaderVal) == 0);
   CHECK(HeaderVal == Header2Val);

   CHECK(Obj1.SetHeader(Header1Name, Header2Val) == 0);
   CHECK(Obj1.GetHeader(Header1Name, &HeaderVal) == 0);
   CHECK(HeaderVal == Header2Val);

   /* Header list */
   const AList<HttpdRequest::Header*> &HeaderList = Obj1.GetHeaderList();
   ListIterator<AList<HttpdRequest::Header*>, HttpdRequest::Header*> Iterator;
   HttpdRequest::Header  *p_CurHeader;
   uint32_t i_Index = 0;

   Iterator.SetTo(&HeaderList);
   Iterator.First();
   while(Iterator.IsDone() == false)
   {
      CHECK(Iterator.GetItem(&p_CurHeader) == 0);
      CHECK(p_CurHeader != NULL);

      CHECK(i_Index <= 1);
      switch(i_Index)
      {
         case 0:
            CHECK(p_CurHeader->Name == Header1Name);
            CHECK(p_CurHeader->Value == Header2Val);
         break;
         case 1:
            CHECK(p_CurHeader->Name == Header2Name);
            CHECK(p_CurHeader->Value == Header2Val);
         break;
      }
      i_Index++;
      Iterator.Next();
   }

};
Exemple #9
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;
    }
Exemple #10
0
    int Ardb::LSet(Context& ctx, RedisCommandFrame& cmd)
    {
        int64 index;
        if (!GetInt64Value(ctx, cmd.GetArguments()[1], index))
        {
            fill_error_reply(ctx.reply, "value is not an integer or out of range");
            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_error_reply(ctx.reply, "no such key");
            return 0;
        }
        if (meta.meta.Encoding() == COLLECTION_ENCODING_ZIPLIST)
        {
            Data* entry = GetZipEntry(meta.meta.ziplist, index);
            if (NULL == entry)
            {
                fill_error_reply(ctx.reply, "index out of range");
                return 0;
            }
            else
            {
                entry->SetString(cmd.GetArguments()[2], true);
                SetKeyValue(ctx, meta);
                fill_status_reply(ctx.reply, "OK");
                return 0;
            }
        }
        else
        {
            if (index >= meta.meta.Length() || (-index) > meta.meta.Length())
            {
                fill_error_reply(ctx.reply, "index out of range");
                return 0;
            }

            if (meta.meta.IsSequentialList())
            {
                ValueObject list_element;
                list_element.key.db = meta.key.db;
                list_element.key.key = meta.key.key;
                list_element.key.type = LIST_ELEMENT;
                list_element.key.score = meta.meta.min_index;
                if (index >= 0)
                {
                    list_element.key.score.IncrBy(index);
                }
                else
                {
                    list_element.key.score.IncrBy(index + meta.meta.Length());
                }
                if (0 == GetKeyValue(ctx, list_element.key, &list_element))
                {
                    list_element.element.SetString(cmd.GetArguments()[2], true);
                    SetKeyValue(ctx, list_element);
                    fill_status_reply(ctx.reply, "OK");
                    return 0;
                }
            }
            else
            {
                ListIterator iter;
                ListIter(ctx, meta, iter, index < 0);
                int64 cursor = index >= 0 ? 0 : -1;
                while (iter.Valid())
                {
                    if (cursor == index)
                    {
                        ValueObject v;
                        v.key.db = meta.key.db;
                        v.key.key = meta.key.key;
                        v.key.type = LIST_ELEMENT;
                        v.key.score = *(iter.Score());
                        v.type = LIST_ELEMENT;
                        v.element.SetString(cmd.GetArguments()[2], true);
                        SetKeyValue(ctx, v);
                        fill_status_reply(ctx.reply, "OK");
                        return 0;
                    }
                    if (cursor >= 0)
                    {
                        cursor++;
                    }
                    else
                    {
                        cursor--;
                    }
                    if (index < 0)
                    {
                        iter.Prev();
                    }
                    else
                    {
                        iter.Next();
                    }
                }
            }
            fill_error_reply(ctx.reply, "index out of range");
        }
        return 0;
    }
Exemple #11
0
 int Ardb::LRem(Context& ctx, RedisCommandFrame& cmd)
 {
     int64 count;
     if (!GetInt64Value(ctx, cmd.GetArguments()[1], count))
     {
         return 0;
     }
     int64 toremove = std::abs(count);
     ValueObject meta;
     int err = GetMetaValue(ctx, cmd.GetArguments()[0], LIST_META, meta);
     CHECK_ARDB_RETURN_VALUE(ctx.reply, err);
     if (0 != err)
     {
         fill_int_reply(ctx.reply, 0);
         return 0;
     }
     Data element;
     element.SetString(cmd.GetArguments()[2], true);
     KeyLockerGuard lock(m_key_lock, ctx.currentDB, cmd.GetArguments()[0]);
     if (meta.meta.Encoding() == COLLECTION_ENCODING_ZIPLIST)
     {
         uint32 oldlen = meta.meta.ziplist.size();
         int64 removed = 0;
         DataArray newzip;
         if (count >= 0)
         {
             for (uint32 i = 0; i < oldlen; i++)
             {
                 if (meta.meta.ziplist[i] == element)
                 {
                     if (toremove == 0 || removed < toremove)
                     {
                         removed++;
                         continue;
                     }
                 }
                 newzip.push_back(meta.meta.ziplist[i]);
             }
         }
         else
         {
             for (uint32 i = 0; i < oldlen; i++)
             {
                 if (meta.meta.ziplist[oldlen - 1 - i] == element)
                 {
                     if (toremove == 0 || removed < toremove)
                     {
                         removed++;
                         continue;
                     }
                 }
                 newzip.push_front(meta.meta.ziplist[i]);
             }
         }
         if (removed > 0)
         {
             meta.meta.ziplist = newzip;
             SetKeyValue(ctx, meta);
         }
         fill_int_reply(ctx.reply, removed);
         return 0;
     }
     BatchWriteGuard guard(GetKeyValueEngine());
     ListIterator iter;
     ListIter(ctx, meta, iter, count < 0);
     int64 remove = 0;
     while (iter.Valid())
     {
         if (iter.Element()->Compare(element) == 0)
         {
             meta.meta.len--;
             meta.meta.SetFlag(COLLECTION_FLAG_NORMAL);
             DelRaw(ctx, iter.CurrentRawKey());
             //DelKeyValue(ctx, k);
             remove++;
             if (remove == toremove)
             {
                 break;
             }
         }
         if (count < 0)
         {
             iter.Prev();
         }
         else
         {
             iter.Next();
         }
     }
     if (remove > 0)
     {
         SetKeyValue(ctx, meta);
     }
     fill_int_reply(ctx.reply, remove);
     return 0;
 }
Exemple #12
0
 int Ardb::LIndex(Context& ctx, RedisCommandFrame& cmd)
 {
     int64 index;
     if (!GetInt64Value(ctx, cmd.GetArguments()[1], index))
     {
         return 0;
     }
     ValueObject meta;
     int err = GetMetaValue(ctx, cmd.GetArguments()[0], LIST_META, meta);
     CHECK_ARDB_RETURN_VALUE(ctx.reply, err);
     if (0 != err)
     {
         ctx.reply.type = REDIS_REPLY_NIL;
         return 0;
     }
     if (meta.meta.Encoding() == COLLECTION_ENCODING_ZIPLIST)
     {
         Data* entry = GetZipEntry(meta.meta.ziplist, index);
         if (NULL != entry)
         {
             fill_value_reply(ctx.reply, *entry);
         }
         else
         {
             ctx.reply.type = REDIS_REPLY_NIL;
         }
         return 0;
     }
     else
     {
         if ((index >= 0 && index >= meta.meta.Length()) || (index < 0 && (meta.meta.Length() + index) < 0))
         {
             ctx.reply.type = REDIS_REPLY_NIL;
             return 0;
         }
         ListIterator iter;
         if (meta.meta.IsSequentialList())
         {
             err = SequencialListIter(ctx, meta, iter, index);
             if (0 == err)
             {
                 if (iter.Valid())
                 {
                     fill_value_reply(ctx.reply, *(iter.Element()));
                     return 0;
                 }
             }
         }
         else
         {
             err = ListIter(ctx, meta, iter, index < 0);
             uint32 cursor = index < 0 ? 1 : 0;
             while (iter.Valid())
             {
                 if (cursor == std::abs(index))
                 {
                     fill_value_reply(ctx.reply, *(iter.Element()));
                     return 0;
                 }
                 cursor++;
                 if (index >= 0)
                 {
                     iter.Next();
                 }
                 else
                 {
                     iter.Prev();
                 }
             }
         }
         ctx.reply.type = REDIS_REPLY_NIL;
     }
     return 0;
 }
Exemple #13
0
    int Ardb::ListRange(Context& ctx, const Slice& key, int64 start, int64 end)
    {
        ValueObject meta;
        int err = GetMetaValue(ctx, key, LIST_META, meta);
        CHECK_ARDB_RETURN_VALUE(ctx.reply, err);
        /* convert negative indexes */
        if (start < 0)
            start = meta.meta.Length() + start;
        if (end < 0)
            end = meta.meta.Length() + end;
        if (start < 0)
            start = 0;

        /* Invariant: start >= 0, so this test will be true when end < 0.
         * The range is empty when start > end or start >= length. */
        ctx.reply.type = REDIS_REPLY_ARRAY;
        if (start > end || start >= meta.meta.Length())
        {
            return 0;
        }
        if (end >= meta.meta.Length())
            end = meta.meta.Length() - 1;
        int64 rangelen = (end - start) + 1;
        if (meta.meta.Encoding() == COLLECTION_ENCODING_ZIPLIST)
        {
            uint32 i = start;
            while (rangelen-- && i < meta.meta.ziplist.size())
            {
                RedisReply& r = ctx.reply.AddMember();
                fill_value_reply(r, meta.meta.ziplist[i++]);
            }
        }
        else
        {
            ListIterator iter;
            if (meta.meta.IsSequentialList())
            {
                SequencialListIter(ctx, meta, iter, start);
                uint32 count = 0;
                while (iter.Valid() && count < rangelen)
                {
                    RedisReply& r = ctx.reply.AddMember();
                    fill_value_reply(r, iter.Element());
                    count++;
                    iter.Next();
                }
            }
            else
            {
                if (start > meta.meta.len / 2)
                {
                    start -= meta.meta.len;
                    end -= meta.meta.len;
                }

                ListIter(ctx, meta, iter, start < 0);
                int64 cursor = start < 0 ? -1 : 0;
                while (iter.Valid())
                {
                    if (cursor >= start && cursor <= end)
                    {
                        RedisReply& r = ctx.reply.AddMember();
                        fill_value_reply(r, iter.Element());
                    }
                    if (start < 0)
                    {
                        if (cursor < start)
                        {
                            break;
                        }
                        cursor--;
                    }
                    else
                    {
                        if (cursor > end)
                        {
                            break;
                        }
                        cursor++;
                    }
                    iter.Next();
                }
            }
        }
        return 0;
    }
Exemple #14
0
    int Ardb::ListInsert(Context& ctx, ValueObject& meta, const std::string* match, const std::string& value, bool head,
            bool abort_nonexist)
    {
        if (WakeBlockList(ctx, meta.key.key, value))
        {
            fill_int_reply(ctx.reply, 1);
            return 0;
        }
        if (NULL != match)
        {
            if (meta.meta.Encoding() == COLLECTION_ENCODING_ZIPLIST)
            {
                Data element;
                element.SetString(value, true);
                DataArray::iterator zit = meta.meta.ziplist.begin();
                while (zit != meta.meta.ziplist.end())
                {
                    std::string tmp;
                    zit->GetDecodeString(tmp);
                    if (tmp == *match)
                    {
                        break;
                    }
                    zit++;
                }
                if (zit == meta.meta.ziplist.end())
                {
                    fill_int_reply(ctx.reply, 0);
                    return 0;
                }
                if (head)
                {
                    meta.meta.ziplist.insert(zit, element);
                }
                else
                {
                    zit++;
                    if (zit != meta.meta.ziplist.end())
                    {
                        meta.meta.ziplist.insert(zit, element);
                    }
                    else
                    {
                        meta.meta.ziplist.push_back(element);
                    }
                }
                if (meta.meta.Length() > 1
                        && (meta.meta.Length() >= m_cfg.list_max_ziplist_entries
                                || element.StringLength() >= m_cfg.list_max_ziplist_value))
                {
                    //convert to non ziplist
                    ZipListConvert(ctx, meta);
                }
            }
            else
            {
                ListIterator iter;
                ListIter(ctx, meta, iter, false);
                std::string tmp;
                Data prev, next;
                Data current;
                bool matched = false;
                while (iter.Valid())
                {
                    if (iter.Element()->GetDecodeString(tmp) == (*match))
                    {
                        current = *(iter.Score());
                        matched = true;
                        if (head)
                        {
                            break;
                        }
                    }
                    if (head)
                    {
                        prev = *(iter.Score());
                        iter.Next();
                    }
                    else
                    {
                        if (matched)
                        {
                            next = *(iter.Score());
                            break;
                        }
                    }
                    iter.Next();
                }
                if (!matched)
                {
                    fill_int_reply(ctx.reply, 0);
                    return 0;
                }
                Data score;
                if (head)
                {
                    if (prev.IsNil())
                    {
                        score = current.IncrBy(-1);
                    }
                    else
                    {
                        score.SetDouble((prev.NumberValue() + current.NumberValue()) / 2);
                        meta.meta.SetFlag(COLLECTION_FLAG_NORMAL);
                    }
                }
                else
                {
                    if (next.IsNil())
                    {
                        score = current.IncrBy(1);
                    }
                    else
                    {
                        score.SetDouble((next.NumberValue() + current.NumberValue()) / 2);
                        meta.meta.SetFlag(COLLECTION_FLAG_NORMAL);
                    }
                }

                meta.meta.len++;
                ValueObject v;
                v.type = LIST_ELEMENT;
                v.element.SetString(value, true);
                v.key.db = meta.key.db;
                v.key.key = meta.key.key;
                v.key.type = LIST_ELEMENT;
                v.key.score = score;
                SetKeyValue(ctx, v);
            }
            fill_int_reply(ctx.reply, meta.meta.Length());
            return 0;
        }
        else
        {
            if (meta.meta.Encoding() == COLLECTION_ENCODING_ZIPLIST)
            {
                Data element;
                element.SetString(value, true);
                if (head)
                {
                    meta.meta.ziplist.push_front(element);
                }
                else
                {
                    meta.meta.ziplist.push_back(element);
                }
                if (meta.meta.Length() >= m_cfg.list_max_ziplist_entries
                        || element.StringLength() >= m_cfg.list_max_ziplist_value)
                {
                    //convert to non ziplist
                    ZipListConvert(ctx, meta);
                }
            }
            else
            {
                meta.meta.len++;
                ValueObject v;
                v.type = LIST_ELEMENT;
                v.element.SetString(value, true);
                v.key.db = meta.key.db;
                v.key.key = meta.key.key;
                v.key.type = LIST_ELEMENT;

                if (head)
                {
                    v.key.score = meta.meta.min_index.IncrBy(-1);
                }
                else
                {
                    v.key.score = meta.meta.max_index.IncrBy(1);
                }
                SetKeyValue(ctx, v);
            }
            fill_int_reply(ctx.reply, meta.meta.Length());
            return 0;
        }
    }
Exemple #15
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;
     }
 }