filehash/ffdb_page.c
static int
_ffdb_get_data (ffdb_htab_t* hashp, ffdb_hent_t* item,
		FFDB_DBT* val, ffdb_datap_t* datap)
{
  pgno_t next, tp;
  void* pagep;
  ffdb_data_header_t* header;
  unsigned int start, rlen, idx, copylen, newchksum;
  int needfree = 0;

  /* Get first page where the data item resides */
  pagep = ffdb_get_page (hashp, datap->first, HASH_DATA_PAGE, 0, &tp);
  if (!pagep) {
    fprintf (stderr, "Cannot get data page at %d \n", datap->first);
    return -1;
  }
  
  /* now do a quick sanity check */
  assert (datap->first == CURR_PGNO(pagep));
  assert (NUM_ENT(pagep) >= 1);

  /* Jump to the offset pointed by datap */
  header = BIG_DATA_HEADER(pagep,datap->offset);
 
  assert (header->len == datap->len);
  assert (header->status == DATA_VALID);
  assert (header->key_page == item->pgno);
  assert (header->key_idx == item->pgndx);

  /* Now check whether I have allocated space to data */
  if (val->data && val->size > 0) {
    if (val->size < header->len) {
      fprintf (stderr, "Warning: application allocated space %d < data size %d\n",
	       val->size, header->len);
      return -1;
    }
    else
      val->size = header->len;
  }
  else {
    val->data = (char *)malloc(header->len * sizeof (char));
    val->size = header->len;
    needfree = 1;
  }
  
  /* Now I am ready to copy */
  rlen = val->size;
  start = datap->offset + sizeof(ffdb_data_header_t);
  next = NEXT_PGNO(pagep);
  while (rlen > 0) {
    /* where copy starts in val->data */
    idx = val->size - rlen;
    /* find out how many bytes of data to copy */
    if (start + rlen <= hashp->hdr.bsize) 
      copylen = rlen;
    else 
      copylen = hashp->hdr.bsize - start;

    memcpy ((unsigned char *)val->data + idx, pagep + start, copylen);
    /* release this page */
    ffdb_put_page (hashp, pagep, HASH_DATA_PAGE, 0);

    rlen -= copylen;
    if (rlen > 0) { /* multiple pages */
      /* get next page */
      pagep = ffdb_get_page (hashp, next, HASH_DATA_PAGE, 0, &tp);
      if (!pagep) {
	fprintf (stderr, "Cannot get data page at %d\n", next);
	val->size = 0;
	if (needfree) {
	  free (val->data);
	  val->data = 0;
	}
	return -1;
      }
      start = BIG_PAGE_OVERHEAD;
      next = NEXT_PGNO(pagep);
    }
  }
  /* Now item is copied, run check sum */
  newchksum = 0;
  newchksum = __ffdb_crc32_checksum (newchksum, val->data,
				     val->size);

  if (val->size == header->len) {
    if (newchksum != datap->chksum) {
      fprintf (stderr, "Val = %s size = %d\n", (char *)val->data, val->size);
      fprintf (stderr, "Get data checksum mismatch 0x%x (calculated) != 0x%x (stored)\n", newchksum, datap->chksum);
      if (needfree) {
	free (val->data);
	val->data = 0;
      }
      val->size = 0;
      return -1;
    }
  }
  return 0;
}
/**
 * Get a real data item from data pages pointed by the data pointer
 * 
 * @param hashp the pointer to hash table
 * @param item  hash entry item pointer
 * @param val   the pointer to data storage: if val->data is null, 
 * a new malloc is used, caller has to free. If val->data is not null,
 * a quick memcpy using val->size as the length.
 * @param datap data pointer containg information about data
 *
 * @return 0 on success, -1 otherwise
 */
Get a real data item from data pages pointed by the data pointer

@param hashp the pointer to hash table
@param item  hash entry item pointer
@param val   the pointer to data storage: if val->data is null,
a new malloc is used, caller has to free. If val->data is not null,
a quick memcpy using val->size as the length.
@param datap data pointer containg information about data

