Beispiel #1
0
/*
 * --- UpdatePointer ------
 * 
 * update an internal pointer (usually because a node merged)
 */
void
indexNode::updatePointer(void *keyInModNode, bSize_t keylen, 
			 void *newSep, bSize_t sepLen) {

  TOUCH();

  //decide which pointer to modify
  int targetPointer = locateKey(keyInModNode, keylen);
  if ( (tree->comparisonFunction(keyInModNode, 
				 keylen, 
				 nth_key(targetPointer),
				 nth_keyLen(targetPointer))) )
    targetPointer--;
  

  nodeID_t *pointerCopy = new nodeID_t;
  *pointerCopy = *(nodeID_t *)nth_value(targetPointer);
  printf("MERGE insert: old sep = <%s, %ld>\n", (char *)nth_key(targetPointer), *(nodeID_t *)nth_value(targetPointer));
  if (targetPointer >= 0) {
    printf("insert: new sep = <%s, %ld>\n", (char *)newSep, *pointerCopy);
    record *newSepRec = new record(newSep, sepLen, pointerCopy, sizeof(nodeID_t));  
    remove(nth_key(targetPointer), nth_keyLen(targetPointer));
    insert(newSepRec, kNoDuplicates, wrap(&update_cb_insert));
  } //else {
    //do nothing
  //}
  return;
}
Beispiel #2
0
/*
 * printRep
 *
 * output a string describing the node
 */
void
indexNode::printRep() {

  FILE* debugFile;
  char *debugFileName = getenv("BTREE_DEBUG");
  if (debugFileName == NULL) {
    return;
  } else {
    debugFile = fopen(debugFileName, "a");
  }

  fprintf(debugFile, "i ");
  fprintf(debugFile, "%ld %d %ld ", ID, 0, header->p_zero);
  for (int i = 0; i < header->numElems; i++) {
    char key[512];
    int len = nth_keyLen(i);
    memcpy(key, (char *)nth_key(i), len);
    key[len] = 0;

    nodeID_t n = *(nodeID_t *)nth_value(i);
    fprintf(debugFile, "%s %ld ", key, n);
  }
  fprintf(debugFile, "\n");
  fflush(debugFile);
  fclose(debugFile);
}
Beispiel #3
0
/*
 * Remove -- remove an entry from this node
 *
 * 
 */
void 
indexNode::remove(void *key, bSize_t len) {

  repOK();
  TOUCH();

  //find the index of the record corresponding to key
  int i=0;
  while ( (i < header->numElems) && (tree->comparisonFunction(key, len, nth_key(i),
							      nth_keyLen(i))) ) i++;
  if (i == header->numElems) {
    warn("attempt to delete non-existent element (indexNode)");
    exit(1);
  }

  //shuffle the localPointers
  for (int j = i; j < header->numElems - 1; j++) 
    header->localPointers[j] = header->localPointers[j+1];

  header->numElems--;

  repOK();
  compact();
  return;
}
Beispiel #4
0
void
indexNode::deleteChild(nodeID_t deletedID) {
  int pos=0;

  if (p_zero == deletedID) {
    if (header->numElems == 0) p_zero = kEmptyNode;
    else {
      p_zero = *((nodeID_t *)nth_value(0));
      remove(nth_key(0), nth_keyLen(0));
    }
  } else {
    while ( (pos < header->numElems) && (*((nodeID_t *)nth_value(pos)) != deletedID) ) pos++;
    if (pos == header->numElems) warn("error on deleteChild -- key not found");
    remove(nth_key(pos), nth_keyLen(pos));
  }
  TOUCH();
  return;
}
Beispiel #5
0
/*
 * locateKey - determine where key is ordered with respect 
 *             to the node's existing keys. Function returns
 *             the existing key that immediately follows key
 */
int indexNode::locateKey(void *key, int len) {

  int i=0;
  while ((i < header->numElems) && (tree->comparisonFunction(nth_key(i), 
				  nth_keyLen(i), 
						key, 
						len) < 0)) i++;
  return i;
}
Beispiel #6
0
/*
 * Search - search called on an indexNode will return a nodeID_t. It will
 *          never return a value since store those only in the leaves
 *
 *          This version uses a binary search
 */
