void BufWrite(int blkno, void* pData) { Buf* find = BufFind(blkno); Buf* pNewBuf; // HIT if (find != NULL) { if (find->state == BUF_STATE_CLEAN && find->state != -1) { // Move to Dirty list. find->state = BUF_STATE_DIRTY; BufDeleteBuf(find); BufInsertToTail(find, blkno, BUF_LIST_DIRTY); } LruInsert(find); memmove(find->pMem, pData, strlen(pData) + 1); } // MISS else { // Create New Buffer pNewBuf = BufGetNewBuffer(); pNewBuf->blkno = blkno; pNewBuf->state = BUF_STATE_DIRTY; BufInsertToTail(pNewBuf, pNewBuf->blkno, BUF_LIST_DIRTY); LruInsert(pNewBuf); memmove(pNewBuf->pMem, pData, strlen(pData) + 1); } }
/* returns 0 on success, -1 on re-open failure (with errno set) */ static int FileAccess(File file) { int returnValue; DO_DB(elog(LOG, "FileAccess %d (%s)", file, VfdCache[file].fileName)); /* * Is the file open? If not, open it and put it at the head of the LRU * ring (possibly closing the least recently used file to get an FD). */ if (FileIsNotOpen(file)) { returnValue = LruInsert(file); if (returnValue != 0) return returnValue; } else if (VfdCache[0].lruLessRecently != file) { /* * We now know that the file is open and that it is not the last one * accessed, so we need to move it to the head of the Lru ring. */ Delete(file); Insert(file); } return 0; }
// MRU 갱신 void LruInsert (Buf* pBuf) { // 이미 있는 Buf가 MRU가 되어 다시 들어오는 경우. Buf* find = LruFind(pBuf->blkno); if (find != NULL) { // 이미 들어와있던 이 Buf가 LRU이자 MRU인 경우 if (find == pLruListHead && find == pLruListTail) { // 그대로 두면 되므로 return; } // 이미 들어와있던 이 Buf가 MRU인 경우 else if (find == pLruListTail) { // 그대로 두면 되므로 return; } // 이미 들어와있던 이 Buf가 LRU인 경우 else if (find == pLruListHead) { find->plNext->plPrev = NULL; pLruListHead = find->plNext; LruInsert(find); // Recursive } else { find->plNext->plPrev = find->plPrev; find->plPrev->plNext = find->plNext; LruInsert(find); // Recursive } } else { // 새로운 Buf가 들어온 경우. if (pLruListHead == NULL) { // 리스트가 비어있는 경우. pBuf->plPrev = NULL; pBuf->plNext = NULL; pLruListHead = pBuf; pLruListTail = pBuf; } else { pLruListTail->plNext = pBuf; pBuf->plPrev = pLruListTail; pBuf->plNext = NULL; pLruListTail = pBuf; } } }
void BufRead(int blkno, void* pData) { Buf* find = BufFind(blkno); Buf* pNewBuf; // HIT if (find != NULL) { LruInsert(find); //pData = find->pMem; memmove(pData, find->pMem, strlen(find->pMem) + 1); } // MISS else { // Create New Buffer pNewBuf = BufGetNewBuffer(); pNewBuf->blkno = blkno; pNewBuf->state = BUF_STATE_CLEAN; DevReadBlock(blkno, pNewBuf->pMem); BufInsertToTail(pNewBuf, pNewBuf->blkno, BUF_LIST_CLEAN); LruInsert(pNewBuf); memmove(pData, pNewBuf->pMem, strlen(pNewBuf->pMem) + 1); } }
/* VARARGS2 */ static File fileNameOpenFile(FileName fileName, int fileFlags, int fileMode) { static int osRanOut = 0; File file; Vfd *vfdP; int tmpfd; DO_DB(printf("DEBUG: FileNameOpenFile: %s %x %o\n", fileName, fileFlags, fileMode)); file = AllocateVfd(); vfdP = &VfdCache[file]; if (nfile >= MAXFILES || (FreeFd == 0 && osRanOut)) { AssertLruRoom(); } tryAgain: tmpfd = open(Nulldev, O_CREAT|O_RDWR, 0666); if (tmpfd < 0) { DO_DB(printf("DB: not enough descs, retry, er= %d\n", errno)); errno = 0; FreeFd = 0; osRanOut = 1; AssertLruRoom(); goto tryAgain; } else { close(tmpfd); } #ifdef WIN32 fileFlags |= _O_BINARY; #endif /* WIN32 */ vfdP->fd = open(fileName,fileFlags,fileMode); vfdP->fdstate = 0x0; if (vfdP->fd < 0) { FreeVfd(file); return -1; } ++nfile; DO_DB(printf("DB: FNOF success %d\n", vfdP->fd)); (void)LruInsert(file); if (fileName==NULL) { elog(WARN, "fileNameOpenFile: NULL fname"); } vfdP->fileName = malloc(strlen(fileName)+1); strcpy(vfdP->fileName,fileName); vfdP->fileFlags = fileFlags & ~(O_TRUNC|O_EXCL); vfdP->fileMode = fileMode; vfdP->seekPos = 0; return file; }
static char * filepath(char *filename) { char *buf; char basename[16]; int len; #ifndef WIN32 if (*filename != Sep_char) { #else if (!(filename[1] == ':' && filename[2] == Sep_char)) { #endif /* WIN32 */ /* Either /base/ or \base\ */ sprintf(basename, "%cbase%c", Sep_char, Sep_char); len = strlen(DataDir) + strlen(basename) + strlen(GetDatabaseName()) + strlen(filename) + 2; buf = (char*) palloc(len); sprintf(buf, "%s%s%s%c%s", DataDir, basename, GetDatabaseName(), Sep_char, filename); } else { buf = (char *) palloc(strlen(filename) + 1); strcpy(buf, filename); } return(buf); } static int FileAccess(File file) { int returnValue; DO_DB(printf("DB: FileAccess %d (%s)\n", file, VfdCache[file].fileName)); /* * Is the file open? If not, close the least recently used, * then open it and stick it at the head of the used ring */ if (FileIsNotOpen(file)) { AssertLruRoom(); returnValue = LruInsert(file); if (returnValue != 0) return returnValue; } else { /* * We now know that the file is open and that it is not the * last one accessed, so we need to more it to the head of * the Lru ring. */ Delete(file); Insert(file); } return (0); }