@return 0 on success, -1 otherwise
Get a real data item from data pages pointed by the data pointer @param hashp the pointer to hash table @param item hash entry item pointer @param val the pointer to data storage : if val - > data is null a new malloc is used caller has to free . If val - > data is not null a quick memcpy using val - > size as the length . @param datap data pointer containg information about data @return 0 on success - 1 otherwise
static int
_ffdb_get_data (ffdb_htab_t* hashp, ffdb_hent_t* item,
		FFDB_DBT* val, ffdb_datap_t* datap)
{
  pgno_t next, tp;
  void* pagep;
  ffdb_data_header_t* header;
  unsigned int start, rlen, idx, copylen, newchksum;
  int needfree = 0;
  pagep = ffdb_get_page (hashp, datap->first, HASH_DATA_PAGE, 0, &tp);
  if (!pagep) {
    fprintf (stderr, "Cannot get data page at %d \n", datap->first);
    return -1;
  }
  assert (datap->first == CURR_PGNO(pagep));
  assert (NUM_ENT(pagep) >= 1);
  header = BIG_DATA_HEADER(pagep,datap->offset);
  assert (header->len == datap->len);
  assert (header->status == DATA_VALID);
  assert (header->key_page == item->pgno);
  assert (header->key_idx == item->pgndx);
  if (val->data && val->size > 0) {
    if (val->size < header->len) {
      fprintf (stderr, "Warning: application allocated space %d < data size %d\n",
	       val->size, header->len);
      return -1;
    }
    else
      val->size = header->len;
  }
  else {
    val->data = (char *)malloc(header->len * sizeof (char));
    val->size = header->len;
    needfree = 1;
  }
  rlen = val->size;
  start = datap->offset + sizeof(ffdb_data_header_t);
  next = NEXT_PGNO(pagep);
  while (rlen > 0) {
    idx = val->size - rlen;
    if (start + rlen <= hashp->hdr.bsize) 
      copylen = rlen;
    else 
      copylen = hashp->hdr.bsize - start;
    memcpy ((unsigned char *)val->data + idx, pagep + start, copylen);
    ffdb_put_page (hashp, pagep, HASH_DATA_PAGE, 0);
    rlen -= copylen;
    if (rlen > 0) { 
      pagep = ffdb_get_page (hashp, next, HASH_DATA_PAGE, 0, &tp);
      if (!pagep) {
	fprintf (stderr, "Cannot get data page at %d\n", next);
	val->size = 0;
	if (needfree) {
	  free (val->data);
	  val->data = 0;
	}
	return -1;
      }
      start = BIG_PAGE_OVERHEAD;
      next = NEXT_PGNO(pagep);
    }
  }
  newchksum = 0;
  newchksum = __ffdb_crc32_checksum (newchksum, val->data,
				     val->size);
  if (val->size == header->len) {
    if (newchksum != datap->chksum) {
      fprintf (stderr, "Val = %s size = %d\n", (char *)val->data, val->size);
      fprintf (stderr, "Get data checksum mismatch 0x%x (calculated) != 0x%x (stored)\n", newchksum, datap->chksum);
      if (needfree) {
	free (val->data);
	val->data = 0;
      }
      val->size = 0;
      return -1;
    }
  }
  return 0;
}
static int _ffdb_get_data ( ffdb_htab_t * hashp , ffdb_hent_t * item , FFDB_DBT * val , ffdb_datap_t * datap ) { pgno_t next , tp ; void * pagep ; ffdb_data_header_t * header ; unsigned int start , rlen , idx , copylen , newchksum ; int needfree = 0 ; pagep = ffdb_get_page ( hashp , datap -> first , HASH_DATA_PAGE , 0 , & tp ) ; if ( ! pagep ) { fprintf ( stderr , " \n " , datap -> first ) ; return -1 ; } assert ( datap -> first == CURR_PGNO ( pagep ) ) ; assert ( NUM_ENT ( pagep ) >= 1 ) ; header = BIG_DATA_HEADER ( pagep , datap -> offset ) ; assert ( header -> len == datap -> len ) ; assert ( header -> status == DATA_VALID ) ; assert ( header -> key_page == item -> pgno ) ; assert ( header -> key_idx == item -> pgndx ) ; if ( val -> data && val -> size > 0 ) { if ( val -> size < header -> len ) { fprintf ( stderr , " \n " , val -> size , header -> len ) ; return -1 ; } else val -> size = header -> len ; } else { val -> data = ( char * ) malloc ( header -> len * sizeof ( char ) ) ; val -> size = header -> len ; needfree = 1 ; } rlen = val -> size ; start = datap -> offset + sizeof ( ffdb_data_header_t ) ; next = NEXT_PGNO ( pagep ) ; while ( rlen > 0 ) { idx = val -> size - rlen ; if ( start + rlen <= hashp -> hdr . bsize ) copylen = rlen ; else copylen = hashp -> hdr . bsize - start ; memcpy ( ( unsigned char * ) val -> data + idx , pagep + start , copylen ) ; ffdb_put_page ( hashp , pagep , HASH_DATA_PAGE , 0 ) ; rlen -= copylen ; if ( rlen > 0 ) { pagep = ffdb_get_page ( hashp , next , HASH_DATA_PAGE , 0 , & tp ) ; if ( ! pagep ) { fprintf ( stderr , " \n " , next ) ; val -> size = 0 ; if ( needfree ) { free ( val -> data ) ; val -> data = 0 ; } return -1 ; } start = BIG_PAGE_OVERHEAD ; next = NEXT_PGNO ( pagep ) ; } } newchksum = 0 ; newchksum = __ffdb_crc32_checksum ( newchksum , val -> data , val -> size ) ; if ( val -> size == header -> len ) { if ( newchksum != datap -> chksum ) { fprintf ( stderr , " \n " , ( char * ) val -> data , val -> size ) ; fprintf ( stderr , " \n " , newchksum , datap -> chksum ) ; if ( needfree ) { free ( val -> data ) ; val -> data = 0 ; } val -> size = 0 ; return -1 ; } } return 0 ; }
Get a real data item from data pages pointed by the data pointer
Get a real data item from data pages pointed by the data pointer
/* Get first page where the data item resides */ /* now do a quick sanity check */ /* Jump to the offset pointed by datap */ /* Now check whether I have allocated space to data */ /* Now I am ready to copy */ /* where copy starts in val->data */ /* find out how many bytes of data to copy */ /* release this page */ /* multiple pages */ /* get next page */ /* Now item is copied, run check sum */