Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion src/BLite.Core/Indexing/RTreeIndex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using BLite.Core.Collections;
using BLite.Core.Indexing.Internal;
using System.Buffers;
using System.Diagnostics;

namespace BLite.Core.Indexing;

Expand Down Expand Up @@ -121,6 +122,12 @@ public IEnumerable<DocumentLocation> SearchNear(double latitude, double longitud
/// Returns all physical page IDs owned by this R-tree.
/// Used when dropping or rebuilding an index to free storage space.
/// </summary>
/// <remarks>
/// The walk does not take this index's lock. Callers must hold the lock that excludes writers
/// to the tree: the collection write lock during <c>VacuumAsync</c>'s rebuild, the index
/// manager's lock (which every index insert, update and delete also takes) when an index is
/// dropped, and a dropped collection is disposed before its pages are collected.
/// </remarks>
public IReadOnlyList<uint> CollectAllPages() => CollectAllPages(0);

/// <summary>
Expand All @@ -142,7 +149,15 @@ internal IReadOnlyList<uint> CollectAllPages(ulong transactionId)
while (stack.Count > 0)
{
uint pageId = stack.Pop();
if (pageId == 0 || !seen.Add(pageId)) continue;
if (pageId == 0) continue;
if (!seen.Add(pageId))
{
// Every node has exactly one parent, so reaching a page twice means a cycle or a
// shared child. The set keeps the walk finite and the page counted once, but the
// tree is corrupt.
Debug.Fail($"R-tree page {pageId} is reachable more than once from root {_rootPageId}.");
continue;
}
pages.Add(pageId);

_storage.ReadPage(pageId, transactionId == 0 ? null : transactionId, buffer);
Expand Down
2 changes: 1 addition & 1 deletion src/BLite.Core/VacuumOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public sealed class VacuumOptions
/// the existing index is kept. Index handles obtained earlier (for example from
/// <c>GetIndexAsync</c> or <c>CreateIndexAsync</c>) refer to the replaced tree afterwards and
/// must be fetched again. A query already running on the old tree while it is replaced may read
/// pages that are being freed. Spatial indexes are not rebuilt.
/// pages that are being freed. Spatial (R-tree) indexes are rebuilt the same way.
/// </para>
/// </summary>
public bool RebuildIndexes { get; init; } = false;
Expand Down
Loading