📄 utdatabase.c
字号:
/*---------------------------------------------------------------------------------------- Database ut----------------------------------------------------------------------------------------*/#include "ddutil.h"union utTempType_ utTemp_;struct utRootType_ utRootData;uint8 utModuleID;struct utSymtabFields utSymtabs;struct utSymFields utSyms;struct utDynarrayFields utDynarrays;struct utSymArrayFields utSymArrays;/*---------------------------------------------------------------------------------------- Constructor/Destructor hooks.----------------------------------------------------------------------------------------*/void(*utSymtabConstructorCallback)(utSymtab);void(*utSymConstructorCallback)(utSym);void(*utDynarrayConstructorCallback)(utDynarray);void(*utDynarrayDestructorCallback)(utDynarray);void(*utSymArrayConstructorCallback)(utSymArray);void(*utSymArrayDestructorCallback)(utSymArray);/*---------------------------------------------------------------------------------------- Default constructor wrapper for the database manager.----------------------------------------------------------------------------------------*/static uint64 allocSymtab(void){ utSymtab Symtab = utSymtabAlloc(); return utSymtab2Index(Symtab);}/*---------------------------------------------------------------------------------------- Allocate the field arrays of Symtab.----------------------------------------------------------------------------------------*/static void allocSymtabs(void){ utSetAllocatedSymtab(2); utSetUsedSymtab(0); utSymtabs.TableIndex = utNewA(uint32, (utAllocatedSymtab())); utSymtabs.NumTable = utNewA(uint32, (utAllocatedSymtab())); utSetUsedSymtabTable(0); utSetAllocatedSymtabTable(2); utSetFreeSymtabTable(0); utSymtabs.Table = utNewA(utSym, utAllocatedSymtabTable()); utSymtabs.NumSym = utNewA(uint32, (utAllocatedSymtab()));}/*---------------------------------------------------------------------------------------- Realloc the arrays of properties for class Symtab.----------------------------------------------------------------------------------------*/static void reallocSymtabs( uint32 newSize){ utResizeArray(utSymtabs.TableIndex, (newSize)); utResizeArray(utSymtabs.NumTable, (newSize)); utResizeArray(utSymtabs.NumSym, (newSize)); utSetAllocatedSymtab(newSize);}/*---------------------------------------------------------------------------------------- Allocate more Symtabs.----------------------------------------------------------------------------------------*/void utSymtabAllocMore(void){ reallocSymtabs(utAllocatedSymtab() + (utAllocatedSymtab() >> 1));}/*---------------------------------------------------------------------------------------- Compact the Symtab.Table heap to free memory.----------------------------------------------------------------------------------------*/void utCompactSymtabTables(void){ uint32 elementSize = sizeof(utSym); uint32 usedHeaderSize = (sizeof(utSymtab) + elementSize - 1)/elementSize; uint32 freeHeaderSize = (sizeof(utSymtab) + sizeof(uint32) + elementSize - 1)/elementSize; utSym *toPtr = utSymtabs.Table; utSym *fromPtr = toPtr; utSymtab Symtab; uint32 size; while(fromPtr < utSymtabs.Table + utUsedSymtabTable()) { Symtab = *(utSymtab *)(void *)fromPtr; if(Symtab != utSymtabNull) { /* Need to move it to toPtr */ size = utMax(utSymtabGetNumTable(Symtab) + usedHeaderSize, freeHeaderSize); memmove((void *)toPtr, (void *)fromPtr, size*elementSize); utSymtabSetTableIndex(Symtab, toPtr - utSymtabs.Table + usedHeaderSize); toPtr += size; } else { /* Just skip it */ size = *(uint32 *)(void *)(((utSymtab *)(void *)fromPtr) + 1); } fromPtr += size; } utSetUsedSymtabTable(toPtr - utSymtabs.Table); utSetFreeSymtabTable(0);}/*---------------------------------------------------------------------------------------- Allocate more memory for the Symtab.Table heap.----------------------------------------------------------------------------------------*/static void allocMoreSymtabTables( uint32 spaceNeeded){ uint32 freeSpace = utAllocatedSymtabTable() - utUsedSymtabTable(); if((utFreeSymtabTable() << 2) > utUsedSymtabTable()) { utCompactSymtabTables(); freeSpace = utAllocatedSymtabTable() - utUsedSymtabTable(); } if(freeSpace < spaceNeeded) { utSetAllocatedSymtabTable(utAllocatedSymtabTable() + spaceNeeded - freeSpace + (utAllocatedSymtabTable() >> 2)); utResizeArray(utSymtabs.Table, utAllocatedSymtabTable()); }}/*---------------------------------------------------------------------------------------- Allocate memory for a new Symtab.Table array.----------------------------------------------------------------------------------------*/void utSymtabAllocTables( utSymtab Symtab, uint32 numTables){ uint32 freeSpace = utAllocatedSymtabTable() - utUsedSymtabTable(); uint32 elementSize = sizeof(utSym); uint32 usedHeaderSize = (sizeof(utSymtab) + elementSize - 1)/elementSize; uint32 freeHeaderSize = (sizeof(utSymtab) + sizeof(uint32) + elementSize - 1)/elementSize; uint32 spaceNeeded = utMax(numTables + usedHeaderSize, freeHeaderSize);#if defined(DD_DEBUG) utAssert(utSymtabGetNumTable(Symtab) == 0);#endif if(numTables == 0) { return; } if(freeSpace < spaceNeeded) { allocMoreSymtabTables(spaceNeeded); } utSymtabSetTableIndex(Symtab, utUsedSymtabTable() + usedHeaderSize); utSymtabSetNumTable(Symtab, numTables); *(utSymtab *)(void *)(utSymtabs.Table + utUsedSymtabTable()) = Symtab; memset(utSymtabGetTables(Symtab), 0xff, numTables*elementSize); utSetUsedSymtabTable(utUsedSymtabTable() + spaceNeeded);}/*---------------------------------------------------------------------------------------- Wrapper around utSymtabGetTables for the database manager.----------------------------------------------------------------------------------------*/static void *getSymtabTables( uint64 objectNumber, uint32 *numValues){ utSymtab Symtab = utIndex2Symtab(objectNumber); *numValues = utSymtabGetNumTable(Symtab); return utSymtabGetTables(Symtab);}/*---------------------------------------------------------------------------------------- Wrapper around utSymtabAllocTables for the database manager.----------------------------------------------------------------------------------------*/static void *allocSymtabTables( uint64 objectNumber, uint32 numValues){ utSymtab Symtab = utIndex2Symtab(objectNumber); utSymtabSetTableIndex(Symtab, 0); utSymtabSetNumTable(Symtab, 0); if(numValues == 0) { return NULL; } utSymtabAllocTables(Symtab, numValues); return utSymtabGetTables(Symtab);}/*---------------------------------------------------------------------------------------- Free memory used by the Symtab.Table array.----------------------------------------------------------------------------------------*/void utSymtabFreeTables( utSymtab Symtab){ uint32 elementSize = sizeof(utSym); uint32 usedHeaderSize = (sizeof(utSymtab) + elementSize - 1)/elementSize; uint32 freeHeaderSize = (sizeof(utSymtab) + sizeof(uint32) + elementSize - 1)/elementSize; uint32 size = utMax(utSymtabGetNumTable(Symtab) + usedHeaderSize, freeHeaderSize); utSym *dataPtr = utSymtabGetTables(Symtab) - usedHeaderSize; if(utSymtabGetNumTable(Symtab) == 0) { return; } *(utSymtab *)(void *)(dataPtr) = utSymtabNull; *(uint32 *)(void *)(((utSymtab *)(void *)dataPtr) + 1) = size; utSymtabSetNumTable(Symtab, 0); utSetFreeSymtabTable(utFreeSymtabTable() + size);}/*---------------------------------------------------------------------------------------- Resize the Symtab.Table array.----------------------------------------------------------------------------------------*/void utSymtabResizeTables( utSymtab Symtab, uint32 numTables){ uint32 freeSpace = utAllocatedSymtabTable() - utUsedSymtabTable(); uint32 elementSize = sizeof(utSym); uint32 usedHeaderSize = (sizeof(utSymtab) + elementSize - 1)/elementSize; uint32 freeHeaderSize = (sizeof(utSymtab) + sizeof(uint32) + elementSize - 1)/elementSize; uint32 newSize = utMax(numTables + usedHeaderSize, freeHeaderSize); uint32 oldSize = utMax(utSymtabGetNumTable(Symtab) + usedHeaderSize, freeHeaderSize); utSym *dataPtr; if(numTables == 0) { if(utSymtabGetNumTable(Symtab) != 0) { utSymtabFreeTables(Symtab); }; return; } if(utSymtabGetNumTable(Symtab) == 0) { utSymtabAllocTables(Symtab, newSize); return; }; if(freeSpace < newSize) { allocMoreSymtabTables(newSize); } dataPtr = utSymtabGetTables(Symtab) - usedHeaderSize; memcpy((void *)(utSymtabs.Table + utUsedSymtabTable()), dataPtr, elementSize*utMin(oldSize, newSize)); if(newSize > oldSize) { memset(utSymtabs.Table + utUsedSymtabTable() + oldSize, 0xff, elementSize*(newSize - oldSize)); } *(utSymtab *)(void *)dataPtr = utSymtabNull; *(uint32 *)(void *)(((utSymtab *)(void *)dataPtr) + 1) = oldSize; utSetFreeSymtabTable(utFreeSymtabTable() + oldSize); utSymtabSetTableIndex(Symtab, utUsedSymtabTable() + usedHeaderSize); utSymtabSetNumTable(Symtab, numTables); utSetUsedSymtabTable(utUsedSymtabTable() + newSize);}#if defined(DD_DEBUG)/*---------------------------------------------------------------------------------------- Write out all the fields of an object.----------------------------------------------------------------------------------------*/void utShowSymtab( utSymtab Symtab){ utDatabaseShowObject("ut", "Symtab", utSymtab2Index(Symtab));}#endif/*---------------------------------------------------------------------------------------- Default constructor wrapper for the database manager.----------------------------------------------------------------------------------------*/static uint64 allocSym(void){ utSym Sym = utSymAlloc(); return utSym2Index(Sym);}/*---------------------------------------------------------------------------------------- Allocate the field arrays of Sym.----------------------------------------------------------------------------------------*/static void allocSyms(void){ utSetAllocatedSym(2); utSetUsedSym(0); utSyms.NameIndex = utNewA(uint32, (utAllocatedSym())); utSyms.NumName = utNewA(uint32, (utAllocatedSym())); utSetUsedSymName(0); utSetAllocatedSymName(2); utSetFreeSymName(0); utSyms.Name = utNewA(char, utAllocatedSymName()); utSyms.HashValue = utNewA(uint32, (utAllocatedSym())); utSyms.Next = utNewA(utSym, (utAllocatedSym())); utSyms.SymArrayIndex = utNewA(uint32, (utAllocatedSym()));}/*---------------------------------------------------------------------------------------- Realloc the arrays of properties for class Sym.----------------------------------------------------------------------------------------*/static void reallocSyms( uint32 newSize){ utResizeArray(utSyms.NameIndex, (newSize)); utResizeArray(utSyms.NumName, (newSize)); utResizeArray(utSyms.HashValue, (newSize)); utResizeArray(utSyms.Next, (newSize)); utResizeArray(utSyms.SymArrayIndex, (newSize)); utSetAllocatedSym(newSize);}/*---------------------------------------------------------------------------------------- Allocate more Syms.----------------------------------------------------------------------------------------*/void utSymAllocMore(void){ reallocSyms(utAllocatedSym() + (utAllocatedSym() >> 1));}/*---------------------------------------------------------------------------------------- Compact the Sym.Name heap to free memory.----------------------------------------------------------------------------------------*/void utCompactSymNames(void){ uint32 elementSize = sizeof(char); uint32 usedHeaderSize = (sizeof(utSym) + elementSize - 1)/elementSize; uint32 freeHeaderSize = (sizeof(utSym) + sizeof(uint32) + elementSize - 1)/elementSize; char *toPtr = utSyms.Name; char *fromPtr = toPtr; utSym Sym; uint32 size; while(fromPtr < utSyms.Name + utUsedSymName()) { Sym = *(utSym *)(void *)fromPtr; if(Sym != utSymNull) { /* Need to move it to toPtr */ size = utMax(utSymGetNumName(Sym) + usedHeaderSize, freeHeaderSize); memmove((void *)toPtr, (void *)fromPtr, size*elementSize); utSymSetNameIndex(Sym, toPtr - utSyms.Name + usedHeaderSize); toPtr += size; } else { /* Just skip it */ size = *(uint32 *)(void *)(((utSym *)(void *)fromPtr) + 1); } fromPtr += size; } utSetUsedSymName(toPtr - utSyms.Name); utSetFreeSymName(0);}/*---------------------------------------------------------------------------------------- Allocate more memory for the Sym.Name heap.----------------------------------------------------------------------------------------*/static void allocMoreSymNames( uint32 spaceNeeded){ uint32 freeSpace = utAllocatedSymName() - utUsedSymName(); if((utFreeSymName() << 2) > utUsedSymName()) { utCompactSymNames(); freeSpace = utAllocatedSymName() - utUsedSymName(); } if(freeSpace < spaceNeeded) { utSetAllocatedSymName(utAllocatedSymName() + spaceNeeded - freeSpace + (utAllocatedSymName() >> 2)); utResizeArray(utSyms.Name, utAllocatedSymName()); }}/*---------------------------------------------------------------------------------------- Allocate memory for a new Sym.Name array.----------------------------------------------------------------------------------------*/void utSymAllocNames( utSym Sym, uint32 numNames){ uint32 freeSpace = utAllocatedSymName() - utUsedSymName(); uint32 elementSize = sizeof(char); uint32 usedHeaderSize = (sizeof(utSym) + elementSize - 1)/elementSize; uint32 freeHeaderSize = (sizeof(utSym) + sizeof(uint32) + elementSize - 1)/elementSize; uint32 spaceNeeded = utMax(numNames + usedHeaderSize, freeHeaderSize);#if defined(DD_DEBUG) utAssert(utSymGetNumName(Sym) == 0);#endif if(numNames == 0) { return; } if(freeSpace < spaceNeeded) { allocMoreSymNames(spaceNeeded); } utSymSetNameIndex(Sym, utUsedSymName() + usedHeaderSize); utSymSetNumName(Sym, numNames); *(utSym *)(void *)(utSyms.Name + utUsedSymName()) = Sym; memset(utSymGetNames(Sym), 0, numNames*elementSize); utSetUsedSymName(utUsedSymName() + spaceNeeded);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -