filehash/ffdb_hash.c
static int
_ffdb_hash_put (const FFDB_DB* dbp, FFDB_DBT* key, const FFDB_DBT* data,
		unsigned int flag)
{
  ffdb_htab_t* hashp;
  ffdb_hent_t item;
  unsigned int bucket;
  int status, newkey;

#if 0
#ifdef _FFDB_DEBUG
  fprintf (stderr, "ffdb_hash_put key %s data %s\n", (char *)key->data,
	   (char *)data->data);
#endif
#endif

  hashp = (ffdb_htab_t *)dbp->internal;

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

  /* This is a new key */
  newkey = 1;

  /* check flags: if there is a flag it must be FFDB_NOOVERWRITE */
  if (flag && flag != FFDB_NOOVERWRITE) {
    FFDB_LOCK (hashp->lock);
    hashp->db_errno = errno = EINVAL;
    FFDB_UNLOCK (hashp->lock);
    return -1;
  }
  
  /* check file permission, if this is a read only file, cannot do it */
  if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
    FFDB_LOCK (hashp->lock);
    hashp->db_errno = errno = EPERM;
    FFDB_UNLOCK (hashp->lock);
    return -1;
  }

  /* initialize item */
  memset (&item, 0, sizeof (ffdb_hent_t));
  /* Calculate the hash item size */
  item.seek_size = PAIRSIZE(key, data);

  /* calculate hash value for this key */
  bucket = _ffdb_call_hash (hashp, key->data, key->size);
  item.bucket = bucket;

#ifdef _FFDB_DEBUG
  fprintf (stderr, "Key %s hash bucket = %d\n", (char *)key->data, bucket);
#endif

  /* Now I need find a page on which this key may reside */
  /* Find item is thread safe */
  status = ffdb_find_item (hashp, key, (FFDB_DBT *)data, &item);
  if (status != 0)  /* Something is really wrong */
    return status;


  FFDB_LOCK(hashp->lock);
  if (item.status == ITEM_NO_MORE) {
    /* There is no item found, we need to insert this item */
    /* Find out whether there is space on this page to fit this pair */
    if (PAIRFITS(item.pagep, key, data)) {
#ifdef _FFDB_DEBUG
      fprintf (stderr, "This data item bucket %d fit with page %d\n", bucket, item.pgno);
#endif
      if ((status = ffdb_add_pair (hashp, key, data, &item, 0)) != 0) {
	FFDB_UNLOCK (hashp->lock);  
	return status;
      }
    }
    else {
      /* Data will not fit on the page */
#ifdef _FFDB_DEBUG
      fprintf (stderr, "This data item will not fit in bucket %d with page %d: overflow page will be added\n", bucket, item.pgno);
#endif

      /* First chain an overflow page */
      if ((status = ffdb_add_ovflpage (hashp, key, data, &item)) != 0) {
	FFDB_UNLOCK (hashp->lock);  
	return status;
      }

      /* Now I need to expand the table even though the current bucket
       * may not be splited at this moment
       */
      if ((status = _ffdb_expand_table (hashp)) != 0) {
	hashp->hdr.nkeys++;
	FFDB_UNLOCK (hashp->lock);
	return status;
      }
    }
    /* Now I should have the data on the page */
  }
  else if (item.status == ITEM_OK) {
    newkey = 0;
    /* This item already exists. Check flag to make sure it is 
     * a replace flag
     */
    if (flag && flag == FFDB_NOOVERWRITE) {
      FFDB_UNLOCK (hashp->lock);  
      return -1;
    }

    if ((status = ffdb_add_pair (hashp, key, data, &item, 1)) != 0) {
      FFDB_UNLOCK (hashp->lock);  
      return -1;
    }
  }      	

  /* update number key information */
  if (newkey)
    hashp->hdr.nkeys++;

  FFDB_UNLOCK (hashp->lock);  
  return 0;
}
/**
 * Put a key and data pair into the database
 */
Put a key and data pair into the database
Put a key and data pair into the database
static int
_ffdb_hash_put (const FFDB_DB* dbp, FFDB_DBT* key, const FFDB_DBT* data,
		unsigned int flag)
{
  ffdb_htab_t* hashp;
  ffdb_hent_t item;
  unsigned int bucket;
  int status, newkey;
#if 0
#ifdef _FFDB_DEBUG
  fprintf (stderr, "ffdb_hash_put key %s data %s\n", (char *)key->data,
	   (char *)data->data);
#endif
#endif
  hashp = (ffdb_htab_t *)dbp->internal;
#ifdef _FFDB_STATISTICS
  FFDB_LOCK (hashp->lock);
  hash_accesses++;
  FFDB_UNLOCK (hashp->lock);
#endif
  newkey = 1;
  if (flag && flag != FFDB_NOOVERWRITE) {
    FFDB_LOCK (hashp->lock);
    hashp->db_errno = errno = EINVAL;
    FFDB_UNLOCK (hashp->lock);
    return -1;
  }
  if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
    FFDB_LOCK (hashp->lock);
    hashp->db_errno = errno = EPERM;
    FFDB_UNLOCK (hashp->lock);
    return -1;
  }
  memset (&item, 0, sizeof (ffdb_hent_t));
  item.seek_size = PAIRSIZE(key, data);
  bucket = _ffdb_call_hash (hashp, key->data, key->size);
  item.bucket = bucket;
#ifdef _FFDB_DEBUG
  fprintf (stderr, "Key %s hash bucket = %d\n", (char *)key->data, bucket);
