filehash/ffdb_page.c
int ffdb_find_item (ffdb_htab_t* hashp,
		    FFDB_DBT* key, FFDB_DBT* val,
		    ffdb_hent_t* item)
{
  unsigned int i, found, done;
  pgno_t nextp;
  unsigned int chksum = 0;
  FFDB_DBT ekey;
  unsigned char *ekdata = 0;
  ffdb_datap_t* datap = 0;


  /* first get page for this bucket */
  item->pagep = ffdb_get_page (hashp, item->bucket, HASH_BUCKET_PAGE,
			       FFDB_PAGE_CREATE, &item->pgno);
  if (item->pagep == 0) {
    fprintf (stderr, "Cannot get page for bucket %d\n", item->bucket);
    item->status = ITEM_ERROR;
    return -1;
  }
#ifdef _FFDB_DEBUG
  fprintf (stderr, "Allocate page %d for bucket %d num entry %d\n", item->pgno, 
	   item->bucket, NUM_ENT(item->pagep));
#endif

  /* do a quick checksum on data */
  if (val) {
    chksum = 0;
    chksum = __ffdb_crc32_checksum (chksum, val->data, val->size);
    item->data_chksum = chksum;
  }
  else
    item->data_chksum = 0;

  if (NUM_ENT(item->pagep) == 0) { /* new page or nothing on it */
    item->pgndx = 0;
    item->status = ITEM_NO_MORE;
    _ffdb_init_page (hashp, item->pagep, item->pgno, HASH_BUCKET_PAGE);
    return 0;
  }

#ifdef _FFDB_STATISTICS
  FFDB_LOCK (hashp->lock);
  hash_collisions++;
  FFDB_UNLOCK (hashp->lock);
#endif

  /* set item page number information */
  item->pgno = CURR_PGNO (item->pagep);
  item->status = ITEM_NO_MORE;
  found = 0;
  done = 0;
  while (!done) {
    for (i = 0; i < NUM_ENT(item->pagep); i++) {
      /* get key for this index */
      ekdata = KEY(item->pagep, i);
      ekey.data = ekdata;
      ekey.size = KEY_LEN(item->pagep, i);
      /* get data for this index */
      datap = DATAP(item->pagep, i);

      /* We do not allow duplicated keys */
      if (hashp->h_compare(key, &ekey) == 0) {
	found = 1;
	break;
      }
    }
    if (found) /* We have found an item */
      done = 1;
    else {
      /* This is the page */
      if (NEXT_PGNO(item->pagep) == INVALID_PGNO)
	done = 1;
      else {
	nextp = NEXT_PGNO(item->pagep);

	/* Put this page back */
	ffdb_put_page (hashp, item->pagep, HASH_BUCKET_PAGE, 0);

	/* get the next page */
	item->pagep = ffdb_get_page (hashp, nextp, HASH_OVFL_PAGE,
				     0, &item->pgno);
	if (item->pagep == 0) {
	  fprintf (stderr, "Cannot get next page for bucket %d at page %d\n", 
		   item->bucket, item->pgno);
	  item->status = ITEM_ERROR;
	  return -1;
	}
#ifdef _FFDB_DEBUG
	fprintf (stderr, "Could not find item on primary page, check next page at %d\n", nextp);
#endif
      }
    }
  }
  /* no matter whether we found the item or not, the index = i */
  item->pgndx = i;

  if (found) {
    /* We found the key */
    item->status = ITEM_OK;
    item->key_off = KEY_OFF(item->pagep, i);
    item->key_len = KEY_LEN(item->pagep, i);
    item->data_off = DATAP_OFF(item->pagep, i);
  }
  return 0;
}
/**
 * Routines to find a page for key and data pair
 */
