public void Set(RefCountPtr* ls, int cnt)
 {
     next = ls; 
     count = cnt;
 }
 public void SetValue(DataKey* src)
 {
     size = src->size;
     var rc = src->val_addr;
     val_addr = rc;
     if (rc != null) rc->AddRef();
 }
 public RefCountPtr* Pop()
 {
     var rc = next;
     if (rc != null)
     {
         next = rc->_list;
         rc->_data = 0;
         count--;
     }
     return rc;
 }
 public void Push(RefCountPtr* bp)
 {
     bp->_list = next;
     next = bp;
     count++;
 }
 private void ResetSlabs()
 {
     _cbuckets = 0;
     // hash bucket extra mem pages are returned to system on reset.
     if (_lpHash != null)
     {
         for (var ls = _lpHash; ls != null; ls = ls.next)
             ls.Release();
         _lpHash = null;
     }
     if (_lpBase == null)
         _lpBase = new LargePage(_virtual_memory, 4);
     _htable = (HashBucket*)_lpBase.data;
     // init shared tables with clean values.
     for (var i = 0; i < _config.HashTableSize; i++)
         _htable[i] = new HashBucket();
     var bp = (byte*)(_htable + _config.HashTableSize);
     _stabs = (int*)bp;
     // encoding slab max size and pos like -> 32 : 0
     _stabs[0] = 0x200000; _stabs[1] = 0x400001;
     _slabs = (SlabList*)_align((byte*)(_stabs + 1 + (iLastSlabSize + SizeofRcp) / iQuantum));
     // calculate slabs indexes and max sizes.
     int sbts = 64, scnt = 2, pos = scnt;
     for (var half = sbts / 2; sbts < iLastSlabSize; half = sbts / 2)
     {
         for (var es = sbts + half; sbts < es; sbts += iQuantum) _stabs[pos++] = scnt | (es << 16);
         scnt++;
         for (var es = sbts + half; sbts < es; sbts += iQuantum) _stabs[pos++] = scnt | (es << 16);
         scnt++;
     }
     _stabs[pos] = scnt;
     bp = _align((byte*)(_slabs + scnt + 1));
     // pre-allocate ~32k into every slab slot.
     var quot = sbts / 4;
     while (scnt-- > 0)
     {
         RefCountPtr* ls = null;
         var count = 0;
         for (var todo = 32768; todo > 0; count++, todo -= sbts, bp += sbts)
         {
             var rc = (RefCountPtr*)bp;
             rc->_list = ls; ls = rc;
         }
         _slabs[scnt].Set(ls, count);
         sbts -= quot;
         if ((scnt & 1) != 0) quot = sbts / 4;
     }
     // pre-allocate 256k into hash table buckets;
     _hb_cp = (HashBucket*)bp;
     _hb_ep = (HashBucket*)(bp += 256 * 1024);
     // pre-allocate ~1mb into big-mem chunks.
     _sbigs = null; _cntBigs = 0; sbts = iBigBlockSize + SizeofRcp;
     for (int left = 1024 * (1024 + 16); left > 0; _cntBigs++, left -= sbts, bp += sbts)
     {
         var rc = (RefCountPtr*)bp;
         rc->_list = _sbigs; _sbigs = rc;
     }
     // pre-allocate large memory pages for cache purposes.
     if (!_config.ReserveMemory)
         _cntPages = 1 + (int)((Stats.MemoryLimit - 1) / _config.AllocPageSize);
     if (_lpList != null)
         if (_config.ReserveMemory) { }
         else
         {
             for (var ls = _lpList; ls != null; ls = ls.next)
                 ls.Release();
             _lpList = null;
         }
     else if (_config.ReserveMemory)
         for (var bytes = Stats.MemoryLimit; bytes > 0; bytes -= _lpList.size)
             _lpList = new LargePage(_virtual_memory, _config.AllocPageSize) { next = _lpList };
     _lpNext = _lpList;
     _cp = bp; _ep = _lpBase.data + _lpBase.size;
 }
 private void FreeMem(RefCountPtr* bp, int size)
 {
     if (size <= iLastSlabSize)
         _slabs[_slab_id(size + SizeofRcp)].Push(bp);
     else
     {
         var ls = bp->Next;
         bp->_list = _sbigs; _sbigs = bp; _cntBigs++;
         if (ls == null) return;
         for (_cntBigs++, bp = ls; bp->_list != null; bp = bp->_list) _cntBigs++;
         bp->_list = _sbigs; _sbigs = ls;
     }
 }
 private RefCountPtr* GetBig(int size = iBigBlockSize)
 {
     RefCountPtr* db = _sbigs, cp = db;
     for (; cp != null; _cntBigs--, cp = cp->_list)
         if ((size -= iBigBlockSize) <= 0)
         {
             _sbigs = cp->_list;
             cp->_list = null;
             _cntBigs--;
             return db;
         }
     Debug.Assert(_cntBigs == 0, "big-mem");
     _sbigs = null;
     do
     {
         var np = GetNewMem(iBigBlockSize + SizeofRcp);
         np->_list = db; db = np;
     } while ((size -= iBigBlockSize) > 0);
     return db;
 }