⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 utpersist.c

📁 DataDraw is an ultra-fast persistent database for high performance programs written in C. It s so fa
💻 C
📖 第 1 页 / 共 4 页
字号:
    utDatabaseSize = utFindFileSize(utSprintf("%s%cdatabase", utDatabaseDirectory, UTDIRSEP));    resetCommandBuffer();    fclose(utRecentChangesFile);    openRecentChanges("wb");}/*--------------------------------------------------------------------------------------------------  Mark the transaction complete, and optionally fush to disk.--------------------------------------------------------------------------------------------------*/void utTransactionComplete(    bool flushToDisk){    uint32 checksum = utChecksum;    uint32 length;    writeUint8(UT_TRANSACTION_COMPLETE);    writeUint32(checksum);    utChecksum = 0;    length = utBufferStartPosition + utBufferPosition - utLastTransactionPosition;    utTransactionCreate(utLastTransactionPosition, length);    utLastTransactionPosition += length;    if(utPersistenceInitialized) {        if(flushToDisk) {            flushRecentChanges();            fflush(utRecentChangesFile);        }#ifndef UT_USE_UTDATABASEUP_H        /* Don't do this if we are a persistent undo/redo database */        if((utBufferStartPosition << 2) > utDatabaseSize) {            utCompactDatabase();        }#endif    }}/*--------------------------------------------------------------------------------------------------  Register an enumerated type.--------------------------------------------------------------------------------------------------*/void utRegisterEnum(    char *name,    uint16 numEntries){    utEnum theEnum;    if(utUsedEnums == utAllocatedEnums) {        utAllocatedEnums += utAllocatedEnums >> 1;        utResizeArray(utEnums, utAllocatedEnums);    }    theEnum = utEnums + utUsedEnums++;    theEnum->name = calloc(strlen(name) + 1, sizeof(char));    strcpy(theEnum->name, name);    theEnum->firstEntryIndex = utUsedEntries;    theEnum->numEntries = numEntries;}/*--------------------------------------------------------------------------------------------------  Register an entry in an enumerated type.--------------------------------------------------------------------------------------------------*/void utRegisterEntry(    char *name,    uint32 value){    utEntry entry;    if(utUsedEntries == utAllocatedEntries) {        utAllocatedEntries += utAllocatedEntries >> 1;        utResizeArray(utEntries, utAllocatedEntries);    }    entry = utEntries + utUsedEntries++;    entry->name = calloc(strlen(name) + 1, sizeof(char));    entry->value = value;    strcpy(entry->name, name);}/*--------------------------------------------------------------------------------------------------  Register the previously registered field as a union.--------------------------------------------------------------------------------------------------*/void utRegisterUnion(    char *switchFieldName,    uint16 numCases){    utField unionField = utFields + utUsedFields - 1;    utUnion theUnion;    utField switchField = utFindField(utCurrentClass, switchFieldName);    if(utUsedUnions == utAllocatedUnions) {        utAllocatedUnions += utAllocatedUnions >> 1;        utResizeArray(utUnions, utAllocatedUnions);    }    unionField->unionIndex = utUsedUnions;    theUnion = utUnions + utUsedUnions++;    theUnion->switchFieldIndex = switchField - utFields;    theUnion->fieldIndex = utUsedFields - 1;    theUnion->firstUnionCaseIndex = utUsedUnionCases;    theUnion->numUnionCases = numCases;}/*--------------------------------------------------------------------------------------------------  Write the variable sized integer.--------------------------------------------------------------------------------------------------*/void utRegisterUnionCase(    uint32 value,    utFieldType type,    uint32 size){    utUnionCase unionCase;    if(utUsedUnionCases == utAllocatedUnionCases) {        utAllocatedUnionCases += utAllocatedUnionCases >> 1;        utResizeArray(utUnionCases, utAllocatedUnionCases);    }    unionCase = utUnionCases + utUsedUnionCases++;    unionCase->value = value;    if(type == UT_BIT) {        type = UT_BOOL; /* We convert bit to bool in unions */        size = sizeof(bool);    }    unionCase->size = size;    unionCase->type = type;}/*--------------------------------------------------------------------------------------------------  Write the variable sized integer.--------------------------------------------------------------------------------------------------*/static void writeInteger(    uint64 value,    uint8 size){    switch(size) {    case 1: writeUint8((uint8)value); break;    case 2: writeUint16((uint16)value); break;    case 4: writeUint32((uint32)value); break;    case 8: writeUint64(value); break;    default:        utExit("Invalid reference size");    }}/*--------------------------------------------------------------------------------------------------  Record the change to the field.--------------------------------------------------------------------------------------------------*/void utRecordField(    uint8 moduleID,    uint16 fieldIndex,    uint64 objectNumber,    bool undo){    utModule module = utModules + moduleID;    uint16 fieldPosition = module->firstFieldIndex + fieldIndex;    utField field = utFields + fieldPosition;    utClass theClass = utClasses + field->classIndex;    uint8 *values = *(uint8 **)(field->arrayPtr) + objectNumber*field->size;    writeUint8(UT_WRITE_FIELD | (undo? 0x80 : 0));    writeUint16(fieldPosition);    writeInteger(objectNumber, theClass->referenceSize);    writeValues(values, field->size);}/*--------------------------------------------------------------------------------------------------  Record the change to the field.--------------------------------------------------------------------------------------------------*/void utRecordArray(    uint8 moduleID,    uint16 fieldIndex,    uint32 dataIndex,    uint32 length,    bool undo){    utModule module = utModules + moduleID;    uint16 fieldPosition = module->firstFieldIndex + fieldIndex;    utField field = utFields + fieldPosition;    uint8 *values = *(uint8 **)(field->arrayPtr) + dataIndex*field->size;    writeUint8(UT_WRITE_ARRAY | (undo? 0x80 : 0));    writeUint16(fieldPosition);    writeUint32(dataIndex);    writeUint32(length);    writeValues(values, field->size*length);}/*--------------------------------------------------------------------------------------------------  Record the change to the global value.--------------------------------------------------------------------------------------------------*/void utRecordGlobal(    uint8 moduleID,    uint8 numBytes,    void *location,    bool undo){    utModule module = utModules + moduleID;    uint32 offset = ((uint8 *) location) - ((uint8 *) module->globalData);    writeUint8(UT_WRITE_GLOBAL | (undo? 0x80 : 0));    writeUint8(moduleID);    writeUint16(offset);    writeUint8(numBytes);    writeValues(location, numBytes);}/*--------------------------------------------------------------------------------------------------  Record when a field is resized.--------------------------------------------------------------------------------------------------*/void utRecordResize(    uint8 moduleID,    uint16 fieldIndex,    uint64 length,    bool undo){    utModule module = utModules + moduleID;    uint16 fieldPosition = module->firstFieldIndex + fieldIndex;    writeUint8(UT_RESIZE_FIELD | (undo? 0x80 : 0));    writeUint16(fieldPosition);    writeUint64(length);}#define readUint8(buffer) (*(buffer))/*--------------------------------------------------------------------------------------------------  Read a uint16 from the command buffer.--------------------------------------------------------------------------------------------------*/static uint16 readUint16(    uint8 *buffer){    return *(uint16 *)(void *)(buffer);}/*--------------------------------------------------------------------------------------------------  Read a uint32 from a buffer.--------------------------------------------------------------------------------------------------*/static uint32 readUint32(    uint8 *buffer){    return *(uint32 *)(void *)(buffer);}/*--------------------------------------------------------------------------------------------------  Read a uint64 from a buffer.--------------------------------------------------------------------------------------------------*/static uint64 readUint64(    uint8 *buffer){    return *(uint64 *)(void *)(buffer);}/*--------------------------------------------------------------------------------------------------  Apply a field value.  WRITE_FIELD <16-bit field #> <32-bit index> <value>--------------------------------------------------------------------------------------------------*/static void applyField(    uint8 *command){    uint16 xField = readUint16(command);    utField field = utFields + xField;    utClass theClass = utClasses + field->classIndex;    uint8 *values;    uint64 objectNumber;    command += 2;    objectNumber = utFindIntValue(command, theClass->referenceSize);    command += theClass->referenceSize;    values = *(uint8 **)(field->arrayPtr) + objectNumber*field->size;    memcpy(values, command, field->size);}/*--------------------------------------------------------------------------------------------------  Apply an array of values.  WRITE_ARRAY <16-bit field #> <32-bit index> <32-bit numValues> <values>--------------------------------------------------------------------------------------------------*/static void applyArray(    uint8 *command){    uint16 xField = readUint16(command);    utField field = utFields + xField;    uint8 *values;    uint32 length, bytes;    uint32 dataIndex;    command += 2;    dataIndex = readUint32(command);    command += 4;    length = readUint32(command);    command += 4;    bytes = field->size*length;    values = *(uint8 **)(field->arrayPtr) + dataIndex*field->size;    memcpy(values, command, bytes);}/*--------------------------------------------------------------------------------------------------  Apply a global value change.  WRITE_GLOBAL <8-bit moduleID> <16-bit offset> <8-bit numBytes> <values>--------------------------------------------------------------------------------------------------*/static void applyGlobal(    uint8 *command){    uint8 moduleID = readUint8(command);    utModule module = utModules + moduleID;    uint16 offset;    uint8 numBytes;    uint8 *values;    command++;    offset = readUint16(command);    command += 2;    numBytes = readUint8(command);    command++;    values = (uint8 *)(module->globalData) + offset;    memcpy(values, command, numBytes);}/*--------------------------------------------------------------------------------------------------  Apply a resize field command.  RESIZE_FIELD <16-bit field #> <64-bit size>--------------------------------------------------------------------------------------------------*/static void applyResize(    uint8 *command){    uint16 xField = readUint16(command);    utField field = utFields + xField;    uint64 size;    command += 2;    size = readUint64(command);    command += 8;    *(uint8 **)(field->arrayPtr) = utRealloc(*(uint8 **)field->arrayPtr, size, field->size);}/*--------------------------------------------------------------------------------------------------  Find the size of a command.--------------------------------------------------------------------------------------------------*/static uint32 findCommandSize(    uint8 *command){    utClass theClass;    utField field;    uint16 xField;    switch((*command) & 0x7f) {    case UT_TRANSACTION_COMPLETE:        /* TRANSACTION_COMPLETE <32-bit checksum> */        return  5;    case UT_WRITE_FIELD:        /* WRITE_FIELD <16-bit field #> <32-bit index> <value> */        xField = readUint16(command + 1);        field = utFields + xField;        theClass = utClasses + field->classIndex;        return 3 + field->size + theClass->referenceSize;    case UT_WRITE_ARRAY:        /* WRITE_ARRAY <16-bit field #> <32-bit index> <32-bit numValues> <values> */        xField = readUint16(command + 1);        field = utFields + xField;        return 11 + field->size*readUint32(command + 7);    case UT_WRITE_GLOBAL:        /* WRITE_GLOBAL <8-bit moduleID> <16-bit offset> <8-bit numBytes> <values> */        return 5 + readUint8(command + 4);    case UT_RESIZE_FIELD:        /* RESIZE_FIELD <16-bit field #> <64-bit size> */        return 11;    default:        utExit("Invalid command");    }    return 0;}/*--------------------------------------------------------------------------------------------------  Apply the command.--------------------------------------------------------------------------------------------------*/static void applyCommand(    uint8 *command){    switch(*command++ & 0x7f) {    case UT_WRITE_FIELD:        applyField(command);        break;    case UT_WRITE_ARRAY:        applyArray(command);        break;    case UT_WRITE_GLOBAL:        applyGlobal(command);        break;    case UT_RESIZE_FIELD:        applyResize(command);        break;    default:        utExit("Unknown command in recentChanges file");    }}/*--------------------------------------------------------------------------------------------------  Apply changes from the commands in the buffer.--------------------------------------------------------------------------------------------------*/static void applyCommands(    uint8 *commands,    uint32 length){    uint32 xCommand = 0;    uint32 size;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -