filehash/ffdb_pagepool.c
static int
_ffdb_pagepool_new_page_i (ffdb_pagepool_t* pgp, pgno_t* pageno,
			   unsigned int flags,  void** mem)
{
  int status;
  struct _ffdb_hqh *head;
  ffdb_bkt_t *bp = 0;

  if (pgp->maxpgno == FFDB_MAX_PAGE_NUMBER) {
    (void)fprintf(stderr, "ffdb_pagepool_new_page: page allocation overflow.\n");
    abort();
  }
#ifdef _FFDB_STATISTICS
  ++pgp->pagenew;
#endif

  /*
   * Get a BKT from the cache.  Assign a new page number, attach
   * it to the head of the hash chain, the tail of the lru chain,
   * and return.
   *
   */
  if (pgp->curcache > pgp->maxcache) {
    /**
     * If the cache is max'd out, walk the lru list for a buffer we
     * can flush.  If we find one, write it (if necessary) and take it
     * off any lists.  If we don't find anything we grow the cache anyway.
     * The cache never shrinks.
     */
    status = _ffdb_pagepool_reuse_bkt (pgp, &bp);
    if (status == -1) {
      /* cannot find page to reuse */
      bp = _ffdb_pagepool_new_bkt (pgp);
    }
  }
  else
    bp = _ffdb_pagepool_new_bkt (pgp);

  /**
   * If we do not have a page, we return -1
   */
  if (!bp) {
    fprintf (stderr, "_ffdb_pagepool_new_page_i: cannot find a new page\n");
    return -1;
  }
  if (FFDB_FLAG_ISSET (flags, FFDB_PAGE_REQUEST)) {
    bp->pgno = *pageno;
    /* new pages can be less than last page because there may be holes */
    if (bp->pgno > pgp->maxpgno) 
      pgp->maxpgno = bp->pgno;
  } else {
    pgp->maxpgno++;
    bp->pgno = *pageno = pgp->maxpgno;
  }

  /* Now we have one thread holding this page */
  bp->ref = 1;
  /* now assign my thread to owner */
  bp->owner = FFDB_THREAD_ID;

  if (FFDB_FLAG_ISSET(flags, FFDB_PAGE_DIRTY) ||
      FFDB_FLAG_ISSET(flags, FFDB_PAGE_EDIT))
    FFDB_FLAG_SET(bp->flags, FFDB_PAGE_DIRTY);
  
  if (FFDB_FLAG_ISSET(flags, FFDB_PAGE_LOCKED))
    FFDB_FLAG_SET(bp->flags, FFDB_PAGE_LOCKED);


  head = &pgp->hqh[FFDB_HASHKEY(bp->pgno)];
#if 0
  {
    ffdb_bkt_t* bk;
    FFDB_CIRCLEQ_FOREACH(bk, head, hq) {
      if (bk->pgno == bp->pgno) {
	fprintf (stderr, "Hash has this page %d alreay\n", bp->pgno);
	pause ();
      }
    }

    FFDB_CIRCLEQ_FOREACH(bk, &pgp->lqh, lq) {
      if (bk->pgno == bp->pgno) {
	fprintf (stderr, "LRU has this page %d alreay\n", bp->pgno);
	pause ();
      }
    } 
  }
#endif
  FFDB_CIRCLEQ_INSERT_HEAD(head, bp, hq);
  FFDB_CIRCLEQ_INSERT_TAIL(&pgp->lqh, bp, lq);

  *mem = bp->page;

  /**
   * since this is a new page. clear first few bytes 
   * to tell applications that this is a clean page 
   */
  memset (bp->page, 0, FFDB_CLEANHDR_SIZE);

  return 0;
}
/**
 * Create a new page not from the back source file
 * @param pgp pagepool pointer
 * @param pageno address of either requested page number or retured page number
 * @param flags request flags.  if flags = FFDB_PAGE_REQUEST, page 
 * will be created using  page number stored in pageno. If flags = 0, 
 * page will be created and new pagenumber is returned.
 * @param mem returned memory address of this page
 * @return 0 on success, otherwise return either errno or -1.
 *
 * This code should be called with lock held
 */
Create a new page not from the back source file
@param pgp pagepool pointer
@param pageno address of either requested page number or retured page number
@param flags request flags.  if flags = FFDB_PAGE_REQUEST, page
will be created using  page number stored in pageno. If flags = 0,
page will be created and new pagenumber is returned.
@param mem returned memory address of this page
@return 0 on success, otherwise return either errno or -1.