#endif
  status = ffdb_find_item (hashp, key, (FFDB_DBT *)data, &item);
  if (status != 0)  
    return status;
  FFDB_LOCK(hashp->lock);
  if (item.status == ITEM_NO_MORE) {
    if (PAIRFITS(item.pagep, key, data)) {
#ifdef _FFDB_DEBUG
      fprintf (stderr, "This data item bucket %d fit with page %d\n", bucket, item.pgno);
#endif
      if ((status = ffdb_add_pair (hashp, key, data, &item, 0)) != 0) {
	FFDB_UNLOCK (hashp->lock);  
	return status;
      }
    }
    else {
#ifdef _FFDB_DEBUG
      fprintf (stderr, "This data item will not fit in bucket %d with page %d: overflow page will be added\n", bucket, item.pgno);
#endif
      if ((status = ffdb_add_ovflpage (hashp, key, data, &item)) != 0) {
	FFDB_UNLOCK (hashp->lock);  
	return status;
      }
      if ((status = _ffdb_expand_table (hashp)) != 0) {
	hashp->hdr.nkeys++;
	FFDB_UNLOCK (hashp->lock);
	return status;
      }
    }
  }
  else if (item.status == ITEM_OK) {
    newkey = 0;
    if (flag && flag == FFDB_NOOVERWRITE) {
      FFDB_UNLOCK (hashp->lock);  
      return -1;
    }
    if ((status = ffdb_add_pair (hashp, key, data, &item, 1)) != 0) {
      FFDB_UNLOCK (hashp->lock);  
      return -1;
    }
  }      	
  if (newkey)
    hashp->hdr.nkeys++;
  FFDB_UNLOCK (hashp->lock);  
  return 0;
}
static int _ffdb_hash_put ( const FFDB_DB * dbp , FFDB_DBT * key , const FFDB_DBT * data , unsigned int flag ) { ffdb_htab_t * hashp ; ffdb_hent_t item ; unsigned int bucket ; int status , newkey ; #if 0 #ifdef _FFDB_DEBUG fprintf ( stderr , " \n " , ( char * ) key -> data , ( char * ) data -> data ) ; #endif #endif hashp = ( ffdb_htab_t * ) dbp -> internal ; #ifdef _FFDB_STATISTICS FFDB_LOCK ( hashp -> lock ) ; hash_accesses ++ ; FFDB_UNLOCK ( hashp -> lock ) ; #endif newkey = 1 ; if ( flag && flag != FFDB_NOOVERWRITE ) { FFDB_LOCK ( hashp -> lock ) ; hashp -> db_errno = errno = EINVAL ; FFDB_UNLOCK ( hashp -> lock ) ; return -1 ; } if ( ( hashp -> flags & O_ACCMODE ) == O_RDONLY ) { FFDB_LOCK ( hashp -> lock ) ; hashp -> db_errno = errno = EPERM ; FFDB_UNLOCK ( hashp -> lock ) ; return -1 ; } memset ( & item , 0 , sizeof ( ffdb_hent_t ) ) ; item . seek_size = PAIRSIZE ( key , data ) ; bucket = _ffdb_call_hash ( hashp , key -> data , key -> size ) ; item . bucket = bucket ; #ifdef _FFDB_DEBUG fprintf ( stderr , " \n " , ( char * ) key -> data , bucket ) ; #endif status = ffdb_find_item ( hashp , key , ( FFDB_DBT * ) data , & item ) ; if ( status != 0 ) return status ; FFDB_LOCK ( hashp -> lock ) ; if ( item . status == ITEM_NO_MORE ) { if ( PAIRFITS ( item . pagep , key , data ) ) { #ifdef _FFDB_DEBUG fprintf ( stderr , " \n " , bucket , item . pgno ) ; #endif if ( ( status = ffdb_add_pair ( hashp , key , data , & item , 0 ) ) != 0 ) { FFDB_UNLOCK ( hashp -> lock ) ; return status ; } } else { #ifdef _FFDB_DEBUG fprintf ( stderr , " \n " , bucket , item . pgno ) ; #endif if ( ( status = ffdb_add_ovflpage ( hashp , key , data , & item ) ) != 0 ) { FFDB_UNLOCK ( hashp -> lock ) ; return status ; } if ( ( status = _ffdb_expand_table ( hashp ) ) != 0 ) { hashp -> hdr . nkeys ++ ; FFDB_UNLOCK ( hashp -> lock ) ; return status ; } } } else if ( item . status == ITEM_OK ) { newkey = 0 ; if ( flag && flag == FFDB_NOOVERWRITE ) { FFDB_UNLOCK ( hashp -> lock ) ; return -1 ; } if ( ( status = ffdb_add_pair ( hashp , key , data , & item , 1 ) ) != 0 ) { FFDB_UNLOCK ( hashp -> lock ) ; return -1 ; } } if ( newkey ) hashp -> hdr . nkeys ++ ; FFDB_UNLOCK ( hashp -> lock ) ; return 0 ; }
Put a key and data pair into the database
Put a key and data pair into the database
/* This is a new key */ /* check flags: if there is a flag it must be FFDB_NOOVERWRITE */ /* check file permission, if this is a read only file, cannot do it */ /* initialize item */ /* Calculate the hash item size */ /* calculate hash value for this key */ /* Now I need find a page on which this key may reside */ /* Find item is thread safe */ /* Something is really wrong */ /* There is no item found, we need to insert this item */ /* Find out whether there is space on this page to fit this pair */ /* Data will not fit on the page */ /* First chain an overflow page */ /* Now I need to expand the table even though the current bucket
       * may not be splited at this moment
       */ /* Now I should have the data on the page */ /* This item already exists. Check flag to make sure it is 
     * a replace flag
     */ /* update number key information */