Routines to find a page for key and data pair
Routines to find a page for key and data pair
int ffdb_find_item (ffdb_htab_t* hashp,
		    FFDB_DBT* key, FFDB_DBT* val,
		    ffdb_hent_t* item)
{
  unsigned int i, found, done;
  pgno_t nextp;
  unsigned int chksum = 0;
  FFDB_DBT ekey;
  unsigned char *ekdata = 0;
  ffdb_datap_t* datap = 0;
  item->pagep = ffdb_get_page (hashp, item->bucket, HASH_BUCKET_PAGE,
			       FFDB_PAGE_CREATE, &item->pgno);
  if (item->pagep == 0) {
    fprintf (stderr, "Cannot get page for bucket %d\n", item->bucket);
    item->status = ITEM_ERROR;
    return -1;
  }
#ifdef _FFDB_DEBUG
  fprintf (stderr, "Allocate page %d for bucket %d num entry %d\n", item->pgno, 
	   item->bucket, NUM_ENT(item->pagep));
#endif
  if (val) {
    chksum = 0;
    chksum = __ffdb_crc32_checksum (chksum, val->data, val->size);
    item->data_chksum = chksum;
  }
  else
    item->data_chksum = 0;
  if (NUM_ENT(item->pagep) == 0) { 
    item->pgndx = 0;
    item->status = ITEM_NO_MORE;
    _ffdb_init_page (hashp, item->pagep, item->pgno, HASH_BUCKET_PAGE);
    return 0;
  }
#ifdef _FFDB_STATISTICS
  FFDB_LOCK (hashp->lock);
  hash_collisions++;
  FFDB_UNLOCK (hashp->lock);
#endif
  item->pgno = CURR_PGNO (item->pagep);
  item->status = ITEM_NO_MORE;
  found = 0;
  done = 0;
  while (!done) {
    for (i = 0; i < NUM_ENT(item->pagep); i++) {
      ekdata = KEY(item->pagep, i);
      ekey.data = ekdata;
      ekey.size = KEY_LEN(item->pagep, i);
      datap = DATAP(item->pagep, i);
      if (hashp->h_compare(key, &ekey) == 0) {
	found = 1;
	break;
      }
    }
    if (found) 
      done = 1;
    else {
      if (NEXT_PGNO(item->pagep) == INVALID_PGNO)
	done = 1;
      else {
	nextp = NEXT_PGNO(item->pagep);
	ffdb_put_page (hashp, item->pagep, HASH_BUCKET_PAGE, 0);
	item->pagep = ffdb_get_page (hashp, nextp, HASH_OVFL_PAGE,
				     0, &item->pgno);
	if (item->pagep == 0) {
	  fprintf (stderr, "Cannot get next page for bucket %d at page %d\n", 
		   item->bucket, item->pgno);
	  item->status = ITEM_ERROR;
	  return -1;
	}
#ifdef _FFDB_DEBUG
	fprintf (stderr, "Could not find item on primary page, check next page at %d\n", nextp);
#endif
      }
    }
  }
  item->pgndx = i;
  if (found) {
    item->status = ITEM_OK;
    item->key_off = KEY_OFF(item->pagep, i);
    item->key_len = KEY_LEN(item->pagep, i);
    item->data_off = DATAP_OFF(item->pagep, i);
  }
  return 0;
}
int ffdb_find_item ( ffdb_htab_t * hashp , FFDB_DBT * key , FFDB_DBT * val , ffdb_hent_t * item ) { unsigned int i , found , done ; pgno_t nextp ; unsigned int chksum = 0 ; FFDB_DBT ekey ; unsigned char * ekdata = 0 ; ffdb_datap_t * datap = 0 ; item -> pagep = ffdb_get_page ( hashp , item -> bucket , HASH_BUCKET_PAGE , FFDB_PAGE_CREATE , & item -> pgno ) ; if ( item -> pagep == 0 ) { fprintf ( stderr , " \n " , item -> bucket ) ; item -> status = ITEM_ERROR ; return -1 ; } #ifdef _FFDB_DEBUG fprintf ( stderr , " \n " , item -> pgno , item -> bucket , NUM_ENT ( item -> pagep ) ) ; #endif if ( val ) { chksum = 0 ; chksum = __ffdb_crc32_checksum ( chksum , val -> data , val -> size ) ; item -> data_chksum = chksum ; } else item -> data_chksum = 0 ; if ( NUM_ENT ( item -> pagep ) == 0 ) { item -> pgndx = 0 ; item -> status = ITEM_NO_MORE ; _ffdb_init_page ( hashp , item -> pagep , item -> pgno , HASH_BUCKET_PAGE ) ; return 0 ; } #ifdef _FFDB_STATISTICS FFDB_LOCK ( hashp -> lock ) ; hash_collisions ++ ; FFDB_UNLOCK ( hashp -> lock ) ; #endif item -> pgno = CURR_PGNO ( item -> pagep ) ; item -> status = ITEM_NO_MORE ; found = 0 ; done = 0 ; while ( ! done ) { for ( i = 0 ; i < NUM_ENT ( item -> pagep ) ; i ++ ) { ekdata = KEY ( item -> pagep , i ) ; ekey . data = ekdata ; ekey . size = KEY_LEN ( item -> pagep , i ) ; datap = DATAP ( item -> pagep , i ) ; if ( hashp -> h_compare ( key , & ekey ) == 0 ) { found = 1 ; break ; } } if ( found ) done = 1 ; else { if ( NEXT_PGNO ( item -> pagep ) == INVALID_PGNO ) done = 1 ; else { nextp = NEXT_PGNO ( item -> pagep ) ; ffdb_put_page ( hashp , item -> pagep , HASH_BUCKET_PAGE , 0 ) ; item -> pagep = ffdb_get_page ( hashp , nextp , HASH_OVFL_PAGE , 0 , & item -> pgno ) ; if ( item -> pagep == 0 ) { fprintf ( stderr , " \n " , item -> bucket , item -> pgno ) ; item -> status = ITEM_ERROR ; return -1 ; } #ifdef _FFDB_DEBUG fprintf ( stderr , " \n " , nextp ) ; #endif } } } item -> pgndx = i ; if ( found ) { item -> status = ITEM_OK ; item -> key_off = KEY_OFF ( item -> pagep , i ) ; item -> key_len = KEY_LEN ( item -> pagep , i ) ; item -> data_off = DATAP_OFF ( item -> pagep , i ) ; } return 0 ; }
Routines to find a page for key and data pair
Routines to find a page for key and data pair
/* first get page for this bucket */ /* do a quick checksum on data */ /* new page or nothing on it */ /* set item page number information */ /* get key for this index */ /* get data for this index */ /* We do not allow duplicated keys */ /* We have found an item */ /* This is the page */ /* Put this page back */ /* get the next page */ /* no matter whether we found the item or not, the index = i */ /* We found the key */