Пример #1
0
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 */
}
Пример #2
0
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;
}
Пример #3
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();
	}
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
    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;
    }