📄 table.c
字号:
char *db;{ char path[MSQL_PATH_LEN]; (void)snprintf(path, MSQL_PATH_LEN,"%s/%s/%s.ofl", server->config.dbDir,db, table); return(open(path,O_RDWR|O_CREAT, 0600));}int tableWriteFreeList(cacheEntry, pos, entry) cache_t *cacheEntry; u_int pos, entry;{ off_t seekPos; char *buf; seekPos = pos * (cacheEntry->rowLen + HEADER_SIZE) + SBLK_SIZE + HEADER_SIZE; buf = ((char *)cacheEntry->dataMap) + seekPos; bcopy(&entry,buf,sizeof(entry)); return(0);}u_int tableReadFreeList(cacheEntry,pos) cache_t *cacheEntry; u_int pos;{ off_t seekPos; char *buf; u_int entry; seekPos = pos * (cacheEntry->rowLen + HEADER_SIZE) + SBLK_SIZE + HEADER_SIZE; buf = ((char *)cacheEntry->dataMap) + seekPos; bcopy(buf, &entry, sizeof(entry)); return(entry);}/****************************************************************************** _popBlankPos**** Purpose : Pop the localtion of a hole from the table's free list** Args : Database and table names** Returns : Offset off hole, NO_POS if the free list is empty** Notes : */u_int tablePopBlankPos(cacheEntry,db,table) cache_t *cacheEntry; char *db, *table;{ u_int pos; sblk_t *sblkPtr; debugTrace(TRACE_IN,"popBlankPos()"); sblkPtr = (sblk_t *)cacheEntry->dataMap; if (!sblkPtr) return(NO_POS); pos = sblkPtr->freeList; if (pos != NO_POS) { sblkPtr->freeList = tableReadFreeList(cacheEntry, sblkPtr->freeList); } return(pos);}/****************************************************************************** _pushBlankPos**** Purpose : Store the location of a data hole ** Args : database and table names** offset for the hole.** Returns : -1 on error** Notes : */int tablePushBlankPos(cacheEntry,db,table,pos) cache_t *cacheEntry; char *db, *table; u_int pos;{ sblk_t *sblkPtr; debugTrace(TRACE_IN,"pushBlankPos()"); sblkPtr = (sblk_t *)cacheEntry->dataMap; if (sblkPtr->freeList == NO_POS) { if (tableWriteFreeList(cacheEntry,pos,NO_POS) < 0) { return(-1); } } else { if (tableWriteFreeList(cacheEntry,pos,sblkPtr->freeList) < 0) { return(-1); } } sblkPtr->freeList = pos; return(0);}/****************************************************************************** _tableFreeDefinition**** Purpose : Free memory used by a table def** Args : pointer to table def** Returns : Nothing** Notes : */void tableFreeDefinition(tableDef) mField_t *tableDef;{ mField_t *curField, *prevField; debugTrace(TRACE_IN,"tableFreeDefinition()"); curField = tableDef; while(curField) { if (curField->value) { parseFreeValue(curField->value); curField->value = NULL; } prevField = curField; curField = curField->next; prevField->next = NULL; memFreeField(prevField); } debugTrace(TRACE_OUT,"tableFreeDefinition()");}void tableCleanTmpDir(server) msqld *server;{#ifdef HAVE_DIRENT_H struct dirent *cur;#else struct direct *cur;#endif DIR *dirp; char *dbDir, path[MSQL_PATH_LEN]; if (server) dbDir = server->config.dbDir; else dbDir = configGetCharEntry("general", "db_dir"); (void)snprintf(path,MSQL_PATH_LEN,"%s/.tmp", dbDir); dirp = opendir(path); if (!dirp) { /* Can't report this. It'll be trapped later */ return; } /* ** Blow away any files skipping . and .. */ cur = readdir(dirp); while(cur) { if (*cur->d_name == '.') { cur = readdir(dirp); continue; } (void)snprintf(path,MSQL_PATH_LEN,"%s/.tmp/%s",dbDir, cur->d_name); unlink(path); cur = readdir(dirp); } closedir(dirp); return;}cache_t *tableCreateTmpTable(server, db, name, table1,table2,fields, flag) msqld *server; char *db, *name; cache_t *table1, *table2; mField_t *fields; int flag;{ cache_t *new; char path[MSQL_PATH_LEN], *tmpfile = NULL, *tmpStr = NULL, *cp = NULL; /* ** Create a name for this tmp table if we need to */ debugTrace(TRACE_IN,"createTmpTable()"); if (name) { strcpy(path,name); snprintf(path,MSQL_PATH_LEN,"%s/%s/%s.dat", server->config.dbDir, db, name); } else { tmpStr = tmpfile = (char *)msql_tmpnam(NULL);#if defined(_OS_OS2) cp = (char *)rindex(tmpfile,'\\'); if (cp) { tmpfile = cp+1; }#endif cp = (char *)rindex(tmpfile,'/'); if (cp) { tmpfile = cp+1; } snprintf(path,MSQL_PATH_LEN,"%s/.tmp/%s.dat", server->config.dbDir, tmpfile); } new = _createTargetTable(path,tmpfile,table1,table2,fields,flag); debugTrace(TRACE_OUT,"createTmpTable()"); free(tmpStr); return(new);}cache_t *tableCreateDestTable(server, db, name, table, fields) msqld *server; char *db, *name; cache_t *table; mField_t *fields;{ cache_t *new; char path[MSQL_PATH_LEN]; snprintf(path,MSQL_PATH_LEN,"%s/%s/%s.dat", server->config.dbDir, db, name); new = _createTargetTable(path,name,table, NULL, fields, 0); return(new);}void tableFreeTmpTable(server, entry) msqld *server; cache_t *entry;{ char path[MSQL_PATH_LEN]; debugTrace(TRACE_IN,"freeTmpTable()"); (void)snprintf(path,MSQL_PATH_LEN, "%s/.tmp/%s.dat", server->config.dbDir, entry->table); tableFreeDefinition(entry->def); entry->def = NULL; *(entry->db) = 0; *(entry->table) = 0; *(entry->cname) = 0; entry->age = 0; free(entry->row.buf); entry->row.buf = NULL; if (entry->dataMap != (caddr_t) NULL && (entry->size > 0)) { munmap(entry->dataMap,entry->size); } entry->dataMap = NULL; entry->size = 0; close(entry->dataFD); indexCloseIndices(entry); (void)free(entry); unlink(path); debugTrace(TRACE_OUT,"freeTmpTable()");}/****************************************************************************** _tableLoadDefinition**** Purpose : Locate a table definition** Args : Database and Table names** Returns : -1 on error** Notes : Table description cache searched first. If it's not** there, the LRU entry is freed and the table def is** loaded into the cache. The tableDef, ** cacheEntry and dataFD globals are set.*/cache_t *tableLoadDefinition(server, table,cname,db) msqld *server; char *table, *cname, *db;{ int maxAge, cacheIndex; mField_t *def, *curField; cache_t *entry; int count; char *tableName; /* ** Look for the entry in the cache. Keep track of the oldest ** entry during the pass so that we can replace it if needed */ debugTrace(TRACE_IN,"tableLoadDefinition()"); msqlDebug2(MOD_CACHE,"Table cache search for %s:%s\n",table,db); count = cacheIndex = 0; maxAge = -1; if (cname) { if (!*cname) { cname = NULL; } } while(count < server->config.tableCache) { entry = &tableCache[count]; msqlDebug5(MOD_CACHE,"Cache entry %d = %s:%s, age = %d (%s)\n", count, entry->table?entry->table:"NULL", entry->db?entry->db:"NULL", entry->age, entry->def?"OK":"NULL Def!!!"); if (entry->age > 0 && *entry->db == *db) { if (strcmp(entry->db,db)==0 && strcmp(entry->table,table)==0 && strcmp((cname)?cname:"",entry->cname)==0) { msqlDebug1(MOD_CACHE,"Found cache entry at %d\n" , count); entry->age = 1; debugTrace(TRACE_OUT,"tableLoadDefinition()"); return(entry); } } if (entry->age > 0) entry->age++; /* ** Empty entries have an age of 0. If we're marking ** an empty cache position just keep the mark */ if ((entry->age == 0) && (maxAge != 0)) { maxAge = entry->age; cacheIndex = count; } else { if ((entry->age > maxAge) && (maxAge != 0)) { maxAge = entry->age; cacheIndex = count; } } count++; } /* ** It wasn't in the cache. Free up the oldest cache entry */ entry = &tableCache[cacheIndex]; if(entry->def) { msqlDebug3(MOD_CACHE,"Removing cache entry %d (%s:%s)\n", cacheIndex, entry->db, entry->table); if (entry->dataMap != (caddr_t) NULL && entry->size > 0) { MSYNC(entry->dataMap,entry->size,0); munmap(entry->dataMap,entry->size); } entry->dataMap = NULL; entry->size = 0; if (entry->overflowMap != (caddr_t) NULL && entry->overflowSize > 0) { MSYNC(entry->overflowMap,entry->overflowSize,0); munmap(entry->overflowMap,entry->overflowSize); } entry->overflowMap = NULL; entry->overflowSize = 0; (void)close(entry->dataFD); (void)close(entry->overflowFD); indexCloseIndices(entry); tableFreeDefinition(entry->def); entry->def = NULL; *(entry->table)=0; *(entry->db)=0; entry->age=0; free(entry->row.buf); entry->row.buf = NULL; } /* ** Now load the new entry */ *errMsg = 0; if (cname) { tableName = cname; def = _readTableDef(server,cname,table,db); } else { tableName = table; def = _readTableDef(server,table,NULL,db); } if (!def) { if (*errMsg == 0) { snprintf(errMsg, MAX_ERR_MSG,TABLE_READ_ERROR,table, (char*)strerror(errno)); msqlDebug1(MOD_ERR, "Couldn't read table definition for %s\n", table); } debugTrace(TRACE_OUT,"tableLoadDefinition()"); return(NULL); } entry->indices = indexLoadIndices(server, tableName,db); entry->def = def; entry->age = 1; entry->result = 0; entry->dirty = 0; strcpy(entry->db,db); strcpy(entry->table,table); if (cname) { strcpy(entry->cname,cname); } else { *(entry->cname) = 0; } msqlDebug3(MOD_CACHE,"Loading cache entry %d (%s:%s)\n", cacheIndex, entry->db, entry->table); entry->dataFD = tableOpenTable(server, tableName, db); if(entry->dataFD < 0) { indexCloseIndices(entry); tableFreeDefinition(entry->def); entry->def = NULL; *(entry->table)=0; *(entry->db)=0; entry->age=0; snprintf(errMsg, MAX_ERR_MSG, DATA_OPEN_ERROR,tableName, (char *)strerror(errno)); debugTrace(TRACE_OUT,"tableLoadDefinition()"); return(NULL); } entry->overflowFD = tableOpenOverflow(server,tableName,db); if(entry->overflowFD < 0) { close(entry->dataFD); indexCloseIndices(entry); tableFreeDefinition(entry->def); entry->def = NULL; *(entry->table)=0; *(entry->db)=0; entry->age=0; snprintf(errMsg,MAX_ERR_MSG,DATA_OPEN_ERROR,tableName, (char *)strerror(errno)); debugTrace(TRACE_OUT,"tableLoadDefinition()"); return(NULL); } curField = entry->def; while(curField) { curField->entry = entry; curField = curField->next; } /* ** Setup for Mapping the data file */ entry->dataMap = NULL; entry->remapData = 1; entry->overflowMap = NULL; entry->remapOverflow = 1; if (tableInitTable(entry,FULL_REMAP) < 0) { close(entry->overflowFD); close(entry->dataFD); indexCloseIndices(entry); tableFreeDefinition(entry->def); entry->def = NULL; *(entry->table) = 0; *(entry->db) = 0; entry->age = 0; return(NULL); } /* ** Set the globals and bail. We need rowLen + 2 (one for the ** active byte and also one for regexp over-run protection) and ** keyLen + 1 (one for the active byte) buffers for performance. ** Keep rows aligned on 8 byte blocks so mmap() access to the ** headers is OK. */ entry->rowDataLen = findRowLen(entry); entry->rowLen = entry->rowDataLen + (8 - ((entry->rowDataLen + HEADER_SIZE) % 8)); entry->row.buf = (u_char *)malloc(entry->rowLen + HEADER_SIZE + 2); entry->row.header = (hdr_t *)entry->row.buf; entry->row.data = entry->row.buf + HEADER_SIZE; entry->sblk = (sblk_t *)entry->dataMap; debugTrace(TRACE_OUT,"tableLoadDefinition()"); return(entry);}/****************************************************************************** _tableInitTable**** Purpose : Reset table pointers used during query processing** Args : None** Returns : Nothing** Notes : This just puts the file into a known state, particular** the current seek pointers.*/int tableInitTable(cacheEntry,mapFlag) cache_t *cacheEntry; int mapFlag;{ struct stat sbuf; int forcedRemap; debugTrace(TRACE_IN,"tableInitTable()"); forcedRemap = 0; if (cacheEntry->dataMap != NULL && cacheEntry->size != cacheEntry->sblk->dataSize) { forcedRemap = 1; } if ((mapFlag && FULL_REMAP) || forcedRemap) { if (cacheEntry->remapData || forcedRemap) { if (cacheEntry->dataMap && cacheEntry->size) { munmap(cacheEntry->dataMap, cacheEntry->size); } fstat(cacheEntry->dataFD, &sbuf); cacheEntry->size = sbuf.st_size; if (cacheEntry->size) { cacheEntry->dataMap = (caddr_t)mmap(NULL, (size_t)cacheEntry->size, (PROT_READ | PROT_WRITE), MAP_SHARED, cacheEntry->dataFD, (off_t)0); if (cacheEntry->dataMap == (caddr_t)-1) return(-1);#ifdef HAVE_MADVISE madvise(cacheEntry->dataMap, cacheEntry->size, MADV_SEQUENTIAL);#endif cacheEntry->sblk=(sblk_t*)cacheEntry->dataMap; } cacheEntry->remapData = 0; } if ((cacheEntry->remapOverflow || forcedRemap) && (cacheEntry->overflowFD != 0)) { if (cacheEntry->overflowMap && cacheEntry->overflowSize) { munmap(cacheEntry->overflowMap, cacheEntry->overflowSize); } fstat(cacheEntry->overflowFD, &sbuf); cacheEntry->overflowSize = sbuf.st_size; if (cacheEntry->overflowSize) { cacheEntry->overflowMap = (caddr_t)mmap(NULL, (size_t)cacheEntry->overflowSize, (PROT_READ | PROT_WRITE), MAP_SHARED, cacheEntry->overflowFD, (off_t)0); if (cacheEntry->overflowMap == (caddr_t)-1) return(-1);#ifdef HAVE_MADVISE madvise(cacheEntry->overflowMap, cacheEntry->overflowSize, MADV_SEQUENTIAL);#endif } cacheEntry->remapOverflow = 0; } } debugTrace(TRACE_OUT,"tableInitTable()"); return(0);} int tableWriteRow(cacheEntry,row,rowNum, query) cache_t *cacheEntry; row_t *row; u_int rowNum; mQuery_t *query;{ return(_tableWriteRow(cacheEntry,row,rowNum, 1, query));}int tablePlaceRow(cacheEntry,row,rowNum, query) cache_t *cacheEntry; row_t *row; u_int rowNum; mQuery_t *query;{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -