Skip to content

refactor: remove duplicated logic from storage internals - #91

Open
imurashka wants to merge 5 commits into
mainfrom
ivan/dedupe-storage-internals
Open

refactor: remove duplicated logic from storage internals#91
imurashka wants to merge 5 commits into
mainfrom
ivan/dedupe-storage-internals

Conversation

@imurashka

Copy link
Copy Markdown
Contributor

Three de-duplication passes over the storage internals, with no change to behaviour, to the public API, or to the bytes on disk.

Section lookup goes through a type-to-index dictionary instead of two different linear scans; the type-mismatch decision, reactive collection tracking and the auto-save condition each collapse from several copies into one; ReactiveList, ReactiveSet and ReactiveDictionary get a shared base for the dispose-and-notify contract. CollectionExtensions leaves the runtime assembly, since only tests used what was still alive in it.

…orage

Look up a registered section through a type-to-index dictionary instead of
scanning the section list twice with two different comparisons. Share the
type-mismatch decision between Set and SetRaw, and keep reactive collection
tracking in one pair of methods instead of five copies.

Drop the per-record type field in favour of the generic argument, and move
the test-only AddRange helpers out of the runtime assembly.
ReactiveList, ReactiveSet and ReactiveDictionary each carried their own copy
of the dispose flag, the OnChanged event, SetDirty and ThrowIfDisposed. Move
that contract into ReactiveCollection so a change to it lands in one place.

Build the nested storage key list in a single pass instead of a LINQ chain,
and reuse the prefix check that RemoveAll already needed.
MarkChanged and DecreaseCounter each carried their own copy of the "auto-save
is on, no change scope is open, there is something to save" condition. Route
DecreaseCounter through MarkChanged so the policy lives in one method.

Give the nested storage key list its capacity up front, reuse a cached prefix
predicate, and share one storage-opening helper across the persistence
fixtures.
WhenManyChangesQueued_ThenDiskHoldsTheLastState ends with an explicit Save,
and WhenDisposedWithPendingChanges_ThenTheyReachDisk queues a single change.
Neither covers a burst that leaves several snapshots behind the writer and is
then flushed by Dispose alone.
RemoveAll is called rarely, so the field traded eight permanent bytes for one
delegate per call on a cold path, and the sibling Remove overload allocates a
closure there anyway.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant