filehash/ffdb_page.c
static void
_ffdb_free_ovflpage (ffdb_htab_t* hashp, void* memp, int isdoubling,
		     int* deleteit)
{
  unsigned int level, nf;
  pgno_t fpage, tp, opage, nextpage, xpage;
  void *fpagep, *fnext, *xpagep;
  int xtra_page, reuse;

  /* Set delete flag to true */
  *deleteit = 1;

  /* get overflow page number */
  opage = CURR_PGNO(memp);

  /* check what level this page belongs to */
  for (level = 0; level <= hashp->hdr.ovfl_point; level++) {
    if (opage < hashp->hdr.spares[level]) {
      break;
    }
  }
  /* level is one level down */
  level--;

#ifdef _FFDB_DEBUG
  fprintf (stderr, "Free overflow page %d for level %d isdoubling = %d\n",
	   opage, level, isdoubling);
#endif

  reuse = 0;
  if (hashp->hdr.free_pages[level] == INVALID_PGNO) {
    /* I just use this page to keep track free pages */
    fpage = opage;
    hashp->hdr.free_pages[level] = fpage;
    *deleteit = 0;

    fnext = fpagep = memp;

    /* Clean this page out into a free page */
    _ffdb_init_page (hashp, fpagep, fpage, HASH_FREE_PAGE);
#ifdef _FFDB_DEBUG
    fprintf (stderr, "Reuse %d to be free page \n", fpage);
#endif
  }
  else {
    fpage = hashp->hdr.free_pages[level];

    /* get this page */
    fnext = fpagep = ffdb_get_page (hashp, fpage, HASH_FREE_PAGE, 
				    FFDB_CREATE, &tp);
    if (!fpagep) {
      fprintf (stderr, "cannot allocate %d for free overflow pages\n", fpage);
      abort ();
    }
    if (reuse)
      _ffdb_init_page (hashp, fpagep, fpage, HASH_FREE_PAGE);

#ifdef _FFDB_DEBUG
    fprintf (stderr, "Get a page %d keeping free page at level %d\n",
	     tp, level);
#endif

    xtra_page = 1;
    /* I have to check chain of pages */
    while (fnext) {
      /* get current number of free pages contained inside this page */
      nf = NUM_FREE_PAGES(fpagep);
      if (nf < MAX_NUM_FREE_PAGES - 1){ /* There is space on this page */
	/* Now write this page number to the free page */
	_ffdb_update_free_page (hashp, fpagep, opage);
	xtra_page = 0;
	/* put this page out */
	ffdb_put_page (hashp, fpagep, TYPE(fpagep), 1);
	/* We are done */
	fnext = 0;
	xtra_page = 0;
      }
      else {
	nextpage = NEXT_PGNO(fpagep);
	if (nextpage == INVALID_PGNO)
	  fnext = 0;
	else {
	  fnext = ffdb_get_page (hashp, nextpage, HASH_FREE_PAGE, 0, &tp);
	  if (!fnext) {
	    fprintf (stderr, "Cannot get free bitmap page %d\n",
		     nextpage);
	    /* release the previous page */
	    ffdb_put_page (hashp, fpagep, TYPE(fpagep), 0);
	    return;
	  }
	  /* release the previous page */
	  ffdb_put_page (hashp, fpagep, TYPE(fpagep), 0);

	  /* assign new pointers */
	  fpagep = fnext;
	  fpage = nextpage;
	}
      }
    }
  
    /* If we need extra page */
    reuse = 0;
    if (xtra_page) {
      /* We need an extra page to store free page. We just use this page */
      xpage = opage;
#ifdef _FFDB_DEBUG
      fprintf (stderr, "reuse overflow page %d as chained free page %d\n",
	       xpage, fpage);
#endif
      *deleteit = 0;

      /* initialize this page */
      xpagep = memp;
      _ffdb_init_page (hashp, xpagep, xpage, HASH_FREE_PAGE);

#ifdef _FFDB_STATISTICS
      hash_overflows++;
#endif

      /* set up correct link */
      NEXT_PGNO (fpagep) = xpage;
      PREV_PGNO (xpagep) = fpage;

      /* release the previous page */
      ffdb_put_page (hashp, fpagep, TYPE(fpagep), 0); 
    }
  }
}
/**
 * Free an overflow page: this happens when a bucket is split. 
 * We need to update free page in the previous level
 *
 * Return whether this page should be deleted
 *
 * The freed overflow page is represented by 'memp'
 */
