static void setnodevector(ktap_State *ks, Table *t, int size) { int lsize; if (size == 0) { /* no elements to hash part? */ t->node = (Node *)dummynode; /* use common `dummynode' */ lsize = 0; } else { int i; lsize = ceillog2(size); if (lsize > MAXBITS) kp_runerror(ks, "table overflow"); size = twoto(lsize); t->node = kp_malloc(ks, size * sizeof(Node)); for (i = 0; i < size; i++) { Node *n = gnode(t, i); gnext(n) = NULL; setnilvalue(gkey(n)); setnilvalue(gval(n)); } } t->lsizenode = (u8)lsize; t->lastfree = gnode(t, size); /* all positions are free */ }
static int countint (const TValue *key, int *nums) { int k = arrayindex(key); if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */ nums[ceillog2(k)]++; /* count as such */ return 1; } else return 0; }
static void dfh_checkcons(DFibHeap * h) { IDnum oDl; /* make sure we have enough memory allocated to "reorganize" */ if (h->dfh_Dl == -1 || h->dfh_n > (1 << h->dfh_Dl)) { oDl = h->dfh_Dl; if ((h->dfh_Dl = ceillog2(h->dfh_n) + 1) < 8) h->dfh_Dl = 8; if (oDl != h->dfh_Dl) h->dfh_cons = (DFibHeapNode **) realloc(h->dfh_cons, sizeof *h-> dfh_cons * (h->dfh_Dl + 1)); if (h->dfh_cons == NULL) abort(); } }
static int checkcons(PQueue *h) { int oDl; /* make sure we have enough memory allocated to "reorganize" */ if (h->Log2N == -1 || h->count > (1 << h->Log2N)) { oDl = h->Log2N; if ((h->Log2N = ceillog2(h->count) + 1) < 8) h->Log2N = 8; if (oDl != h->Log2N) h->lognTable = (PQueueElement **)realloc(h->lognTable, sizeof *h->lognTable * (h->Log2N + 1)); if (h->lognTable == NULL) { iError.RaiseError("iPriorityQueue.Add",CONTAINER_ERROR_NOMEMORY); return CONTAINER_ERROR_NOMEMORY; } } return 1; }
static int load_table(lua_State * L, lbs_LoadState * ls) { int array_size = 0; int hash_size = 0; unsigned int total_size = 0; int result = lbsLS_readbytes(ls, (unsigned char *)&array_size, LUABINS_LINT); if (result == LUABINS_ESUCCESS) { result = lbsLS_readbytes(ls, (unsigned char *)&hash_size, LUABINS_LINT); } if (result == LUABINS_ESUCCESS) { total_size = array_size + hash_size; /* SPAM(( "LT SIZE CHECK\n" "* array_size %d limit 0 .. %d\n" "* hash_size %d limit >0\n" "* hash_size bytes %d, limit %d\n" "* unread %u limit >min_size %u (total_size %u)\n", array_size, MAXASIZE, hash_size, ceillog2((unsigned int)hash_size), MAXBITS, (unsigned int)lbsLS_unread(ls), (unsigned int)luabins_min_table_data_size(total_size), (unsigned int)total_size )); */ if ( array_size < 0 || array_size > MAXASIZE || hash_size < 0 || (hash_size > 0 && ceillog2((unsigned int)hash_size) > MAXBITS) || lbsLS_unread(ls) < luabins_min_table_data_size(total_size) ) { result = LUABINS_EBADSIZE; } } if (result == LUABINS_ESUCCESS) { unsigned int i = 0; XSPAM(( "* load: creating table a:%d + h:%d = %d\n", array_size, hash_size, total_size )); lua_createtable(L, array_size, hash_size); for (i = 0; i < total_size; ++i) { int key_type = LUA_TNONE; result = load_value(L, ls); /* Load key. */ if (result != LUABINS_ESUCCESS) { break; } /* Table key can't be nil or NaN */ key_type = lua_type(L, -1); if (key_type == LUA_TNIL) { /* Corrupt data? */ SPAM(("load: nil as key detected\n")); result = LUABINS_EBADDATA; break; } if (key_type == LUA_TNUMBER) { lua_Number key = lua_tonumber(L, -1); if (luai_numisnan(key)) { /* Corrupt data? */ SPAM(("load: NaN as key detected\n")); result = LUABINS_EBADDATA; break; } } result = load_value(L, ls); /* Load value. */ if (result != LUABINS_ESUCCESS) { break; } lua_rawset(L, -3); } } return result; }
Iterator query(Iterator range_begin, Iterator range_end) { // find superblocks fully contained within range index_t begin_idx = std::distance(_begin, range_begin); index_t end_idx = std::distance(_begin, range_end); assert(begin_idx < end_idx); assert(end_idx <= n); // round up to next superblock index_t left_sb = (begin_idx - 1) / superblock_size + 1; if (begin_idx == 0) left_sb = 0; // round down to prev superblock index_t right_sb = end_idx / superblock_size; // init result Iterator min_pos = range_begin; // if there is at least one superblock if (left_sb < right_sb) { // get largest power of two that doesn't exceed the number of // superblocks from (left,right) index_t n_sb = right_sb - left_sb; unsigned int dist = floorlog2(n_sb); assert(dist < superblock_mins.size() && left_sb < superblock_mins[dist].size()); min_pos = _begin + superblock_mins[dist][left_sb]; assert(dist < superblock_mins.size() && right_sb - (1<<dist) < superblock_mins[dist].size()); Iterator right_sb_min = _begin + superblock_mins[dist][right_sb - (1 << dist)]; if (*min_pos > *right_sb_min) { min_pos = right_sb_min; } } // go to left -> blocks -> sub-block if (left_sb <= right_sb && left_sb != 0 && begin_idx != left_sb*superblock_size) { index_t left_b = (begin_idx - 1) / block_size + 1; index_t left_b_gidx = left_b * block_size; left_b -= (left_sb - 1)*n_blocks_per_superblock; index_t n_b = n_blocks_per_superblock - left_b; if (n_b > 0) { unsigned int level = ceillog2(n_b); index_t sb_offset = (left_sb-1)*(n_blocks_per_superblock - (1<<level)/2); Iterator block_min_it = _begin + block_mins[level][left_b + sb_offset] + (left_sb-1)*superblock_size; if (*block_min_it < *min_pos) min_pos = block_min_it; } // go left into remaining block, if elements left if (left_b_gidx > begin_idx) { // linearly search (at most block_size elements) Iterator inblock_min_it = std::min_element(range_begin, _begin + left_b_gidx); if (*inblock_min_it < *min_pos) { min_pos = inblock_min_it; } } } // go to right -> blocks -> sub-block if (left_sb <= right_sb && right_sb != n_superblocks && end_idx != right_sb*superblock_size) { index_t left_b = right_sb*n_blocks_per_superblock; index_t right_b = end_idx / block_size; index_t n_b = right_b - left_b; if (n_b > 0) { unsigned int dist = floorlog2(n_b); index_t sb_offset = right_sb*((1<<dist)/2); Iterator block_min_it = _begin + block_mins[dist][left_b - sb_offset] + (right_sb)*superblock_size; if (*block_min_it < *min_pos) min_pos = block_min_it; block_min_it = _begin + block_mins[dist][right_b - sb_offset - (1<<dist)] + (right_sb)*superblock_size; if (*block_min_it < *min_pos) min_pos = block_min_it; } // go right into remaining block, if elements left index_t left_gl_idx = right_b*block_size; if (left_gl_idx < end_idx) { // linearly search (at most block_size elements) Iterator inblock_min_it = std::min_element(_begin + left_gl_idx, range_end); if (*inblock_min_it < *min_pos) { min_pos = inblock_min_it; } } } // if there are no superblocks covered (both indeces in same superblock) if (left_sb > right_sb) { index_t left_b = (begin_idx - 1) / block_size + 1; if (begin_idx == 0) left_b = 0; index_t right_b = end_idx / block_size; if (left_b < right_b) { // if blocks are in between: get mins of blocks in range // NOTE: there was a while if-else block here to handle the // case if blocks would span accross the boundary of two // superblocks, this should however never happen // git blame this line to find where this code was removed // assert blocks lie in the same superblock assert(left_b / n_blocks_per_superblock == right_b / n_blocks_per_superblock); unsigned int dist = floorlog2(right_b - left_b); index_t sb_offset = 0; index_t sb_size_offset = 0; if (left_sb > 1) { sb_offset = (left_sb-1)*((1<<dist)/2); sb_size_offset = (left_sb-1)*superblock_size; } Iterator block_min_it = _begin + block_mins[dist][left_b - sb_offset] + sb_size_offset; if (*block_min_it < *min_pos) min_pos = block_min_it; block_min_it = _begin + block_mins[dist][right_b - sb_offset - (1<<dist)] + sb_size_offset; if (*block_min_it < *min_pos) min_pos = block_min_it; // remaining inblock if (begin_idx < left_b*block_size) { Iterator inblock_min_it = std::min_element(range_begin, _begin + left_b*block_size); if (*inblock_min_it < *min_pos) { min_pos = inblock_min_it; } } if (end_idx > right_b*block_size) { Iterator inblock_min_it = std::min_element(_begin + right_b*block_size, range_end); if (*inblock_min_it < *min_pos) { min_pos = inblock_min_it; } } } else { // no blocks at all Iterator inblock_min_it = std::min_element(range_begin, range_end); if (*inblock_min_it < *min_pos) { min_pos = inblock_min_it; } } } // return the minimum found return min_pos; }