15b0a1dc9Sbostic /*- 2*3cd9f84aSbostic * Copyright (c) 1991, 1993 3*3cd9f84aSbostic * The Regents of the University of California. All rights reserved. 45b0a1dc9Sbostic * 55b0a1dc9Sbostic * %sccs.include.redist.c% 65b0a1dc9Sbostic * 7*3cd9f84aSbostic * @(#)mpool.h 8.1 (Berkeley) 06/02/93 85b0a1dc9Sbostic */ 95b0a1dc9Sbostic 105b0a1dc9Sbostic /* 115b0a1dc9Sbostic * The memory pool scheme is a simple one. Each in memory page is referenced 125b0a1dc9Sbostic * by a bucket which is threaded in three ways. All active pages are threaded 135b0a1dc9Sbostic * on a hash chain (hashed by the page number) and an lru chain. Inactive 145b0a1dc9Sbostic * pages are threaded on a free chain. Each reference to a memory pool is 155b0a1dc9Sbostic * handed an MPOOL which is the opaque cookie passed to all of the memory 165b0a1dc9Sbostic * routines. 175b0a1dc9Sbostic */ 185b0a1dc9Sbostic #define HASHSIZE 128 195b0a1dc9Sbostic #define HASHKEY(pgno) ((pgno - 1) % HASHSIZE) 205b0a1dc9Sbostic 215b0a1dc9Sbostic /* The BKT structures are the elements of the lists. */ 225b0a1dc9Sbostic typedef struct BKT { 235b0a1dc9Sbostic struct BKT *hnext; /* next hash bucket */ 245b0a1dc9Sbostic struct BKT *hprev; /* previous hash bucket */ 255b0a1dc9Sbostic struct BKT *cnext; /* next free/lru bucket */ 265b0a1dc9Sbostic struct BKT *cprev; /* previous free/lru bucket */ 275b0a1dc9Sbostic void *page; /* page */ 285b0a1dc9Sbostic pgno_t pgno; /* page number */ 295b0a1dc9Sbostic 305b0a1dc9Sbostic #define MPOOL_DIRTY 0x01 /* page needs to be written */ 315b0a1dc9Sbostic #define MPOOL_PINNED 0x02 /* page is pinned into memory */ 325b0a1dc9Sbostic unsigned long flags; /* flags */ 335b0a1dc9Sbostic } BKT; 345b0a1dc9Sbostic 355b0a1dc9Sbostic /* The BKTHDR structures are the heads of the lists. */ 365b0a1dc9Sbostic typedef struct BKTHDR { 375b0a1dc9Sbostic struct BKT *hnext; /* next hash bucket */ 385b0a1dc9Sbostic struct BKT *hprev; /* previous hash bucket */ 395b0a1dc9Sbostic struct BKT *cnext; /* next free/lru bucket */ 405b0a1dc9Sbostic struct BKT *cprev; /* previous free/lru bucket */ 415b0a1dc9Sbostic } BKTHDR; 425b0a1dc9Sbostic 435b0a1dc9Sbostic typedef struct MPOOL { 445b0a1dc9Sbostic BKTHDR free; /* The free list. */ 455b0a1dc9Sbostic BKTHDR lru; /* The LRU list. */ 465b0a1dc9Sbostic BKTHDR hashtable[HASHSIZE]; /* Hashed list by page number. */ 475b0a1dc9Sbostic pgno_t curcache; /* Current number of cached pages. */ 485b0a1dc9Sbostic pgno_t maxcache; /* Max number of cached pages. */ 495b0a1dc9Sbostic pgno_t npages; /* Number of pages in the file. */ 503c3a101cSbostic u_long pagesize; /* File page size. */ 515b0a1dc9Sbostic int fd; /* File descriptor. */ 525b0a1dc9Sbostic /* Page in conversion routine. */ 535b0a1dc9Sbostic void (*pgin) __P((void *, pgno_t, void *)); 545b0a1dc9Sbostic /* Page out conversion routine. */ 555b0a1dc9Sbostic void (*pgout) __P((void *, pgno_t, void *)); 565b0a1dc9Sbostic void *pgcookie; /* Cookie for page in/out routines. */ 575b0a1dc9Sbostic #ifdef STATISTICS 585b0a1dc9Sbostic unsigned long cachehit; 595b0a1dc9Sbostic unsigned long cachemiss; 605b0a1dc9Sbostic unsigned long pagealloc; 615b0a1dc9Sbostic unsigned long pageflush; 625b0a1dc9Sbostic unsigned long pageget; 635b0a1dc9Sbostic unsigned long pagenew; 645b0a1dc9Sbostic unsigned long pageput; 655b0a1dc9Sbostic unsigned long pageread; 665b0a1dc9Sbostic unsigned long pagewrite; 675b0a1dc9Sbostic #endif 685b0a1dc9Sbostic } MPOOL; 695b0a1dc9Sbostic 705b0a1dc9Sbostic #ifdef __MPOOLINTERFACE_PRIVATE 715b0a1dc9Sbostic /* Macros to insert/delete into/from hash chain. */ 725b0a1dc9Sbostic #define rmhash(bp) { \ 735b0a1dc9Sbostic (bp)->hprev->hnext = (bp)->hnext; \ 745b0a1dc9Sbostic (bp)->hnext->hprev = (bp)->hprev; \ 755b0a1dc9Sbostic } 765b0a1dc9Sbostic #define inshash(bp, pg) { \ 775b0a1dc9Sbostic hp = &mp->hashtable[HASHKEY(pg)]; \ 785b0a1dc9Sbostic (bp)->hnext = hp->hnext; \ 795b0a1dc9Sbostic (bp)->hprev = (struct BKT *)hp; \ 805b0a1dc9Sbostic hp->hnext->hprev = (bp); \ 815b0a1dc9Sbostic hp->hnext = (bp); \ 825b0a1dc9Sbostic } 835b0a1dc9Sbostic 845b0a1dc9Sbostic /* Macros to insert/delete into/from lru and free chains. */ 855b0a1dc9Sbostic #define rmchain(bp) { \ 865b0a1dc9Sbostic (bp)->cprev->cnext = (bp)->cnext; \ 875b0a1dc9Sbostic (bp)->cnext->cprev = (bp)->cprev; \ 885b0a1dc9Sbostic } 895b0a1dc9Sbostic #define inschain(bp, dp) { \ 905b0a1dc9Sbostic (bp)->cnext = (dp)->cnext; \ 915b0a1dc9Sbostic (bp)->cprev = (struct BKT *)(dp); \ 925b0a1dc9Sbostic (dp)->cnext->cprev = (bp); \ 935b0a1dc9Sbostic (dp)->cnext = (bp); \ 945b0a1dc9Sbostic } 955b0a1dc9Sbostic #endif 965b0a1dc9Sbostic 975b0a1dc9Sbostic __BEGIN_DECLS 985b0a1dc9Sbostic MPOOL *mpool_open __P((DBT *, int, pgno_t, pgno_t)); 995b0a1dc9Sbostic void mpool_filter __P((MPOOL *, void (*)(void *, pgno_t, void *), 1005b0a1dc9Sbostic void (*)(void *, pgno_t, void *), void *)); 1015b0a1dc9Sbostic void *mpool_new __P((MPOOL *, pgno_t *)); 1025b0a1dc9Sbostic void *mpool_get __P((MPOOL *, pgno_t, u_int)); 1035b0a1dc9Sbostic int mpool_put __P((MPOOL *, void *, u_int)); 1045b0a1dc9Sbostic int mpool_sync __P((MPOOL *)); 1055b0a1dc9Sbostic int mpool_close __P((MPOOL *)); 1065b0a1dc9Sbostic #ifdef STATISTICS 1075b0a1dc9Sbostic void mpool_stat __P((MPOOL *)); 1085b0a1dc9Sbostic #endif 1095b0a1dc9Sbostic __END_DECLS 110