nodeID_t indexNode::search(void *key, bSize_t len, void **retValue, bSize_t *retLen) {
  
  /*  int l, h,m, comp;
  l=0; h = header->numElems - 1;
      
  do {
    m = (l + h) / 2;
    void *cKey = nth_key(m);
    bSize_t cLen = nth_keyLen(m);
    comp = tree->comparisonFunction(key, len, cKey, cLen);
    if (comp == 0) {
      goto end;
    } else if (comp < 0)
      if (h==m) goto end; else h = m;
    else
      l = m+1;
  } while (l <= h);
  
 end:

  
  //the search has hit one of the duplicate keys, return the associated pointer
  if (comp == 0) return *(nodeID_t *)nth_value(m);

  //the key isn't in the list, but return the right pointer
  nodeID_t *p = NULL;
  if (comp < 0)
    if (m > 0)
      p = (nodeID_t *)nth_value(m-1);
    else
      p = &p_zero;
  else
    p = (nodeID_t *)nth_value(m);
  return *p;
  */
  
  
  int i = 0;
  int c = -1;
  
  while ( (i < header->numElems) && 
	  ((c = tree->comparisonFunction(key, len, nth_key(i), nth_keyLen(i))) > 0)) i++;
  
  //hit dup
  nodeID_t retVal=-666;
  if (c == 0)  retVal = *(nodeID_t *)nth_value(i);
  //last pointer case
  else if (i == header->numElems) retVal = *(nodeID_t *)nth_value(header->numElems - 1);
  //p_zero case
  else if (i == 0) retVal =  p_zero;
  else retVal = *(nodeID_t *)nth_value(i-1);
  
  return retVal;
}
Beispiel #7
0
int     seq_key(BTREE *bt, long page, int m, KEY *key, int *t)
{
PAGE_ADDRESS *p;
KEY *pk, *pkk;
long    nx;
int     l, r, k;

   if (page == BTREE_NULL)
   {
	*t = m + 1;
        return 0;
   }

   p = (PAGE_ADDRESS *) get_page(bt, page);
   pk = (KEY *) (p + 1);

   l = 0; r = p->nkeys-1;
   do {
        k = (l + r) / 2;
        pkk = nth_key(bt, p, k);

        if (bt->compare_key((void *) key, pkk) < 0) r = k - 1;
        else

        if (bt->compare_key((void *) key, pkk) > 0) l = k + 1;
        else
           break;
   } while (r >= l);

   if (r >= l)
   {
	m += p->child0+1;
	for (r = 0; r < k; r++)
	   m += p->s[r].child + 1;
	*t = m;
        return 0;      /* chave existe */
   }

   if (r < 0)
        nx = p->next0;
   else
   {
        nx = p->s[r].next;
        m += p->child0 + 1;
	for (k = 0; k < r; k++)
	   m += p->s[k].child + 1;
   }

   return seq_key(bt, nx, m, key, t);
}
Beispiel #8
0
int     delete_key(BTREE *bt, long page, KEY *key)
{
PAGE_ADDRESS *p;
KEY *pk, *pkk;
long    nx;
int     l, r, k;

   if (page == BTREE_NULL)
   {
        btree_errno = NON_KEY;
        return -1;
   }

   p = (PAGE_ADDRESS *) get_page(bt, page);
   pk = (KEY *) (p + 1);

   l = 0; r = p->nkeys-1;
   do {
        k = (l + r) / 2;
        pkk = nth_key(bt, p, k);

        if (bt->compare_key((void *) key, pkk) < 0) r = k - 1;
        else

        if (bt->compare_key((void *) key, pkk) > 0) l = k + 1;
        else
           break;
   } while (r >= l);

   if (r >= l)
   {
	if (p->s[k].size < 0)
	{
	   btree_errno = DEL_KEY;
	   return -1;
	}
	p->s[k].size *= -1;
        return 0;      
   }

   if (r < 0)
        nx = p->next0;
   else
        nx = p->s[r].next;

   return delete_key(bt, nx, key);
}
Beispiel #9
0
int     search_key(BTREE *bt, long page, KEY *key, ITEM *u)
{
PAGE_ADDRESS *p;
KEY *pk, *pkk;
long    nx;
int	l, r, k;

   if (page == BTREE_NULL)
   {
        u->next = page;
	u->address = BTREE_NULL;
	u->size = -1;
	btree_errno = NON_KEY;
        return -1;
   }

   p = (PAGE_ADDRESS *) get_page(bt, page);
   pk = (KEY *) (p + 1);

   l = 0; r = p->nkeys-1;
   do {
        k = (l + r) / 2;
        pkk = nth_key(bt, p, k);

        if (bt->compare_key((void *) key, pkk) < 0) r = k - 1;
        else

        if (bt->compare_key((void *) key, pkk) > 0) l = k + 1;
        else
           break;
   } while (r >= l);

   if (r >= l)
   {
	*u = p->s[k];
        return 0;      /* chave jah existe */
   }

   if (r < 0)
        nx = p->next0;
   else
        nx = p->s[r].next;

   return search_key(bt, nx, key, u);
}
Beispiel #10
0
int     get_nth(BTREE *bt, long page, int n, KEY *key, ITEM *u)
{
PAGE_ADDRESS *p;
int     i, cont;

   if (page == BTREE_NULL)
   {
        btree_errno = INTERN_MIST;
        return -1;
   }

   p = (PAGE_ADDRESS *) get_page(bt, page);

   if (p->child0 >= n)
        return get_nth(bt, p->next0, n, key, u);

   n -= p->child0;
   i = 0;
   while (i < p->nkeys-1)
   {
        if (1 == n)
        {
           l1:
           memcpy(key, nth_key(bt, p, i), bt->realkeysize);
           *u = p->s[i];
           return 0;
        }
        n--;
        if (n <= p->s[i].child)
           return get_nth(bt, p->s[i].next, n , key, u);
        n-= p->s[i].child;
        i++;
   }
   if (n == 1)
        goto l1;

   return get_nth(bt, p->s[i].next, n-1 , key, u);
}
Beispiel #11
0
int	insert_key(BTREE *bt, long page, KEY *key, ITEM *u, KEY **hkey)
{
PAGE_ADDRESS *p, *b;
KEY *pk, *pkk, *vkey;
long	nx;
int	k, l, r, n;
ITEM	v;

   *hkey = NULL;
   if (page == BTREE_NULL)
   {
	u->next = page;
	u->child = 0;
	*hkey = (KEY *) malloc(bt->keysize);
	memcpy(*hkey, key, bt->realkeysize);
        return 0;
   }

   p = (PAGE_ADDRESS *) get_page(bt, page);
   pk = (KEY *) (p + 1);

   l = 0; r = p->nkeys-1;
   do {
	k = (l + r) / 2;
	pkk = nth_key(bt, p, k);

	if (bt->compare_key((void *) key, pkk) < 0) r = k - 1;
	else

	if (bt->compare_key((void *) key, pkk) > 0) l = k + 1;
	else
	   break;
   } while (r >= l);

   if (r >= l)
   {
	if (p->s[k].size < 0) /* chave foi deletada */
	{
	   p->s[k].size = u->size;
	   p->s[k].address = u->address;
	   memcpy(nth_key(bt, p, k), key, bt->realkeysize);
	   return 0;
	} 
	btree_errno = DUP_KEY;
	return -1;	/* chave jah existe */
   }

   if (r < 0)
      	nx = p->next0;
   else
	nx = p->s[r].next;

   v = *u;
   if ((k = insert_key(bt, nx, key, &v, &vkey)) < 0)
	return k;

   if (vkey == NULL)
   {
     if ( r < 0)
     {
	p->child0 += v.child;
     }
     else
     {
	p->s[r].child += v.child;
     }
     *u = v;
     write_page(bt, p);
     return 0;
   }	

   p->s[r].child -= v.child;

   if (p->nkeys < bt->order)
   {
	for (k = p->nkeys; k > r+1; k--)
	{
	   p->s[k] = p->s[k-1];
	   pkk = nth_key(bt, p, k);
	   pk = nth_key(bt, p, k-1);
	   memcpy(pkk, pk, bt->realkeysize);
	}
	memcpy(nth_key(bt, p, k), vkey, bt->realkeysize);
	p->s[k] = v;
	p->nkeys++;
	u->child = 1;
	free(vkey);
	write_page(bt, p);
	return 0;
   }

   b = (PAGE_ADDRESS *) new_page(bt);
   b->label = BTREE_LABEL;
   n = bt->order / 2 - 1;
   if (r <= n)
   {
	if (r != n)
	{
	   *u = p->s[n];
	   *hkey = (KEY *) malloc(bt->keysize);
	   memcpy(*hkey, nth_key(bt, p, n), bt->realkeysize);
	   for (k = n ; k > r+1; k--)
	   {
	   	p->s[k] = p->s[k-1];
	   	pkk = nth_key(bt, p, k);
	   	pk = nth_key(bt, p, k-1);
	   	memcpy(pkk, pk, bt->realkeysize);
	   }
	   memcpy(nth_key(bt, p, k), vkey, bt->realkeysize);
	   p->s[k] = v;
	   free(vkey);
	}
	else
	{
	   *u = v;
	   *hkey = vkey;
	}
	n++;
	
	for (k = 0; k < n; k++)
	{
	   b->s[k] = p->s[k+n];
	   memcpy(nth_key(bt, b, k), nth_key(bt, p, k+n), bt->realkeysize);
	}
   }
   else
   {
	r = r - n - 1;
	*u = p->s[n+1];
	*hkey = (KEY *) malloc(bt->keysize);
	memcpy(*hkey, nth_key(bt, p, n+1), bt->realkeysize);
	for (k = 0; k < r; k++)
	{
	   
	   b->s[k] = p->s[k+n+2];
	   memcpy(nth_key(bt, b, k), nth_key(bt, p, k+n+2), bt->realkeysize);
	}
	memcpy(nth_key(bt, b, k), vkey, bt->realkeysize);
	b->s[k] = v;
	free(vkey);
	n++;
	for (k = r+1; k < n; k++)
	{
	   
	   b->s[k] = p->s[k+n];
	   memcpy(nth_key(bt, b, k), nth_key(bt, p, k+n), bt->realkeysize);
	}
   }
   p->nkeys = b->nkeys = n;
   b->next0 = u->next;
   b->child0 = u->child;
   u->next = address_of(bt, b);
   u->child = n + b->child0;
   for (k = 0; k < n; k++)
      u->child += b->s[k].child;
   write_page(bt, p);
   write_page(bt, b); 
   return 0;
}