This code should be called with lock held
Create a new page not from the back source file @param pgp pagepool pointer @param pageno address of either requested page number or retured page number @param flags request flags . if flags = FFDB_PAGE_REQUEST page will be created using page number stored in pageno . If flags = 0 page will be created and new pagenumber is returned . @param mem returned memory address of this page @return 0 on success otherwise return either errno or - 1 . This code should be called with lock held
static int
_ffdb_pagepool_new_page_i (ffdb_pagepool_t* pgp, pgno_t* pageno,
			   unsigned int flags,  void** mem)
{
  int status;
  struct _ffdb_hqh *head;
  ffdb_bkt_t *bp = 0;
  if (pgp->maxpgno == FFDB_MAX_PAGE_NUMBER) {
    (void)fprintf(stderr, "ffdb_pagepool_new_page: page allocation overflow.\n");
    abort();
  }
#ifdef _FFDB_STATISTICS
  ++pgp->pagenew;
#endif
  if (pgp->curcache > pgp->maxcache) {
    status = _ffdb_pagepool_reuse_bkt (pgp, &bp);
    if (status == -1) {
      bp = _ffdb_pagepool_new_bkt (pgp);
    }
  }
  else
    bp = _ffdb_pagepool_new_bkt (pgp);
  if (!bp) {
    fprintf (stderr, "_ffdb_pagepool_new_page_i: cannot find a new page\n");
    return -1;
  }
  if (FFDB_FLAG_ISSET (flags, FFDB_PAGE_REQUEST)) {
    bp->pgno = *pageno;
    if (bp->pgno > pgp->maxpgno) 
      pgp->maxpgno = bp->pgno;
  } else {
    pgp->maxpgno++;
    bp->pgno = *pageno = pgp->maxpgno;
  }
  bp->ref = 1;
  bp->owner = FFDB_THREAD_ID;
  if (FFDB_FLAG_ISSET(flags, FFDB_PAGE_DIRTY) ||
      FFDB_FLAG_ISSET(flags, FFDB_PAGE_EDIT))
    FFDB_FLAG_SET(bp->flags, FFDB_PAGE_DIRTY);
  if (FFDB_FLAG_ISSET(flags, FFDB_PAGE_LOCKED))
    FFDB_FLAG_SET(bp->flags, FFDB_PAGE_LOCKED);
  head = &pgp->hqh[FFDB_HASHKEY(bp->pgno)];
#if 0
  {
    ffdb_bkt_t* bk;
    FFDB_CIRCLEQ_FOREACH(bk, head, hq) {
      if (bk->pgno == bp->pgno) {
	fprintf (stderr, "Hash has this page %d alreay\n", bp->pgno);
	pause ();
      }
    }
    FFDB_CIRCLEQ_FOREACH(bk, &pgp->lqh, lq) {
      if (bk->pgno == bp->pgno) {
	fprintf (stderr, "LRU has this page %d alreay\n", bp->pgno);
	pause ();
      }
    } 
  }
#endif
  FFDB_CIRCLEQ_INSERT_HEAD(head, bp, hq);
  FFDB_CIRCLEQ_INSERT_TAIL(&pgp->lqh, bp, lq);
  *mem = bp->page;
  memset (bp->page, 0, FFDB_CLEANHDR_SIZE);
  return 0;
}
static int _ffdb_pagepool_new_page_i ( ffdb_pagepool_t * pgp , pgno_t * pageno , unsigned int flags , void * * mem ) { int status ; struct _ffdb_hqh * head ; ffdb_bkt_t * bp = 0 ; if ( pgp -> maxpgno == FFDB_MAX_PAGE_NUMBER ) { ( void ) fprintf ( stderr , " \n " ) ; abort ( ) ; } #ifdef _FFDB_STATISTICS ++ pgp -> pagenew ; #endif if ( pgp -> curcache > pgp -> maxcache ) { status = _ffdb_pagepool_reuse_bkt ( pgp , & bp ) ; if ( status == -1 ) { bp = _ffdb_pagepool_new_bkt ( pgp ) ; } } else bp = _ffdb_pagepool_new_bkt ( pgp ) ; if ( ! bp ) { fprintf ( stderr , " \n " ) ; return -1 ; } if ( FFDB_FLAG_ISSET ( flags , FFDB_PAGE_REQUEST ) ) { bp -> pgno = * pageno ; if ( bp -> pgno > pgp -> maxpgno ) pgp -> maxpgno = bp -> pgno ; } else { pgp -> maxpgno ++ ; bp -> pgno = * pageno = pgp -> maxpgno ; } bp -> ref = 1 ; bp -> owner = FFDB_THREAD_ID ; if ( FFDB_FLAG_ISSET ( flags , FFDB_PAGE_DIRTY ) || FFDB_FLAG_ISSET ( flags , FFDB_PAGE_EDIT ) ) FFDB_FLAG_SET ( bp -> flags , FFDB_PAGE_DIRTY ) ; if ( FFDB_FLAG_ISSET ( flags , FFDB_PAGE_LOCKED ) ) FFDB_FLAG_SET ( bp -> flags , FFDB_PAGE_LOCKED ) ; head = & pgp -> hqh [ FFDB_HASHKEY ( bp -> pgno ) ] ; #if 0 { ffdb_bkt_t * bk ; FFDB_CIRCLEQ_FOREACH ( bk , head , hq ) { if ( bk -> pgno == bp -> pgno ) { fprintf ( stderr , " \n " , bp -> pgno ) ; pause ( ) ; } } FFDB_CIRCLEQ_FOREACH ( bk , & pgp -> lqh , lq ) { if ( bk -> pgno == bp -> pgno ) { fprintf ( stderr , " \n " , bp -> pgno ) ; pause ( ) ; } } } #endif FFDB_CIRCLEQ_INSERT_HEAD ( head , bp , hq ) ; FFDB_CIRCLEQ_INSERT_TAIL ( & pgp -> lqh , bp , lq ) ; * mem = bp -> page ; memset ( bp -> page , 0 , FFDB_CLEANHDR_SIZE ) ; return 0 ; }
Create a new page not from the back source file
 @param pgp pagepool pointer
 @param pageno address of either requested page number or retured page number
 @param flags request flags.
Create a new page not from the back source file @param pgp pagepool pointer @param pageno address of either requested page number or retured page number @param flags request flags .
/*
   * Get a BKT from the cache.  Assign a new page number, attach
   * it to the head of the hash chain, the tail of the lru chain,
   * and return.
   *
   */ /**
     * If the cache is max'd out, walk the lru list for a buffer we
     * can flush.  If we find one, write it (if necessary) and take it
     * off any lists.  If we don't find anything we grow the cache anyway.
     * The cache never shrinks.
     */ /* cannot find page to reuse */ /**
   * If we do not have a page, we return -1
   */ /* new pages can be less than last page because there may be holes */ /* Now we have one thread holding this page */ /* now assign my thread to owner */ /**
   * since this is a new page. clear first few bytes 
   * to tell applications that this is a clean page 
   */