Пример #1
0
HASH_INT hash_tands(HASH_INT triad, hash_table_t *theTable)
{
   hash_cell_t *theElement= theTable->table+hash_hash(triad,theTable);
   int isScratch;
   if(theElement->triad == 0)/*No such a triad -- install it and return:*/
      return theElement->triad=triad;
   if(theElement->next == 0){
      if( hash_cmp(triad, theElement->triad, theTable) )
         return theElement->triad;
      isScratch=0;/*theElement points somewhere into the table*/
   }else{
#ifdef DEBUG
      HASH_INT maxCNew=0;
#endif
      isScratch=1;/*theElement points somewhere into the scratch*/
      for(;;){
         if( hash_cmp(triad, theElement->triad, theTable) )
            return theElement->triad;
         if(theElement->next == 0)
            break;
         theElement= theTable->scratch+theElement->next;
#ifdef DEBUG
         maxCNew++;
#endif
      }/*for(;;)*/
#ifdef DEBUG
      nC++;
      avC+=maxCNew;
      if(maxCNew>maxC)
         maxC=maxCNew;
#endif
   }/*else*/
   /*Install a new element in scratch:*/
   if(theTable->free == theTable->max){/*(re)allocate the scratch array:*/
      if(theTable->max == 0)
         hash_alloc(theTable);
      else{
         if(isScratch){/*theElement points somewhere into the scratch*/
            /*Store the position:*/
            HASH_INT n=theElement-theTable->scratch;
               hash_realloc(theTable);
               /*The scratch was changed, restore the position:*/
               theElement=theTable->scratch+n;
         }else/*theElement has no relation to the scratch, just realloc the scratch:*/
            hash_realloc(theTable);
      }/*else*/
   }/*if(theTable->free == theTable->max)*/
   /*Install the triad and return:*/
   theTable->scratch[theTable->free].triad=triad;
   theElement->next=theTable->free;
   theTable->scratch[theTable->free].next=0;
   theTable->free++;
   return triad;
}/*hash_tands*/
Пример #2
0
int hash_put( hash_table_t *h,
              const void *key,
              const void *data )
{
    int pos;

    if( (float)(h->count+1)/h->size > 0.75f )
    {
        if( !hash_realloc( h, (h->size+1) * 2 -1 ) )
        {
            return 0;
        }
    }

    pos = hash_search( h, (void *)key );

    if( h->arr[pos].key == 0 )
    {
        h->count++;
    }

    h->arr[pos].key = (void *)key;
    h->arr[pos].data = (void *)data;
    return 1;
}
Пример #3
0
/**
 * Add a new frame to the current thread.  Resize the stack structure
 * if necessary.
 */
static void frame_grow_num_frames() {
    current_thread->num_frames++;

    if (current_thread->num_frames >= current_thread->size_frames) {
	size_t newsize;

	current_thread->size_frames += 10;
	newsize = sizeof(thread_info)
	    + current_thread->size_frames * sizeof(frame_info);
	current_thread = hash_realloc(&threads, 0, newsize);
    }
}
Пример #4
0
/*
 * Returns:
 *	 0 ==> OK
 *	-1 ==> Error
 */
extern int
__expand_table(HTAB *hashp)
{
	uint32 old_bucket, new_bucket;
	int new_segnum, spare_ndx;
	size_t dirsize;

#ifdef HASH_STATISTICS
	hash_expansions++;
#endif
	new_bucket = ++hashp->MAX_BUCKET;
	old_bucket = (hashp->MAX_BUCKET & hashp->LOW_MASK);

	new_segnum = new_bucket >> hashp->SSHIFT;

	/* Check if we need a new segment */
	if (new_segnum >= hashp->nsegs) {
		/* Check if we need to expand directory */
		if (new_segnum >= hashp->DSIZE) {
			/* Reallocate directory */
			dirsize = hashp->DSIZE * sizeof(SEGMENT *);
			if (!hash_realloc(&hashp->dir, dirsize, dirsize << 1))
				return (-1);
			hashp->DSIZE = dirsize << 1;
		}
		if ((hashp->dir[new_segnum] =
		    (SEGMENT)calloc((size_t)hashp->SGSIZE, sizeof(SEGMENT))) == NULL)
			return (-1);
		hashp->exsegs++;
		hashp->nsegs++;
	}
	/*
	 * If the split point is increasing (MAX_BUCKET's log base 2
	 * * increases), we need to copy the current contents of the spare
	 * split bucket to the next bucket.
	 */
	spare_ndx = __log2((uint32)(hashp->MAX_BUCKET + 1));
	if (spare_ndx > hashp->OVFL_POINT) {
		hashp->SPARES[spare_ndx] = hashp->SPARES[hashp->OVFL_POINT];
		hashp->OVFL_POINT = spare_ndx;
	}

	if (new_bucket > (uint32)hashp->HIGH_MASK) {
		/* Starting a new doubling */
		hashp->LOW_MASK = hashp->HIGH_MASK;
		hashp->HIGH_MASK = new_bucket | hashp->LOW_MASK;
	}
	/* Relocate records to the new bucket */
	return (__split_page(hashp, old_bucket, new_bucket));
}
Пример #5
0
void hash_remove( hash_table_t *h,
                  const void *key,
                  void **old_key,
                  void **old_val )
{
    if( !h->count )
    {

        if( old_key != 0 )
            *old_key = 0;
        if( old_val != 0 )
            *old_val = 0;
        return;
    }

    int pos = hash_search( h, (void *)key );
    int next_pos;

    if( h->arr[pos].key == 0 )
    {

        if( old_key != 0 )
            *old_key = 0;
        if( old_val != 0 )
            *old_val = 0;
        return;
    }

    h->count--;

    if( old_key != 0 )
        *old_key = h->arr[pos].key;
    if( old_val != 0 )
        *old_val = h->arr[pos].data;

    h->arr[pos].key = 0;

    next_pos = pos+1;
    next_pos %= h->size;

    while( h->arr[next_pos].key != 0 )
    {

        int hv = h->hash_func( h->arr[next_pos].key );
        int ideal_pos = ( hv  & 0x7fffffff) % h->size;
        int dist_old = (next_pos - ideal_pos + h->size)%h->size;
        int dist_new = (pos - ideal_pos + h->size)%h->size;
        if ( dist_new < dist_old )
        {
            h->arr[pos].key = h->arr[next_pos].key;
            h->arr[pos].data = h->arr[next_pos].data;
            h->arr[next_pos].key = 0;
            pos = next_pos;
        }
        next_pos++;

        next_pos %= h->size;

    }

    if( (float)(h->count+1)/h->size < 0.2f && h->count < 63 )
    {
        hash_realloc( h, (h->size+1) / 2 -1 );
    }

    return;
}