Free an overflow page: this happens when a bucket is split.
We need to update free page in the previous level

Return whether this page should be deleted

The freed overflow page is represented by 'memp'
Free an overflow page : this happens when a bucket is split . We need to update free page in the previous level Return whether this page should be deleted The freed overflow page is represented by ' memp '
static void
_ffdb_free_ovflpage (ffdb_htab_t* hashp, void* memp, int isdoubling,
		     int* deleteit)
{
  unsigned int level, nf;
  pgno_t fpage, tp, opage, nextpage, xpage;
  void *fpagep, *fnext, *xpagep;
  int xtra_page, reuse;
  *deleteit = 1;
  opage = CURR_PGNO(memp);
  for (level = 0; level <= hashp->hdr.ovfl_point; level++) {
    if (opage < hashp->hdr.spares[level]) {
      break;
    }
  }
  level--;
#ifdef _FFDB_DEBUG
  fprintf (stderr, "Free overflow page %d for level %d isdoubling = %d\n",
	   opage, level, isdoubling);
#endif
  reuse = 0;
  if (hashp->hdr.free_pages[level] == INVALID_PGNO) {
    fpage = opage;
    hashp->hdr.free_pages[level] = fpage;
    *deleteit = 0;
    fnext = fpagep = memp;
    _ffdb_init_page (hashp, fpagep, fpage, HASH_FREE_PAGE);
#ifdef _FFDB_DEBUG
    fprintf (stderr, "Reuse %d to be free page \n", fpage);
#endif
  }
  else {
    fpage = hashp->hdr.free_pages[level];
    fnext = fpagep = ffdb_get_page (hashp, fpage, HASH_FREE_PAGE, 
				    FFDB_CREATE, &tp);
    if (!fpagep) {
      fprintf (stderr, "cannot allocate %d for free overflow pages\n", fpage);
      abort ();
    }
    if (reuse)
      _ffdb_init_page (hashp, fpagep, fpage, HASH_FREE_PAGE);
#ifdef _FFDB_DEBUG
    fprintf (stderr, "Get a page %d keeping free page at level %d\n",
	     tp, level);
#endif
    xtra_page = 1;
    while (fnext) {
      nf = NUM_FREE_PAGES(fpagep);
      if (nf < MAX_NUM_FREE_PAGES - 1){ 
	_ffdb_update_free_page (hashp, fpagep, opage);
	xtra_page = 0;
	ffdb_put_page (hashp, fpagep, TYPE(fpagep), 1);
	fnext = 0;
	xtra_page = 0;
      }
      else {
	nextpage = NEXT_PGNO(fpagep);
	if (nextpage == INVALID_PGNO)
	  fnext = 0;
	else {
	  fnext = ffdb_get_page (hashp, nextpage, HASH_FREE_PAGE, 0, &tp);
	  if (!fnext) {
	    fprintf (stderr, "Cannot get free bitmap page %d\n",
		     nextpage);
	    ffdb_put_page (hashp, fpagep, TYPE(fpagep), 0);
	    return;
	  }
	  ffdb_put_page (hashp, fpagep, TYPE(fpagep), 0);
	  fpagep = fnext;
	  fpage = nextpage;
	}
      }
    }
    reuse = 0;
    if (xtra_page) {
      xpage = opage;
#ifdef _FFDB_DEBUG
      fprintf (stderr, "reuse overflow page %d as chained free page %d\n",
	       xpage, fpage);
#endif
      *deleteit = 0;
      xpagep = memp;
      _ffdb_init_page (hashp, xpagep, xpage, HASH_FREE_PAGE);
#ifdef _FFDB_STATISTICS
      hash_overflows++;
#endif
      NEXT_PGNO (fpagep) = xpage;
      PREV_PGNO (xpagep) = fpage;
      ffdb_put_page (hashp, fpagep, TYPE(fpagep), 0); 
    }
  }
}
static void _ffdb_free_ovflpage ( ffdb_htab_t * hashp , void * memp , int isdoubling , int * deleteit ) { unsigned int level , nf ; pgno_t fpage , tp , opage , nextpage , xpage ; void * fpagep , * fnext , * xpagep ; int xtra_page , reuse ; * deleteit = 1 ; opage = CURR_PGNO ( memp ) ; for ( level = 0 ; level <= hashp -> hdr . ovfl_point ; level ++ ) { if ( opage < hashp -> hdr . spares [ level ] ) { break ; } } level -- ; #ifdef _FFDB_DEBUG fprintf ( stderr , " \n " , opage , level , isdoubling ) ; #endif reuse = 0 ; if ( hashp -> hdr . free_pages [ level ] == INVALID_PGNO ) { fpage = opage ; hashp -> hdr . free_pages [ level ] = fpage ; * deleteit = 0 ; fnext = fpagep = memp ; _ffdb_init_page ( hashp , fpagep , fpage , HASH_FREE_PAGE ) ; #ifdef _FFDB_DEBUG fprintf ( stderr , " \n " , fpage ) ; #endif } else { fpage = hashp -> hdr . free_pages [ level ] ; fnext = fpagep = ffdb_get_page ( hashp , fpage , HASH_FREE_PAGE , FFDB_CREATE , & tp ) ; if ( ! fpagep ) { fprintf ( stderr , " \n " , fpage ) ; abort ( ) ; } if ( reuse ) _ffdb_init_page ( hashp , fpagep , fpage , HASH_FREE_PAGE ) ; #ifdef _FFDB_DEBUG fprintf ( stderr , " \n " , tp , level ) ; #endif xtra_page = 1 ; while ( fnext ) { nf = NUM_FREE_PAGES ( fpagep ) ; if ( nf < MAX_NUM_FREE_PAGES - 1 ) { _ffdb_update_free_page ( hashp , fpagep , opage ) ; xtra_page = 0 ; ffdb_put_page ( hashp , fpagep , TYPE ( fpagep ) , 1 ) ; fnext = 0 ; xtra_page = 0 ; } else { nextpage = NEXT_PGNO ( fpagep ) ; if ( nextpage == INVALID_PGNO ) fnext = 0 ; else { fnext = ffdb_get_page ( hashp , nextpage , HASH_FREE_PAGE , 0 , & tp ) ; if ( ! fnext ) { fprintf ( stderr , " \n " , nextpage ) ; ffdb_put_page ( hashp , fpagep , TYPE ( fpagep ) , 0 ) ; return ; } ffdb_put_page ( hashp , fpagep , TYPE ( fpagep ) , 0 ) ; fpagep = fnext ; fpage = nextpage ; } } } reuse = 0 ; if ( xtra_page ) { xpage = opage ; #ifdef _FFDB_DEBUG fprintf ( stderr , " \n " , xpage , fpage ) ; #endif * deleteit = 0 ; xpagep = memp ; _ffdb_init_page ( hashp , xpagep , xpage , HASH_FREE_PAGE ) ; #ifdef _FFDB_STATISTICS hash_overflows ++ ; #endif NEXT_PGNO ( fpagep ) = xpage ; PREV_PGNO ( xpagep ) = fpage ; ffdb_put_page ( hashp , fpagep , TYPE ( fpagep ) , 0 ) ; } } }
Free an overflow page: this happens when a bucket is split.
Free an overflow page : this happens when a bucket is split .
/* Set delete flag to true */ /* get overflow page number */ /* check what level this page belongs to */ /* level is one level down */ /* I just use this page to keep track free pages */ /* Clean this page out into a free page */ /* get this page */ /* I have to check chain of pages */ /* get current number of free pages contained inside this page */ /* There is space on this page */ /* Now write this page number to the free page */ /* put this page out */ /* We are done */ /* release the previous page */ /* release the previous page */ /* assign new pointers */ /* If we need extra page */ /* We need an extra page to store free page. We just use this page */ /* initialize this page */ /* set up correct link */ /* release the previous page */