📄 index.c
字号:
/*** Copyright (c) 1995-2001 Hughes Technologies Pty Ltd. All rights** reserved. **** Terms under which this software may be used or copied are** provided in the specific license associated with this product.**** Hughes Technologies disclaims all warranties with regard to this ** software, including all implied warranties of merchantability and ** fitness, in no event shall Hughes Technologies be liable for any ** special, indirect or consequential damages or any damages whatsoever ** resulting from loss of use, data or profits, whether in an action of ** contract, negligence or other tortious action, arising out of or in ** connection with the use or performance of this software.****** $Id: index.c,v 1.10 2002/12/05 04:23:25 bambi Exp $***//*** Module : main : table** Purpose : ** Exports : ** Depends Upon : *//**************************************************************************** STANDARD INCLUDES**************************************************************************/#include <common/config.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#ifdef HAVE_STRING_H# include <string.h>#endif#ifdef HAVE_STRINGS_H# include <strings.h>#endif/**************************************************************************** MODULE SPECIFIC INCLUDES**************************************************************************/#include <fcntl.h>#include <errno.h>#include <common/msql_defs.h>#include <common/debug/debug.h>#include <common/config/config.h>#include <msqld/index/index.h>#include <msqld/includes/errmsg.h>#include <msqld/includes/msqld.h>#include <msqld/main/main.h>#include <msqld/main/index.h>#include <msqld/main/table.h>#include <msqld/main/parse.h>#include <msqld/main/memory.h>#include <msqld/main/compare.h>#include <common/types/types.h>#include <libmsql/msql.h>/**************************************************************************** GLOBAL VARIABLES**************************************************************************/extern char errMsg[];/**************************************************************************** PRIVATE ROUTINES**************************************************************************/static int _fillIndexBuffer(index,newFields, oldFields) mIndex_t *index; mField_t *newFields, *oldFields;{ char *cp; int count, fieldID; mField_t *curField; cp = index->buf; if (index->idxType != IDX_INT && index->idxType != IDX_UINT && index->idxType != IDX_REAL) { bzero(cp, index->length + 1); } count = 0; while(index->fields[count] != -1) { fieldID = index->fields[count]; curField = newFields; while(curField) { if (curField->fieldID == fieldID) break; curField = curField->next; } if (!curField) { curField = oldFields; while(curField) { if (curField->fieldID == fieldID) break; curField = curField->next; } } if (!curField) { /* missing field index field. Trapped later */ return(-1); } if (parseCopyValue(cp,curField->value,curField->type, curField->length,0) < 0) { snprintf(errMsg,MAX_ERR_MSG,NULL_JOIN_COND_ERR, curField->name); return(-1); } cp += curField->length; count++; } return(0);}static int _compareIndexValues(val1,val2) mVal_t *val1, *val2;{ int res = 0; switch(typeBaseType(val1->type)) { case CHAR_TYPE: res = strcmp(val1->val.charVal,val2->val.charVal); res = res == 0; break; case BYTE_TYPE: res = localByteCmp(val1->val.byteVal,val2->val.byteVal, typeFieldSize(val1->type)); res = res == 0; break; case INT_TYPE: case UINT_TYPE: res = val1->val.intVal == val2->val.intVal; break;#ifdef HUGE_T case INT64_TYPE: case UINT64_TYPE: res = val1->val.int64Val == val2->val.int64Val; break;#endif case REAL_TYPE: res = val1->val.realVal == val2->val.realVal; break; } return(res);}/**************************************************************************** PUBLIC ROUTINES**************************************************************************/void indexCloseIndices(entry) cache_t *entry;{ mIndex_t *cur, *prev; cur = entry->indices; while(cur) { idxClose(&cur->handle); if (cur->buf) { free(cur->buf); cur->buf = NULL; } prev = cur; cur = cur->next; free(prev); }}mIndex_t *indexLoadIndices(server, table,db) msqld *server; char *table, *db;{ mIndex_t *headIndex = NULL, *tmpIndex, *prevIndex, *curIndex, buf; char path[MSQL_PATH_LEN]; int numBytes, count, fd; debugTrace(TRACE_IN,"loadIndices()"); (void)snprintf(path,MSQL_PATH_LEN,"%s/%s/%s.idx", server->config.dbDir, db,table); fd = open(path, O_RDWR | O_CREAT, 0600); if (fd < 0) { snprintf(errMsg,MAX_ERR_MSG, "Can't open index definition for '%s'",table); msqlDebug0(MOD_ERR,errMsg); debugTrace(TRACE_OUT,"loadIndices()"); return(NULL); } numBytes = read(fd,&buf,sizeof(buf)); count = 0; while(numBytes > 0) { if (numBytes < sizeof(buf)) { snprintf(errMsg,MAX_ERR_MSG, TABLE_READ_ERROR,table, (char*)strerror(errno)); msqlDebug1(MOD_ERR, "Error reading \"%s\" index definition\n", table); close(fd); debugTrace(TRACE_OUT,"loadIndices()"); return(NULL); } curIndex = (mIndex_t *)malloc(sizeof(mIndex_t)); bcopy(&buf, curIndex, sizeof(mIndex_t)); if (!headIndex) { headIndex = prevIndex = curIndex; curIndex->next = NULL; } else { /* ensure the list is sorted by DESC field count */ tmpIndex = headIndex; prevIndex = NULL; while(tmpIndex) { if (curIndex->fieldCount > tmpIndex->fieldCount) { curIndex->next = tmpIndex; if (prevIndex) prevIndex->next=curIndex; else headIndex = curIndex; break; } prevIndex = tmpIndex; tmpIndex = tmpIndex->next; } if (!tmpIndex) { prevIndex->next = curIndex; curIndex->next = NULL; } } snprintf(path,MSQL_PATH_LEN,"%s/%s/%s.idx-%s", server->config.dbDir,db,table, curIndex->name); idxOpen(path, curIndex->idxType, &curIndex->environ, &curIndex->handle); curIndex->buf = (char *)malloc(curIndex->length + 1); numBytes = read(fd,&buf,sizeof(buf)); count++; } close(fd); debugTrace(TRACE_OUT,"loadIndices()"); return(headIndex);}int indexInsertIndexValue(entry,fields,pos,index) cache_t *entry; mField_t *fields; u_int pos; mIndex_t *index;{ int res; if (pos == NO_POS) pos = entry->sblk->numRows; if(_fillIndexBuffer(index,fields,NULL) < 0) { return(-1); } res = idxInsert(&index->handle, index->buf, index->length,(off_t)pos); if (res < 0) return(-1); return(0);}int indexInsertIndices(entry,fields,pos) cache_t *entry; mField_t *fields; u_int pos;{ mIndex_t *curIndex; curIndex = entry->indices; while(curIndex) { if (indexInsertIndexValue(entry,fields,pos,curIndex) < 0) return(-1); curIndex = curIndex->next; } return(0);}/****************************************************************************** _deleteIndices**** Purpose : ** Args : ** Returns : ** Notes : */int indexDeleteIndices(entry,fields,pos) cache_t *entry; mField_t *fields; u_int pos;{ mIndex_t *curIndex; int res; if (pos == NO_POS) pos = entry->sblk->numRows; curIndex = entry->indices; while(curIndex) { if (_fillIndexBuffer(curIndex,fields,NULL) < 0) return(-1); res = idxDelete(&curIndex->handle, curIndex->buf, curIndex->length, (off_t)pos); if (res < 0) return(-1); curIndex = curIndex->next; } return(0);}/****************************************************************************** _updateIndices**** Purpose : ** Args : ** Returns : ** Notes : */int indexUpdateIndices(entry,oldFields,pos,row,flist,updated,candIdx,query) cache_t *entry; mField_t *oldFields; u_int pos; row_t *row; int *flist, *updated, candIdx; mQuery_t *query;{ mIndex_t *curIndex; int count, offset, idxCount, needUpdate; mField_t *newFields = NULL, *newTail = NULL, *newCur, *oldCur; /* ** Create a duplicate field list for the complete row containing ** the new values */ oldCur = oldFields; while(oldCur) { newCur = memMallocField(); bcopy(oldCur,newCur,sizeof(mField_t)); newCur->value = NULL; if (!newFields) { newFields = newTail = newCur; newFields->next = NULL; } else { newTail->next = newCur; newTail = newCur; } oldCur = oldCur->next; } tableExtractValues(entry, row, newFields, flist, query); /* ** Work through the indices */ idxCount = 0; *updated = 0; curIndex = entry->indices; while(curIndex) { /* ** Do we need to update this index? */ count = 0; needUpdate = 0; while(curIndex->fields[count] != -1) { offset = curIndex->fields[count]; oldCur = oldFields; newCur = newFields; while(offset) { oldCur = oldCur->next; newCur = newCur->next; offset--; } if (_compareIndexValues(oldCur->value,newCur->value)!=1) { needUpdate = 1; break; } count++; } if (!needUpdate) { /* Skip this index */ curIndex = curIndex->next; idxCount++; continue; } if (idxCount == candIdx) *updated = 1; if (_fillIndexBuffer(curIndex,oldFields,NULL) < 0) return(-1); if (idxDelete(&curIndex->handle, curIndex->buf, curIndex->length, (off_t)pos) < 0) return(-1); if (_fillIndexBuffer(curIndex,newFields,NULL) < 0) return(-1); if (idxInsert(&curIndex->handle, curIndex->buf, curIndex->length, (off_t)pos) < 0) return(-1); curIndex = curIndex->next; idxCount++; } /* ** Free up the duplicatate field list and return */ newCur = newFields; while(newCur) { newCur = newCur->next; parseFreeValue(newFields->value); newFields->value = NULL; memFreeField(newFields); newFields = newCur; } return(0);}int indexCheckIndex(entry, newFields, oldFields, index, rowNum) cache_t *entry; mField_t *newFields, *oldFields; mIndex_t *index; u_int rowNum;{ idx_nod node; u_int curRow; /* ** If it's a non-unique index, just bail */ if (!index->unique) return(1); /* ** Try to read the index value and bail if it's there */ if(_fillIndexBuffer(index,newFields,oldFields) < 0) return(-1); if (idxLookup(&index->handle, index->buf, index->length, IDX_EXACT, &node) == IDX_OK) { curRow = (u_int)node.data; if (curRow != rowNum) return(0); } return(1);}int indexCheckIndices(entry, newFields, oldFields, rowNum) cache_t *entry; mField_t *newFields, *oldFields; u_int rowNum;{ mIndex_t *curIndex; curIndex = entry->indices; while(curIndex) { if (indexCheckIndex(entry, newFields, oldFields, curIndex, rowNum)==0) { return(0); } curIndex = curIndex->next; } return(1);}int indexCheckNullFields(entry,row,index,flist) cache_t *entry; row_t *row; mIndex_t *index; int *flist;{ mField_t *curField; int *offset, count, field; u_char *data; debugTrace(TRACE_IN,"checkIndexNullFields()"); data = row->data; for (count=0; count<5; count++) { offset = 0; field = index->fields[count]; if(field == -1) { break; } curField = entry->def; offset = flist; while(curField && field) { offset++; curField = curField->next; field--; } if (!*(data + *offset)) { snprintf(errMsg,MAX_ERR_MSG, NULL_INDEX_ERROR, curField->name); debugTrace(TRACE_OUT,"checkIndexNullFields()"); return(-1); } } debugTrace(TRACE_OUT,"checkIndexNullFields()"); return(0);}int indexCheckAllForNullFields(entry,row, flist) cache_t *entry; row_t *row; int *flist;{ mIndex_t *curIndex; u_char *data; debugTrace(TRACE_IN,"indexCheckAllForNullFields()"); curIndex = entry->indices; data = row->data; while(curIndex) { if (indexCheckNullFields(entry,row,curIndex,flist) < 0) { debugTrace(TRACE_OUT,"indexCheckAllForNullFields()"); return(-1); } curIndex = curIndex->next; } debugTrace(TRACE_OUT,"indexCheckAllForNullFields()"); return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -