From ceb94a5ba7c9a0742a51cc01c861cb5091963a17 Mon Sep 17 00:00:00 2001 From: Markus Mittendrein Date: Sun, 8 Sep 2019 18:39:53 +0200 Subject: Revert "Store duplicate data only once if possible (Offset stays in the valid range)" This reverts commit 36f1c4c4e822458170099890cf586dd013e82673. --- src/cc4group.c | 114 ++++++--------------------------------------------------- 1 file changed, 12 insertions(+), 102 deletions(-) (limited to 'src/cc4group.c') diff --git a/src/cc4group.c b/src/cc4group.c index 2919224..b086110 100644 --- a/src/cc4group.c +++ b/src/cc4group.c @@ -73,7 +73,6 @@ typedef struct C4GroupEntryData_t { size_t absolutePosition; const char* path; - const struct C4GroupEntryData_t* shareDataWith; } C4GroupEntryData; LIST_AUTO(C4GroupEntryData, GroupEntryList) @@ -327,7 +326,7 @@ static bool buildChildren(CC4Group* const this, C4GroupEntryData* const entry, s return false; } - C4GroupEntryData* childEntry = &GroupEntryListAppend(entry->children, (C4GroupEntryData){.core = *core, .data = childData + core->Offset, .memoryManagement = cc4group.MemoryManagement.Reference, .children = NULL, .parent = entry, .absolutePosition = entry->absolutePosition + childDataOffset + core->Offset, .path = NULL, .shareDataWith = NULL})->value; + C4GroupEntryData* childEntry = &GroupEntryListAppend(entry->children, (C4GroupEntryData){.core = *core, .data = childData + core->Offset, .memoryManagement = cc4group.MemoryManagement.Reference, .children = NULL, .parent = entry, .absolutePosition = entry->absolutePosition + childDataOffset + core->Offset, .path = NULL})->value; if(this->readState.position < childEntry->absolutePosition) { @@ -1204,7 +1203,6 @@ static void cc4group_init(CC4Group* const this) this->root.children = NULL; this->root.core.Directory = true; this->root.path = NULL; - this->root.shareDataWith = NULL; this->cleanupJobs = CleanUpJobListNew(); @@ -1535,7 +1533,6 @@ static C4GroupEntryData* cc4group_addFileFromDisk(CC4Group* const this, const ch result->core.Modified = st.st_mtime; result->core.Size = st.st_size; result->path = filePath; - result->shareDataWith = NULL; ret: if(result == NULL || result->path == NULL) @@ -2254,10 +2251,7 @@ static size_t cc4group_calculateEntrySizes(CC4Group* const this, C4GroupEntryDat size_t sum = sizeof(C4GroupHeader) + GroupEntryListSize(children) * sizeof(C4GroupEntryCore); ForeachGroupEntry(children) { - if(entry->value.shareDataWith == NULL) - { - sum += cc4group_calculateEntrySizes(this, &entry->value); - } + sum += cc4group_calculateEntrySizes(this, &entry->value); } return entryData->core.Size = sum; @@ -2268,7 +2262,7 @@ static size_t cc4group_calculateEntrySizes(CC4Group* const this, C4GroupEntryDat } } -static void cc4group_calculateEntryCRC(CC4Group* const this, C4GroupEntryData* const groupEntry, bool withFileName) +static void cc4group_calculateEntryCRC(CC4Group* const this, C4GroupEntryData* const groupEntry) { if(groupEntry->core.Directory) { @@ -2281,13 +2275,13 @@ static void cc4group_calculateEntryCRC(CC4Group* const this, C4GroupEntryData* c uint32_t crc = 0; ForeachGroupEntry(children) { - cc4group_calculateEntryCRC(this, &entry->value, withFileName); + cc4group_calculateEntryCRC(this, &entry->value); crc ^= entry->value.core.CRC; } - groupEntry->core.HasCRC = withFileName ? C4GroupEntryCore_ContentsFileNameCRC : C4GroupEntryCore_ContentsCRC; + groupEntry->core.HasCRC = C4GroupEntryCore_ContentsFileNameCRC; groupEntry->core.CRC = crc; } - else + else if(groupEntry->core.HasCRC != C4GroupEntryCore_ContentsFileNameCRC) { const uint8_t* data = cc4group_getOnlyEntryData(this, groupEntry); if(data == NULL) @@ -2295,74 +2289,13 @@ static void cc4group_calculateEntryCRC(CC4Group* const this, C4GroupEntryData* c return; } uint32_t crc = crc32(0, data, groupEntry->core.Size); - if(withFileName) - { - crc = crc32(crc, (uint8_t*)groupEntry->core.FileName, strlen(groupEntry->core.FileName)); - } + crc = crc32(crc, (uint8_t*)groupEntry->core.FileName, strlen(groupEntry->core.FileName)); - groupEntry->core.HasCRC = withFileName ? C4GroupEntryCore_ContentsFileNameCRC : C4GroupEntryCore_ContentsCRC; + groupEntry->core.HasCRC = C4GroupEntryCore_ContentsFileNameCRC; groupEntry->core.CRC = crc; } } -// currentOffset is the offset of parent to inEntry's original parent's header -static const C4GroupEntryData* cc4group_findDuplicateEntry(C4GroupEntryData* const inEntry, C4GroupEntryData* const parent, size_t currentOffset) -{ - uint32_t ownCRC = inEntry->core.CRC; - ForeachGroupEntry(parent->children) - { - if(&entry->value != inEntry && entry->value.shareDataWith == NULL) - { - if(entry->value.core.CRC == ownCRC) - { - return &entry->value; - } - else if(entry->value.core.Directory) - { - const C4GroupEntryData* result = cc4group_findDuplicateEntry(inEntry, &entry->value, currentOffset); - if(result != 0) - { - return result; - } - } - - if(entry->value.shareDataWith == NULL) - { - currentOffset += entry->value.core.Size; - } - } - } - - return 0; -} - -// assumes that everything is loaded already and CRCs and sizes have been calculated before -static void cc4group_deduplicateEntriesOf(C4GroupEntryData* const inEntry) -{ - ForeachGroupEntry(inEntry->children) - { - entry->value.shareDataWith = NULL; - } - - ForeachGroupEntry(inEntry->children) - { - const C4GroupEntryData* shareWith = cc4group_findDuplicateEntry(&entry->value, inEntry, 0); - if(shareWith != 0) - { - entry->value.shareDataWith = shareWith; - } - else if(entry->value.core.Directory) - { - cc4group_deduplicateEntriesOf(&entry->value); - } - } -} - -static void cc4group_deduplicateEntries(CC4Group* const this) -{ - cc4group_deduplicateEntriesOf(&this->root); -} - static bool cc4group_flushBufferedWrite(WriteCallback* const callback) { bool success = true; @@ -2497,38 +2430,20 @@ static bool cc4group_writeEntries(CC4Group* const this, C4GroupEntryData* const ForeachGroupEntry(children) { - if(entry->value.shareDataWith == NULL) - { - entry->value.core.Offset = offset; - } + entry->value.core.Offset = offset; entry->value.core.Packed = 1; - if(entry->value.shareDataWith == NULL) - { - offset += entry->value.core.Size; - } - } - - ForeachGroupEntry(children) - { - if(entry->value.shareDataWith != NULL) - { - entry->value.core.Offset = entry->value.shareDataWith->core.Offset; - } - if(!cc4group_deflateToCallback(callback, &entry->value.core, sizeof(entry->value.core), Z_NO_FLUSH, Z_OK)) { SET_MESSAGE_ERROR("Failed writing a group entry core"); return false; } + + offset += entry->value.core.Size; } ForeachGroupEntry(children) { - if(entry->value.shareDataWith != NULL) - { - continue; - } if(entry->value.core.Directory) { if(!cc4group_writeEntries(this, &entry->value, callback)) @@ -2614,10 +2529,7 @@ static bool cc4group_saveWithWriteCallback(CC4Group* const this, CC4Group_WriteC bool success = false; cc4group_calculateEntrySizes(this, &this->root); - cc4group_calculateEntryCRC(this, &this->root, false); - cc4group_deduplicateEntries(this); - cc4group_calculateEntrySizes(this, &this->root); - cc4group_calculateEntryCRC(this, &this->root, true); + cc4group_calculateEntryCRC(this, &this->root); if(!cc4group_writeEntries(this, &this->root, &callback)) { // error is set in cc4group_writeEntries @@ -3108,7 +3020,6 @@ static C4GroupEntryData* cc4group_createEntry(CC4Group* const this, const char* entry.data = NULL; entry.path = NULL; - entry.shareDataWith = NULL; entry.memoryManagement = cc4group.MemoryManagement.Reference; C4GroupEntryCore_init(&entry.core); @@ -3219,7 +3130,6 @@ static bool cc4group_setEntryData(CC4Group* const this, const char* const entryP { free((void*)entry->path); entry->path = NULL; - entry->shareDataWith = NULL; } if(data != NULL && size != 0) -- cgit v1.2.3-54-g00ecf