#pragma once #include #include "structures.h" #include "utils/file_handle.h" constexpr int roundToNearest16(int number) { return (number + 15) & ~15; } class SweepstoreHeader { private: SweepstoreFileHandle& file; public: explicit SweepstoreHeader(SweepstoreFileHandle &fileStream) : file(fileStream) {} // Offset 0 - 4 bytes std::string readMagicNumber(); void writeMagicNumber(const std::string& magicNumber); // Offset 4 - 12 bytes std::string readVersion(); void writeVersion(const std::string& version); // Offset 16 - 8 bytes SweepstorePointer readAddressTablePointer(); void writeAddressTablePointer(const SweepstorePointer& ptr); // Offset 24 - 4 bytes uint32_t readFreeListCount(); void writeFreeListCount(uint32_t count); // Offset 28 - 1 byte bool readIsFreeListLifted(); void writeIsFreeListLifted(bool isLifted); /** * Initialises the header with default values. */ void initialise(); }; constexpr int SWEEPSTORE_COMBINED_STATIC_HEADER_SIZE = roundToNearest16(46); struct SweepstoreWorkerTicketSnapshot { SweepstoreWorkerTicketSnapshot() : identifier(0), workerHeartbeat(0), state(SweepstoreTicketState::FREE), operation(SweepstoreTicketOperation::NONE), keyHash(0), targetAddress(SweepstorePointer::NULL_PTR), targetSize(0) {} // Offset 0 - 4 bytes uint32_t identifier; // Offset 4 - 4 bytes uint32_t workerHeartbeat; // Offset 8 - 1 byte SweepstoreTicketState state; // Offset 9 - 1 byte SweepstoreTicketOperation operation; // Offset 10 - 8 bytes uint64_t keyHash; // Offset 18 - 8 bytes SweepstorePointer targetAddress; // Offset 26 - 4 bytes uint32_t targetSize; }; class SweepstoreWorkerTicket { SweepstoreFileHandle& file; uint32_t ticketIndex; uint64_t getOffset() const { return SWEEPSTORE_COMBINED_STATIC_HEADER_SIZE + (ticketIndex * TICKET_SIZE); } public: static constexpr int TICKET_SIZE = roundToNearest16(29); SweepstoreWorkerTicket(const uint32_t index, SweepstoreFileHandle& fileStream) : file(fileStream), ticketIndex(index) {} int getTicketIndex() const { return ticketIndex; } void write(SweepstoreWorkerTicketSnapshot &snapshot); bool writable(); SweepstoreWorkerTicketSnapshot snapshot(); }; class SweepstoreConcurrencyHeader { private: SweepstoreFileHandle& file; public: explicit SweepstoreConcurrencyHeader(SweepstoreFileHandle &fileStream) : file(fileStream) {} // Offset 29 - 8 bytes uint64_t readMasterIdentifier(); void writeMasterIdentifier(uint64_t identifier); // Offset 37 - 4 bytes uint32_t readMasterHeartbeat(); void writeMasterHeartbeat(uint32_t heartbeat); // Offset 41 - 4 bytes uint32_t readNumberOfWorkers(); void writeNumberOfWorkers(uint32_t numWorkers); // Offset 45 - 1 byte bool readIsReadAllowed(); void writeIsReadAllowed(bool isAllowed); /** * Initialises the concurrency header with default values. */ void initialise(int concurrentWorkers); SweepstoreWorkerTicket operator[](const uint32_t index) const { return SweepstoreWorkerTicket(index, file); } };