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

  /**
   * 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 (!bp) {
    /* This has to be successful. This is a new page */
    fprintf (stderr, "ffdb_pagepool_load_new_page: cannot get new page of page number %d\n", pageno);
    abort ();
  }
  
  /**
   * The obtained bucket has pinned flag set, we own this page.
   * It is time to populate this page using back file
   */
  off = (off_t)pgp->pagesize * (pageno);
  if (lseek (pgp->fd, off, SEEK_SET) != off) {
    fprintf (stderr, "ffdb_pagepool_load_new_page: cannot seek to a right position.\n");
    return errno;
  }
  nbytes = read (pgp->fd, bp->page, pgp->pagesize);
  if (nbytes != pgp->pagesize && nbytes > 0) {
    fprintf (stderr, "ffdb_pagepool_load_new_page: cannot read back end file\n");
    return errno;
  }
  else if (nbytes == 0) 
    memset (bp->page, 0, pgp->pagesize);

#ifdef _FFDB_STATISTICS
  ++pgp->pageread;
#endif

  /* Set page number */
  bp->pgno = pageno;
  bp->owner = FFDB_THREAD_ID;
  bp->ref = 1;
  bp->waiters = 0;

  /* Change flags of this page since I own this page now */
  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);
  
  *mem = bp->page; 

  /* insert this page into LRU and hash bucket */
  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);
#if 0
  fprintf (stderr, "Load page insert pageno %d\n", bp->pgno);
#endif

  /**
   * Check whether page in callback routine 
   */
  if (pgp->pgin) {
    (pgp->pgin)(pgp->pgcookie, bp->pgno, bp->page);
  }

  return 0;
}
/**
 * Get a new page from the back source file
 */
Get a new page from the back source file
Get a new page from the back source file
static int
_ffdb_pagepool_load_new_page (ffdb_pagepool_t* pgp, pgno_t pageno,
			      unsigned int flags, void** mem)
{
  int status, nbytes;
  off_t off;
  struct _ffdb_hqh *head;
  ffdb_bkt_t* bp = 0;
  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_load_new_page: cannot get new page of page number %d\n", pageno);
    abort ();
  }
  off = (off_t)pgp->pagesize * (pageno);
  if (lseek (pgp->fd, off, SEEK_SET) != off) {
    fprintf (stderr, "ffdb_pagepool_load_new_page: cannot seek to a right position.\n");
    return errno;
  }
  nbytes = read (pgp->fd, bp->page, pgp->pagesize);
  if (nbytes != pgp->pagesize && nbytes > 0) {
    fprintf (stderr, "ffdb_pagepool_load_new_page: cannot read back end file\n");
    return errno;
  }
  else if (nbytes == 0) 
    memset (bp->page, 0, pgp->pagesize);
#ifdef _FFDB_STATISTICS
  ++pgp->pageread;
#endif
  bp->pgno = pageno;
  bp->owner = FFDB_THREAD_ID;
  bp->ref = 1;
  bp->waiters = 0;
  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);
  *mem = bp->page; 
  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);
#if 0
  fprintf (stderr, "Load page insert pageno %d\n", bp->pgno);
#endif
  if (pgp->pgin) {
    (pgp->pgin)(pgp->pgcookie, bp->pgno, bp->page);
  }
  return 0;
}
static int _ffdb_pagepool_load_new_page ( ffdb_pagepool_t * pgp , pgno_t pageno , unsigned int flags , void * * mem ) { int status , nbytes ; off_t off ; struct _ffdb_hqh * head ; ffdb_bkt_t * bp = 0 ; 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 " , pageno ) ; abort ( ) ; } off = ( off_t ) pgp -> pagesize * ( pageno ) ; if ( lseek ( pgp -> fd , off , SEEK_SET ) != off ) { fprintf ( stderr , " \n " ) ; return errno ; } nbytes = read ( pgp -> fd , bp -> page , pgp -> pagesize ) ; if ( nbytes != pgp -> pagesize && nbytes > 0 ) { fprintf ( stderr , " \n " ) ; return errno ; } else if ( nbytes == 0 ) memset ( bp -> page , 0 , pgp -> pagesize ) ; #ifdef _FFDB_STATISTICS ++ pgp -> pageread ; #endif bp -> pgno = pageno ; bp -> owner = FFDB_THREAD_ID ; bp -> ref = 1 ; bp -> waiters = 0 ; 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 ) ; * mem = bp -> page ; 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 ) ; #if 0 fprintf ( stderr , " \n " , bp -> pgno ) ; #endif if ( pgp -> pgin ) { ( pgp -> pgin ) ( pgp -> pgcookie , bp -> pgno , bp -> page ) ; } return 0 ; }
Get a new page from the back source file
Get a new page from the back source file
/**
   * 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 */ /* This has to be successful. This is a new page */ /**
   * The obtained bucket has pinned flag set, we own this page.
   * It is time to populate this page using back file
   */ /* Set page number */ /* Change flags of this page since I own this page now */ /* insert this page into LRU and hash bucket */ /**
   * Check whether page in callback routine 
   */