Этап 5

This commit is contained in:
2026-03-29 16:05:45 +03:00
parent 5fdaaaa2bf
commit 400af7982e
8 changed files with 474 additions and 34 deletions

View File

@@ -21,6 +21,13 @@ public sealed class MinintDocument
public List<MinintLayer> Layers { get; }
/// <summary>
/// Reverse lookup cache: RgbaColor → palette index. Built lazily, invalidated
/// on structural palette changes (compact, clear). Call <see cref="InvalidatePaletteCache"/>
/// after bulk palette modifications.
/// </summary>
private Dictionary<RgbaColor, int>? _paletteCache;
public MinintDocument(string name)
{
Name = name;
@@ -50,4 +57,48 @@ public sealed class MinintDocument
<= 16_777_215 => 3,
_ => 4
};
/// <summary>
/// O(1) lookup of a color in the palette. Returns the index, or -1 if not found.
/// Lazily builds an internal dictionary on first call.
/// </summary>
public int FindColorCached(RgbaColor color)
{
var cache = EnsurePaletteCache();
return cache.TryGetValue(color, out int idx) ? idx : -1;
}
/// <summary>
/// Returns the index of <paramref name="color"/>. If absent, appends it to the palette
/// and updates the cache. O(1) amortized.
/// </summary>
public int EnsureColorCached(RgbaColor color)
{
var cache = EnsurePaletteCache();
if (cache.TryGetValue(color, out int idx))
return idx;
idx = Palette.Count;
Palette.Add(color);
cache[color] = idx;
return idx;
}
/// <summary>
/// Drops the reverse lookup cache. Must be called after any operation that
/// reorders, removes, or bulk-replaces palette entries (e.g. compact, grayscale).
/// </summary>
public void InvalidatePaletteCache() => _paletteCache = null;
private Dictionary<RgbaColor, int> EnsurePaletteCache()
{
if (_paletteCache is not null)
return _paletteCache;
var cache = new Dictionary<RgbaColor, int>(Palette.Count);
for (int i = 0; i < Palette.Count; i++)
cache.TryAdd(Palette[i], i); // first occurrence wins (for dupes)
_paletteCache = cache;
return cache;
}
}