using NATS.Server.JetStream.Models; // Alias for the full Go-parity StreamState in this namespace. using StorageStreamState = NATS.Server.JetStream.Storage.StreamState; namespace NATS.Server.JetStream.Storage; // Go: server/store.go:91 /// /// Abstraction over a single stream's message store. /// The async methods (AppendAsync, LoadAsync, …) are used by the current /// high-level JetStream layer. The sync methods (StoreMsg, LoadMsg, State, …) /// mirror Go's StreamStore interface exactly and will be the primary surface /// once the block-engine FileStore implementation lands. /// public interface IStreamStore { // ------------------------------------------------------------------------- // Async helpers — used by the current JetStream layer // ------------------------------------------------------------------------- ValueTask AppendAsync(string subject, ReadOnlyMemory payload, CancellationToken ct); ValueTask LoadAsync(ulong sequence, CancellationToken ct); ValueTask LoadLastBySubjectAsync(string subject, CancellationToken ct); ValueTask> ListAsync(CancellationToken ct); ValueTask RemoveAsync(ulong sequence, CancellationToken ct); ValueTask PurgeAsync(CancellationToken ct); ValueTask CreateSnapshotAsync(CancellationToken ct); ValueTask RestoreSnapshotAsync(ReadOnlyMemory snapshot, CancellationToken ct); // Returns Models.StreamState for API-layer JSON serialisation compatibility. // Existing MemStore/FileStore implementations return this type. ValueTask GetStateAsync(CancellationToken ct); // Cached state properties — avoid GetStateAsync on the publish hot path. // These are maintained incrementally by FileStore/MemStore and are O(1). ulong LastSeq => throw new NotSupportedException("LastSeq not implemented."); ulong MessageCount => throw new NotSupportedException("MessageCount not implemented."); ulong TotalBytes => throw new NotSupportedException("TotalBytes not implemented."); ulong FirstSeq => throw new NotSupportedException("FirstSeq not implemented."); // ------------------------------------------------------------------------- // Go-parity sync interface — mirrors server/store.go StreamStore // Default implementations throw NotSupportedException so existing // MemStore / FileStore implementations continue to compile while the // block-engine port is in progress. // ------------------------------------------------------------------------- // Go: StreamStore.StoreMsg — append a message; returns (seq, timestamp) (ulong Seq, long Ts) StoreMsg(string subject, byte[]? hdr, byte[] msg, long ttl) => throw new NotSupportedException("Block-engine StoreMsg not yet implemented."); // Go: StreamStore.StoreRawMsg — store a raw message at a specified sequence void StoreRawMsg(string subject, byte[]? hdr, byte[] msg, ulong seq, long ts, long ttl, bool discardNewCheck) => throw new NotSupportedException("Block-engine StoreRawMsg not yet implemented."); // Go: StreamStore.SkipMsg — reserve a sequence without storing a message ulong SkipMsg(ulong seq) => throw new NotSupportedException("Block-engine SkipMsg not yet implemented."); // Go: StreamStore.SkipMsgs — reserve a range of sequences void SkipMsgs(ulong seq, ulong num) => throw new NotSupportedException("Block-engine SkipMsgs not yet implemented."); // Go: StreamStore.FlushAllPending — flush any buffered writes to backing storage Task FlushAllPending() => throw new NotSupportedException("Block-engine FlushAllPending not yet implemented."); // Go: StreamStore.LoadMsg — load message by exact sequence; sm is an optional reusable buffer StoreMsg LoadMsg(ulong seq, StoreMsg? sm) => throw new NotSupportedException("Block-engine LoadMsg not yet implemented."); // Go: StreamStore.LoadNextMsg — load next message at or after start matching filter; // returns the message and the number of sequences skipped (StoreMsg Msg, ulong Skip) LoadNextMsg(string filter, bool wc, ulong start, StoreMsg? sm) => throw new NotSupportedException("Block-engine LoadNextMsg not yet implemented."); // Go: StreamStore.LoadLastMsg — load the most recent message on a given subject StoreMsg LoadLastMsg(string subject, StoreMsg? sm) => throw new NotSupportedException("Block-engine LoadLastMsg not yet implemented."); // Go: StreamStore.LoadPrevMsg — load message before start sequence StoreMsg LoadPrevMsg(ulong start, StoreMsg? sm) => throw new NotSupportedException("Block-engine LoadPrevMsg not yet implemented."); // Go: StreamStore.RemoveMsg — soft-delete a message by sequence; returns true if found bool RemoveMsg(ulong seq) => throw new NotSupportedException("Block-engine RemoveMsg not yet implemented."); // Go: StreamStore.EraseMsg — overwrite a message with random bytes before removing it bool EraseMsg(ulong seq) => throw new NotSupportedException("Block-engine EraseMsg not yet implemented."); // Go: StreamStore.Purge — remove all messages; returns count purged ulong Purge() => throw new NotSupportedException("Block-engine Purge not yet implemented."); // Go: StreamStore.PurgeEx — purge messages on subject up to seq keeping keep newest ulong PurgeEx(string subject, ulong seq, ulong keep) => throw new NotSupportedException("Block-engine PurgeEx not yet implemented."); // Go: StreamStore.Compact — remove all messages with seq < given sequence ulong Compact(ulong seq) => throw new NotSupportedException("Block-engine Compact not yet implemented."); // Go: StreamStore.Truncate — remove all messages with seq > given sequence void Truncate(ulong seq) => throw new NotSupportedException("Block-engine Truncate not yet implemented."); // Go: StreamStore.GetSeqFromTime — return first sequence at or after wall-clock time t ulong GetSeqFromTime(DateTime t) => throw new NotSupportedException("Block-engine GetSeqFromTime not yet implemented."); // Go: StreamStore.FilteredState — compact state for messages matching subject at or after seq SimpleState FilteredState(ulong seq, string subject) => throw new NotSupportedException("Block-engine FilteredState not yet implemented."); // Go: StreamStore.SubjectsState — per-subject SimpleState for all subjects matching filter Dictionary SubjectsState(string filterSubject) => throw new NotSupportedException("Block-engine SubjectsState not yet implemented."); // Go: StreamStore.SubjectsTotals — per-subject message count for subjects matching filter Dictionary SubjectsTotals(string filterSubject) => throw new NotSupportedException("Block-engine SubjectsTotals not yet implemented."); // Go: StreamStore.AllLastSeqs — last sequence for every subject in the stream ulong[] AllLastSeqs() => throw new NotSupportedException("Block-engine AllLastSeqs not yet implemented."); // Go: StreamStore.MultiLastSeqs — last sequences for subjects matching filters, up to maxSeq ulong[] MultiLastSeqs(string[] filters, ulong maxSeq, int maxAllowed) => throw new NotSupportedException("Block-engine MultiLastSeqs not yet implemented."); // Go: StreamStore.SubjectForSeq — return the subject stored at the given sequence string SubjectForSeq(ulong seq) => throw new NotSupportedException("Block-engine SubjectForSeq not yet implemented."); // Go: StreamStore.NumPending — count messages pending from sseq on filter subject; // lastPerSubject restricts to one-per-subject semantics (ulong Total, ulong ValidThrough) NumPending(ulong sseq, string filter, bool lastPerSubject) => throw new NotSupportedException("Block-engine NumPending not yet implemented."); // Go: StreamStore.State — return full stream state (Go-parity, with deleted sets) StorageStreamState State() => throw new NotSupportedException("Block-engine State not yet implemented."); // Go: StreamStore.FastState — populate a pre-allocated StreamState with the minimum // fields needed for replication without allocating a new struct void FastState(ref StorageStreamState state) => throw new NotSupportedException("Block-engine FastState not yet implemented."); // Go: StreamStore.EncodedStreamState — binary-encode stream state for NRG replication byte[] EncodedStreamState(ulong failed) => throw new NotSupportedException("Block-engine EncodedStreamState not yet implemented."); // Go: StreamStore.Type — the storage type (File or Memory) StorageType Type() => throw new NotSupportedException("Block-engine Type not yet implemented."); // Go: StreamStore.UpdateConfig — apply a new StreamConfig without restarting the store void UpdateConfig(StreamConfig cfg) => throw new NotSupportedException("Block-engine UpdateConfig not yet implemented."); // Go: StreamStore.Delete — stop and delete all data; inline=true means synchronous deletion void Delete(bool inline) => throw new NotSupportedException("Block-engine Delete not yet implemented."); // Go: StreamStore.Stop — flush and stop without deleting data void Stop() => throw new NotSupportedException("Block-engine Stop not yet implemented."); // Go: StreamStore.ConsumerStore — create or open a consumer store for the named consumer IConsumerStore ConsumerStore(string name, DateTime created, ConsumerConfig cfg) => throw new NotSupportedException("Block-engine ConsumerStore not yet implemented."); // Go: StreamStore.ResetState — reset internal state caches (used after NRG catchup) void ResetState() => throw new NotSupportedException("Block-engine ResetState not yet implemented."); }