网站开发违法/360网站安全检测
我个人的理解:其实质,和Java里的Hash表有点类似。在C语言中是为了解决数组无法扩展的缺陷。
例子:
看 PostgreSQL对 VFD的处理:
初始化:
/** Virtual File Descriptor array pointer and size. This grows as* needed. 'File' values are indexes into this array.* Note that VfdCache[0] is not a usable VFD, just a list header.*/ static Vfd *VfdCache; static Size SizeVfdCache = 0;
/** InitFileAccess --- initialize this module during backend startup** This is called during either normal or standalone backend start.* It is *not* called in the postmaster.*/ void InitFileAccess(void) {Assert(SizeVfdCache == 0); /* call me only once *//* initialize cache header entry *////#### VfdCache = (Vfd *) malloc(sizeof(Vfd));if (VfdCache == NULL)ereport(FATAL,(errcode(ERRCODE_OUT_OF_MEMORY),errmsg("out of memory")));MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));VfdCache->fd = VFD_CLOSED;SizeVfdCache = 1;/* register proc-exit hook to ensure temp files are dropped at exit */on_proc_exit(AtProcExit_Files, 0); }
扩展:
static File AllocateVfd(void) {Index i;File file;DO_DB(elog(LOG, "AllocateVfd. Size %lu", SizeVfdCache));Assert(SizeVfdCache > 0); /* InitFileAccess not called? */if (VfdCache[0].nextFree == 0){/** The free list is empty so it is time to increase the size of the* array. We choose to double it each time this happens. However,* there's not much point in starting *real* small.*/Size newCacheSize = SizeVfdCache * 2;Vfd *newVfdCache;if (newCacheSize < 32)newCacheSize = 32;////####/** Be careful not to clobber VfdCache ptr if realloc fails.*/newVfdCache = (Vfd *) realloc(VfdCache, sizeof(Vfd) * newCacheSize);if (newVfdCache == NULL)ereport(ERROR,(errcode(ERRCODE_OUT_OF_MEMORY),errmsg("out of memory")));VfdCache = newVfdCache;/** Initialize the new entries and link them into the free list.*/for (i = SizeVfdCache; i < newCacheSize; i++){MemSet((char *) &(VfdCache[i]), 0, sizeof(Vfd));VfdCache[i].nextFree = i + 1;VfdCache[i].fd = VFD_CLOSED;}VfdCache[newCacheSize - 1].nextFree = 0;VfdCache[0].nextFree = SizeVfdCache;/** Record the new size*/SizeVfdCache = newCacheSize;}file = VfdCache[0].nextFree;VfdCache[0].nextFree = VfdCache[file].nextFree;return file; }