示例#1
0
static MprSymbol *lookupInner(int *bucketIndex, MprSymbol **prevSp,
                              MprSymbolTable *table, const char *key)
{
    MprSymbol	*sp, *prev;
    int			index, rc;

    mprAssert(key);

    index = hashIndex(key, table->hashSize);
    if (bucketIndex) {
        *bucketIndex = index;
    }

    sp = table->buckets[index];
    prev = 0;

    while (sp) {
        rc = strcmp(sp->key, key);
        if (rc == 0) {
            if (prevSp) {
                *prevSp = prev;
            }
            return sp;
        }
        prev = sp;
        mprAssert(sp != sp->next);
        sp = sp->next;
    }
    return 0;
}
示例#2
0
entry *findName(char lastname[], entry *pHead)
{
    unsigned int idx = hashIndex(lastname);
    pHead = hash_p[idx];

    while (pHead != NULL) {
        if (strcasecmp(lastname, pHead->lastName) == 0)
            return pHead;
        pHead = pHead->pNext;
    }
    return NULL;
}
示例#3
0
int symDelete(sym_fd_t sd, char_t *name)
{
	sym_tabent_t	*tp;
	sym_t			*sp, *last;
	char_t			*cp;
	int				hindex;

	a_assert(name && *name);
	a_assert(0 <= sd && sd < symMax);
	tp = sym[sd];
	a_assert(tp);

/*
 *	Calculate the first daisy-chain from the hash table. If non-zero, then
 *	we have daisy-chain, so scan it and look for the symbol.
 */
	last = NULL;
	hindex = hashIndex(tp, name);
	if ((sp = tp->hash_table[hindex]) != NULL) {
		for ( ; sp; sp = sp->forw) {
			cp = sp->name.value.string;
			if (cp[0] == name[0] && gstrcmp(cp, name) == 0) {
				break;
			}
			last = sp;
		}
	}
	if (sp == (sym_t*) NULL) {				/* Not Found */
		return -1;
	}

/*
 *	Unlink and free the symbol. Last will be set if the element to be deleted
 *	is not first in the chain.
 */
	if (last) {
		last->forw = sp->forw;
	} else {
		tp->hash_table[hindex] = sp->forw;
	}
	valueFree(&sp->name);
	valueFree(&sp->content);
	bfree(B_L, (void*) sp);

	return 0;
}
示例#4
0
int findElementHash(Key *key, Hash *hash)
{
  int index;
  Node *h;

  index = hashIndex(key, hash->size);

  h = hash->table[index];

  while( h!=NULL && !equalKey(&h->key,key) )
    h = h->next;

  if( h==NULL )
    return 0;

  return h->count;
}
示例#5
0
int setElementHash(Key *key, Hash *hash, int count)
{
  int index;
  Node *h,*p=NULL;

  index = hashIndex(key, hash->size);

  if( hash->table[index]==NULL )
    {
      if( (h = (Node*) mymalloc(sizeof(Node)))==NULL )
	{ fprintf(stderr, "Cannot allocate memory for new entry in hash table"); exit(2); }

      hash->table[index] = h;
      hash->total++;
      keyCopy(&(h->key),key);
      h->count = count;
      h->next = NULL;
      return count;
    }    

  h = hash->table[index];
  //assert(h);
  while( h!=NULL && !equalKey(&h->key, key))
    {
      p = h;
      h = h->next;
    }
  if(h == NULL)
    {
      if( (h = (Node*) mymalloc(sizeof(Node)))==NULL )
	{ fprintf(stderr, "Cannot allocate memory for new entry in hash table"); exit(2); }
      hash->total++;
      //assert(p);
      p->next = h;
      keyCopy(&(h->key),key);
      h->count = count;
      h->next = NULL;
      return count;
    }

  h->count = count;
  return h->count;
}
示例#6
0
entry *append(char lastName[], entry *not_used)
{
    unsigned int idx;
    entry *e = NULL;
    entry **head = NULL;

    // calc hash index
    idx = hashIndex(lastName);
    head = &hash_p[idx];
    // link on the head on hash_p[index]
    e = (entry *) malloc(sizeof(entry));
    strcpy(e->lastName, lastName);
    if (*head == 0) {
        e->pNext = NULL;
    } else {
        e->pNext = *head;
    }
    *head = e;

    return e;
}
示例#7
0
const Status Index::startScan(const void* scanValue)
{
  int hashvalue;

  curValue = scanValue;

  // read in and pin down the bucket containing entries with 'value'
  // in the buffer pool
  Status status = hashIndex(curValue, hashvalue);
  if (status != OK) 
    return status;

  int pageNo = curPageNo = headerPage->dir[hashvalue];
  status = bufMgr->readPage(file, pageNo, 
			    (Page*&)curBuc);
  if (status != OK) 
    return status;

  curOffset = 0;
  
  return OK;
}
示例#8
0
const Status Index::deleteEntry(const void* value, const RID & rid) 
{
  Status status;
  int index;
  Bucket* bucket;

  status = hashIndex(value, index);

  // read in the bucket that might have the entry in it
  int pageNo = headerPage->dir[index];
  status = bufMgr->readPage(file, pageNo, (Page*&)bucket);
  if (status != OK) 
    return status;

  // scan the bucket for the entry. Delete it if found
  for(int i = 0; i < bucket->slotCnt; i++) {
    status = matchRec(bucket, value, i);
    if (status == OK) {
      if (!memcmp(&rid, &(bucket->data[i*recSize + headerPage->length]), 
		 sizeof(RID))) {

	// the entry is found. Decrease the entry counts in the bucket
	// and copy the last entry in the bucket to the slot occupied
	// by the deleted entry

	(bucket->slotCnt)--;
	memcpy(&(bucket->data[i*recSize]), 
	       &(bucket->data[recSize*(bucket->slotCnt)]),recSize);
	status = bufMgr->unPinPage(file, pageNo, true);
	return status;
      }
    }
  }

  status = bufMgr->unPinPage(file, pageNo, false);
  if (status != OK)
    return status;
  return RECNOTFOUND;
}
示例#9
0
static sym_t *hash(sym_tabent_t *tp, char_t *name)
{
	a_assert(tp);

	return tp->hash_table[hashIndex(tp, name)];
}
示例#10
0
sym_t *symEnter(sym_fd_t sd, char_t *name, value_t v, int arg)
{
	sym_tabent_t	*tp;
	sym_t			*sp, *last;
	char_t			*cp;
	int				hindex;

	a_assert(name);
	a_assert(0 <= sd && sd < symMax);
	tp = sym[sd];
	a_assert(tp);

/*
 *	Calculate the first daisy-chain from the hash table. If non-zero, then
 *	we have daisy-chain, so scan it and look for the symbol.
 */
	last = NULL;
	hindex = hashIndex(tp, name);
	if ((sp = tp->hash_table[hindex]) != NULL) {
		for (; sp; sp = sp->forw) {
			cp = sp->name.value.string;
			if (cp[0] == name[0] && gstrcmp(cp, name) == 0) {
				break;
			}
			last = sp;
		}
		if (sp) {
/*
 *			Found, so update the value
 *			If the caller stores handles which require freeing, they
 *			will be lost here. It is the callers responsibility to free
 *			resources before overwriting existing contents. We will here
 *			free allocated strings which occur due to value_instring().
 *			We should consider providing the cleanup function on the open rather
 *			than the close and then we could call it here and solve the problem.
 */
			if (sp->content.valid) {
				valueFree(&sp->content);
			}
			sp->content = v;
			sp->arg = arg;
			return sp;
		}
/*
 *		Not found so allocate and append to the daisy-chain
 */
		sp = (sym_t*) balloc(B_L, sizeof(sym_t));
		if (sp == NULL) {
			return NULL;
		}
		sp->name = valueString(name, VALUE_ALLOCATE);
		sp->content = v;
		sp->forw = (sym_t*) NULL;
		sp->arg = arg;
		last->forw = sp;

	} else {
/*
 *		Daisy chain is empty so we need to start the chain
 */
		sp = (sym_t*) balloc(B_L, sizeof(sym_t));
		if (sp == NULL) {
			return NULL;
		}
		tp->hash_table[hindex] = sp;
		tp->hash_table[hashIndex(tp, name)] = sp;

		sp->forw = (sym_t*) NULL;
		sp->content = v;
		sp->arg = arg;
		sp->name = valueString(name, VALUE_ALLOCATE);
	}
	return sp;
}
示例#11
0
const Status Index::insertEntry(const void *value, RID rid) 
{ 
  Bucket* bucket;
  Status status;
  Bucket *newBucket;
  int newPageNo;       
  char  data[PAGESIZE*2];
  int counter;
  int index;

  // If the 'unique' flag is set, scan the index to see if the
  // <attribute, rid> pair already exists

  if (headerPage->unique == UNIQUE) {
    RID outRid;

    if((status = startScan(value)) != OK)
      return status;
    while ((status = scanNext(outRid)) != NOMORERECS) {
      if (status != OK)
	return status;    
      if (!memcmp(&outRid, &rid, sizeof(RID)))
	return NONUNIQUEENTRY;
    }
    if((status = endScan()) != OK)
      return status;
  }
 
  // Get the bucket containing the entry into buffer pool
  status = hashIndex(value, index);
  int pageNo = headerPage->dir[index];

#ifdef DEBUGIND
  cout << "Inserting entry " << *(int*)value << " to bucket " 
    << pageNo << endl;
#endif 
 
  status = bufMgr->readPage(file, pageNo, (Page*&)bucket);
  if (status != OK) 
    return status;

  // the bucket needs to be splitted if the number of entries
  // on the bucket equals the maximum
  if (bucket->slotCnt == numSlots) { // splitting bucket
    
    // allocate a new bucket
    status = bufMgr->allocPage(file, newPageNo, (Page*&)newBucket);  
    if (status != OK)
      return status;

    // Initialize this newly allocated bucket
    newBucket->depth = ++(bucket->depth);
    newBucket->slotCnt = 0;

    // Copy all (value, rid) pairs in the old bucket and the new
    // entry to a temporary area
    memcpy(data, bucket->data, numSlots*recSize);
    memcpy(&(data[numSlots*recSize]), value, headerPage->length);
    memcpy(&(data[numSlots*recSize + headerPage->length]), &rid, sizeof(RID));

    counter = bucket->slotCnt + 1;
    bucket->slotCnt = 0;

    // the directory needs to be doubled if the depth of the bucket
    // being splitted equals the depth of the directory

    if (bucket->depth > headerPage->depth) { // doubling directory

      // The directory is doubled and the lower half of the directory
      // is copied to the upper half

      int newDirSize = 2 * dirSize;
      if (newDirSize > DIRSIZE)
	return DIROVERFLOW;
      for (int i = 0; i < dirSize; i++)
	headerPage->dir[i + dirSize] = headerPage->dir[i];

      dirSize = newDirSize;
      (headerPage->depth)++;
      headerPage->dir[index + (1 << (bucket->depth - 1))] = newPageNo;

    } else {

      // reset the appropriate directories to the new bucket
      int oldindex = index % (1 << (bucket->depth - 1));
      int newindex = oldindex + (1 << (bucket->depth - 1));
      for (int j = 0; j < dirSize; j++) 
	if ((j % (1 << (bucket->depth))) == newindex)
	  headerPage->dir[j] = newPageNo;
    }

#ifdef DEBUGIND
      printDir();
#endif 

    // call insertEntry recursively to insert all (value, rid) 
    // pairs in the temporary area to the index

    for (int k = 0; k < counter; k++) {
      value = &(data[k * recSize]);
      rid = * ((RID *)((char *)value + headerPage->length));
      status = insertEntry(value, rid);
      if (status != OK)
	return status;
    }
    status = bufMgr->unPinPage(file, newPageNo, true);
    if (status != OK)
      return status;

    } else { 
    // There is sufficient free space in the bucket. Insert (value, rid) here

    int offset = (bucket->slotCnt) * recSize;
    memcpy(&(bucket->data[offset]), value, headerPage->length);
    memcpy(&(bucket->data[offset+headerPage->length]), &rid, sizeof(RID));
    (bucket->slotCnt)++;
  }

  status = bufMgr->unPinPage(file, pageNo, true);
  return status;
}