From: Alexander G. Pronchenkov Date: Tue, 26 Jan 2010 11:34:08 +0000 (+0500) Subject: Rewritten the mechanism of cells allocating. X-Git-Url: http://p2p-next.cs.pub.ro/gitweb/?a=commitdiff_plain;h=1315a8aafd1afa7592cfc671d44bb2b2f538cfd8;p=swift-upb.git Rewritten the mechanism of cells allocating. --- diff --git a/bins.cpp b/bins.cpp index 1c20dd4..80c531d 100644 --- a/bins.cpp +++ b/bins.cpp @@ -6,10 +6,17 @@ * Copyright 2009 Delft University of Technology. All rights reserved. * */ -#include "bins.h" -#include -#include + #include +#include +#include +#include +#include +#include + +#include "binmap.h" + +#undef max // make it work piece by piece @@ -21,20 +28,36 @@ const int binmap_t::NOJOIN = 0x10000; void binmap_t::extend () { - uint16_t nblocks = blocks_allocated ? (blocks_allocated<<1) : 1; - size_t had_bytes = blocks_allocated<<6; - size_t need_bytes = nblocks<<6; - cells = (uint32_t*) realloc(cells,need_bytes); - memset(((char*)cells)+had_bytes,0,need_bytes-had_bytes); - for(int b=blocks_allocated; b 1 + std::numeric_limits::max() ) + return /* The limit of cells number reached */; + + uint32_t * const ncells = (uint32_t *) realloc(cells, nblocks * 16 * sizeof(uint32_t)); + if( ncells == NULL ) + return /* Memory allocation error */; + + size_t blk = nblocks; + while( blk-- != blocks_allocated ) { + uint16_t const blk_off = 16 * blk; + uint16_t * const blk_ptr = reinterpret_cast(ncells + blk_off); + + blk_ptr[28] = free_top; + + for(uint16_t i = 13; i != (uint16_t)-1; --i) + blk_ptr[2 * i] = blk_off + i + 1; + + free_top = blk_off; + } + blocks_allocated = nblocks; + cells = ncells; } binmap_t::binmap_t() : height(4), blocks_allocated(0), cells(NULL), - ap(0), cells_allocated(0), twist_mask(0) { - extend(); - assert(!alloc_cell()); + free_top(0), cells_allocated(0), twist_mask(0) { + alloc_cell(); + assert( free_top == 1 ); } void binmap_t::twist (uint64_t mask) { @@ -43,7 +66,7 @@ void binmap_t::twist (uint64_t mask) { twist_mask = mask; } -binmap_t::binmap_t (const binmap_t& b) : height(b.height), ap(b.ap), +binmap_t::binmap_t (const binmap_t& b) : height(b.height), free_top(b.free_top), blocks_allocated(b.blocks_allocated), cells_allocated(b.cells_allocated) { size_t memsz = blocks_allocated*16*32; cells = (uint32_t*) malloc(memsz); @@ -121,33 +144,32 @@ bool binmap_t::join (uint32_t half) { } void binmap_t::free_cell (uint16_t cell) { - cells[cell] = 0; - int left = cell<<1, right=left+1; - mark(left); - unmark(right); - if (ap==cell+1) - ap--; - cells_allocated--; + --cells_allocated; + + halves[2 * cell] = free_top; + free_top = cell; } /** Get a free cell. */ uint16_t binmap_t::alloc_cell () { - uint16_t ap1 = ap; - cells_allocated++; - for(; ap<(blocks_allocated<<4); ap++) { - if ((ap&0xf)==0xf) - continue; - if (!cells[ap] && deep(ap<<1)) { - unmark(ap<<1); - return ap++; - } - } - if (ap1) - ap = 0; - else + if( cells_allocated == 15 * blocks_allocated ) extend(); - cells_allocated--; - return alloc_cell(); + + if( cells_allocated == 15 * blocks_allocated ) { + assert( free_top != 0 ); + return 0; + } + + ++cells_allocated; + + const uint16_t ref = free_top; + free_top = halves[2 * ref]; + + cells[ref] = 0; + unmark(2 * ref); + unmark(2 * ref + 1); + + return ref; } diff --git a/bins.h b/bins.h index c6a69f1..69bf6f7 100644 --- a/bins.h +++ b/bins.h @@ -108,8 +108,8 @@ private: uint32_t blocks_allocated; uint32_t cells_allocated; int height; - uint32_t ap; uint64_t twist_mask; + uint16_t free_top; void extend();