コード例 #1
0
 private DataKey* LookupKey(DataKey* rqs, bool deleteKey = false)
 {
     var level = 0;
     var he = _htable + (rqs->hash & _hashMask);
     do
     {
         if (he->IsList)
         {
             DataKey* cp = he->List, nx;
             for (DataKey* wx = null; cp != null; wx = cp, cp = nx)
             {
                 nx = cp->next;
                 // check eviction opportunities.
                 if (IsExpired(cp))
                 {
                     var expired = DataKey.Equal(cp, rqs);
                     he->Pop(wx);
                     DeleteKey(cp);
                     if (expired) break;
                     cp = wx;
                     continue;
                 }
                 // check if we have a clean match.
                 if (DataKey.Equal(cp, rqs))
                 {
                     if (!deleteKey)
                         return LruUpdate(cp);
                     he->Pop(wx);
                     DeleteKey(cp);
                     return null;
                 }
             }
         }
         else
         {
             var htp = _hashBits + iHSubBits * level++;
             htp = (int)(rqs->hash >> htp) & iHSubMask;
             he = he->Htab + htp;
             continue;
         }
         // if command can append to cache, request entry will be consumed.
         if (!ReqsAdds.Has(rqs->opcode) || deleteKey)
             return null;
         Stats.CurrentItems++;
         // create new data key for the request.
         var nk = GetDk(rqs->KeySize);
         _copy_with_key(nk, rqs);
         // add new key to the head of LRU list.
         var head = _lruHead;
         nk->lrup = null;
         if (head != null) { nk->lrux = head; head->lrup = nk; }
         else _lruTail = nk;
         var hmax = he->Push(_lruHead = nk);
         if (hmax > 8 && hmax > 8 + level * 2 && level < 3)
             he->Split(GetBucket(), _hashBits + level * iHSubBits, iHSubMask);
         return nk;
     } while (true);
 }
コード例 #2
0
 private DataKey* LruUpdate(DataKey* cp)
 {
     if (_lruHead != cp)
     {
         DataKey* prev = cp->lrup, lx = cp->lrux;
         prev->lrux = lx;
         if (lx != null) lx->lrup = prev;
         else _lruTail = prev;
         cp->lrup = null; cp->lrux = _lruHead;
         _lruHead->lrup = cp;
         _lruHead = cp;
     }
     return cp;
 }
コード例 #3
0
 private byte* ParsePacket(byte* cp, byte* ep)
 {
     var left = (int)(ep - cp);
     if (left < SizeofPacket)
         return SaveIntoSplit(cp, left);
     var cr = (Packet*)cp;
     if (cr->magic != 0x80)
         throw new SerializationException("magic byte");
     if (_ce == null)
     {
         // create new datakey and add it to the list.
         _ce = GetDk(cr);
         if (_clist == null) _clist = _ce;
         else _clast->next = _ce;
         _clast = _ce;
     }
     int xsz = cr->extlen, xks = xsz + _ce->KeySize;
     // buffer may split on extras or key part.
     if (xks > left - SizeofPacket)
         return SaveIntoSplit(cp, left);
     // copy key and extras bytes into place.
     cp += sizeof(Packet);
     _set_key(_ce, cp + xsz);
     if (xsz > 0) _ce->SetExtras(cp, xsz);
     return cp + xks;
 }
コード例 #4
0
 private void DeleteKey(DataKey* dk)
 {
     // remove entry from LRU list.
     DataKey* prev = dk->lrup, next = dk->lrux;
     if (next == null)
         if ((_lruTail = prev) != null)
             prev->lrux = null;
         else _lruHead = null;
     else
     {
         next->lrup = prev;
         if (prev != null) prev->lrux = next;
         else _lruHead = next;
     }
     // free key-mem and release val-mem.
     FreeDk(dk);
 }
コード例 #5
0
            public override int ParseExecuteRequest()
            {
                if (_stackSize > 512 * 1024)
                    throw new InvalidOperationException("request-too-big");

                // allocate space on stack for request headers and keys.
                _clist = _clast = _ce = null;
                byte* sp = stackalloc byte[_stackSize + iDataKeyLimit];
                _split = _ep = sp + _stackSize;
                _cp = sp;
                
                // parse storage data into request entries.
                var bytesIn = _data.ContentSize;
                ParseRequests(_data);
                if (_ce != null)
                    throw new SerializationException("corrupt memcached byte stream");
                
                // run requests through cache instance, copy results into storage and release values.
                try
                {
                    _cache.ExecuteBatch(_clist, bytesIn);
                    OutputResponse(_data.Reset());
                }
                finally
                {
                    _cache.ReleaseValues(_clist, (uint)_data.ContentSize);
                    _stackSize = 0;
                }
                return 0;
            }