static void SaveRecord( ScanCacheWriter* self, const HashDigest* digest, T* includes, int include_count, uint64_t file_timestamp, uint64_t access_time) { // TODO: Check access time to see if we should discard. BinarySegment *digest_seg = self->m_DigestSeg; BinarySegment *data_seg = self->m_DataSeg; BinarySegment *timestamp_seg = self->m_TimestampSeg; BinarySegment *string_seg = self->m_StringSeg; BinarySegment *array_seg = self->m_ArraySeg; BinaryLocator string_ptrs = BinarySegmentPosition(array_seg); for (int i = 0; i < include_count; ++i) { BinarySegmentWritePointer(array_seg, BinarySegmentPosition(string_seg)); BinarySegmentWriteUint32(array_seg, includes[i].m_Hash); BinarySegmentWriteStringData(string_seg, includes[i].m_Filename); } BinarySegmentWrite(digest_seg, (const char*) digest->m_Data, sizeof(HashDigest)); BinarySegmentWriteUint64(data_seg, file_timestamp); BinarySegmentWriteUint32(data_seg, uint32_t(include_count)); BinarySegmentWritePointer(data_seg, string_ptrs); BinarySegmentWriteUint64(timestamp_seg, access_time); self->m_RecordsOut++; }
static bool ScanCacheWriterFlush(ScanCacheWriter* self, const char* filename) { BinarySegmentWriteUint32(self->m_MainSeg, ScanData::MagicNumber); BinarySegmentWriteUint32(self->m_MainSeg, self->m_RecordsOut); BinarySegmentWritePointer(self->m_MainSeg, self->m_DigestPtr); BinarySegmentWritePointer(self->m_MainSeg, self->m_EntryPtr); BinarySegmentWritePointer(self->m_MainSeg, self->m_TimestampPtr); return BinaryWriterFlush(&self->m_Writer, filename); }
bool DigestCacheSave(DigestCache* self, MemAllocHeap* serialization_heap, const char* tmp_filename) { TimingScope timing_scope(nullptr, &g_Stats.m_DigestCacheSaveTimeCycles); BinaryWriter writer; BinaryWriterInit(&writer, serialization_heap); BinarySegment *main_seg = BinaryWriterAddSegment(&writer); BinarySegment *array_seg = BinaryWriterAddSegment(&writer); BinarySegment *string_seg = BinaryWriterAddSegment(&writer); BinaryLocator array_ptr = BinarySegmentPosition(array_seg); auto save_record = [=](size_t index, const HashRecord* hr) { const DigestCacheRecord* r = (const DigestCacheRecord*) hr; BinarySegmentWriteUint64(array_seg, r->m_Timestamp); BinarySegmentWriteUint64(array_seg, r->m_AccessTime); BinarySegmentWriteUint32(array_seg, r->m_Hash); BinarySegmentWrite(array_seg, &r->m_ContentDigest, sizeof(r->m_ContentDigest)); BinarySegmentWritePointer(array_seg, BinarySegmentPosition(string_seg)); BinarySegmentWriteStringData(string_seg, r->m_String); BinarySegmentWriteUint32(array_seg, 0); // m_Padding #if ENABLED(USE_FAST_HASH) BinarySegmentWriteUint32(array_seg, 0); // m_Padding #endif }; HashTableWalk(&self->m_Table, save_record); BinarySegmentWriteUint32(main_seg, DigestCacheState::MagicNumber); BinarySegmentWriteInt32(main_seg, (int) self->m_Table.m_RecordCount); BinarySegmentWritePointer(main_seg, array_ptr); // Unmap old state to avoid sharing conflicts on Windows. MmapFileUnmap(&self->m_StateFile); self->m_State = nullptr; bool success = BinaryWriterFlush(&writer, tmp_filename); if (success) { success = RenameFile(tmp_filename, self->m_StateFilename); } else { remove(tmp_filename); } BinaryWriterDestroy(&writer); return success; }