From 55736cc2db2c691e37ad8a4322891390bcbd2c76 Mon Sep 17 00:00:00 2001 From: Maciej Aszyk Date: Mon, 6 May 2024 15:28:19 +0200 Subject: [PATCH] RavenDB-21900 When query has no load, use small cache to avoid persisting document too long. --- .../Documents/DocumentsStorage.cs | 4 +- .../Queries/CollectionQueryEnumerable.cs | 58 ++----------------- .../Queries/Results/QueriedDocumentCache.cs | 3 +- .../Results/QueryResultRetrieverBase.cs | 12 ++-- 4 files changed, 16 insertions(+), 61 deletions(-) diff --git a/src/Raven.Server/Documents/DocumentsStorage.cs b/src/Raven.Server/Documents/DocumentsStorage.cs index c2efca38793..e7ed620c282 100644 --- a/src/Raven.Server/Documents/DocumentsStorage.cs +++ b/src/Raven.Server/Documents/DocumentsStorage.cs @@ -1038,7 +1038,7 @@ public IEnumerable GetDocuments(DocumentsOperationContext listOfIds.Add(slice); } - return GetDocuments(context, listOfIds, start, take); + return GetDocuments(context, listOfIds, start, take); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1049,7 +1049,7 @@ public IEnumerable GetDocumentsForCollection(DocumentsOper where TDocument : Document, new() { // we'll fetch all documents and do the filtering here since we must check the collection name - foreach (var doc in GetDocuments(context, ids, start, int.MaxValue, totalCount)) + foreach (var doc in GetDocuments(context, ids, start, int.MaxValue)) { if (collection == Constants.Documents.Collections.AllDocumentsCollection) { diff --git a/src/Raven.Server/Documents/Queries/CollectionQueryEnumerable.cs b/src/Raven.Server/Documents/Queries/CollectionQueryEnumerable.cs index e99f78549fa..fe6fd746b41 100644 --- a/src/Raven.Server/Documents/Queries/CollectionQueryEnumerable.cs +++ b/src/Raven.Server/Documents/Queries/CollectionQueryEnumerable.cs @@ -361,7 +361,6 @@ private void CountDocumentsInEnumerator(bool countQuery) if (_fieldsToFetch.IsProjection) { - RetrieverInput retrieverInput = new(null, QueryResultRetrieverBase.ZeroScore, null); var result = _resultsRetriever.GetProjectionFromDocument(_inner.Current, ref retrieverInput, _fieldsToFetch, _context, _token); if (result.List != null) { @@ -464,7 +463,7 @@ private void ConfigureStreamForUnboundedQueries() _totalResultsCalculated = true; } } - + private void Initialize(out bool processedAllDocuments) { _initialized = true; @@ -474,56 +473,8 @@ private void Initialize(out bool processedAllDocuments) if (start == 0) { - var count = 0; - foreach (var document in _documents.GetDocumentsFrom(_context, _collection, 0, start, _query.PageSize)) - { - count++; - RetrieverInput retrieverInput = new(null, QueryResultRetrieverCommon.ZeroScore, null); - if (_fieldsToFetch.IsProjection) - { - var result = _resultsRetriever.GetProjectionFromDocument(document, ref retrieverInput, _fieldsToFetch, _context, _token); - if (result.Document != null) - { - if (IsStartingPoint(result.Document)) - break; - } - else if (result.List != null) - { - bool match = false; - foreach (Document item in result.List) - { - if (IsStartingPoint(item)) - { - match = true; - break; - } - } - - if (match) - break; - } - } - else - { - if (IsStartingPoint(_inner.Current)) - { - break; - } - } - - bool IsStartingPoint(Document d) - { - return d.Data.Count > 0 && _alreadySeenProjections.Add(d.DataHash) && _alreadySeenProjections.Count == _query.Start; - } - } - - if (_alreadySeenProjections.Count == _query.Start) - break; - - if (count < _query.PageSize) - break; - - start += count; + _inner = GetDocuments(out _totalResultsCalculated, start).GetEnumerator(); + return; } if (_query.SkipDuplicateChecking) @@ -561,7 +512,6 @@ void ReleaseDocument() if (document != null) { document.Dispose(); - _context.Transaction.ForgetAbout(document); } } } @@ -580,7 +530,7 @@ bool IsStartingPoint(Document d) if (count < _query.Start) processedAllDocuments = true; } - + public void Reset() { throw new NotSupportedException(); diff --git a/src/Raven.Server/Documents/Queries/Results/QueriedDocumentCache.cs b/src/Raven.Server/Documents/Queries/Results/QueriedDocumentCache.cs index 3bbcf9bf5bd..6c641cbc94b 100644 --- a/src/Raven.Server/Documents/Queries/Results/QueriedDocumentCache.cs +++ b/src/Raven.Server/Documents/Queries/Results/QueriedDocumentCache.cs @@ -1,4 +1,5 @@ -using System.Diagnostics; +using System; +using System.Diagnostics; using System.Runtime.CompilerServices; using Raven.Server.ServerWide.Context; using Raven.Server.Utils; diff --git a/src/Raven.Server/Documents/Queries/Results/QueryResultRetrieverBase.cs b/src/Raven.Server/Documents/Queries/Results/QueryResultRetrieverBase.cs index fcb99e5138b..7f5d22a9d22 100644 --- a/src/Raven.Server/Documents/Queries/Results/QueryResultRetrieverBase.cs +++ b/src/Raven.Server/Documents/Queries/Results/QueryResultRetrieverBase.cs @@ -35,7 +35,8 @@ namespace Raven.Server.Documents.Queries.Results { public abstract class QueryResultRetrieverCommon { - public static readonly int LoadedDocumentsCacheSize = 16 * 1024; + public const int LoadedDocumentsCacheSize = 16 * 1024; + public const int NoLoadedDocumentsCacheSize = 32; public static readonly Lucene.Net.Search.ScoreDoc ZeroScore = new Lucene.Net.Search.ScoreDoc(-1, 0f); @@ -149,10 +150,13 @@ protected QueryResultRetrieverBase( DocumentFields = query?.DocumentFields ?? DocumentFields.All; _blittableTraverser = reduceResults ? BlittableJsonTraverser.FlatMapReduceResults : BlittableJsonTraverser.Default; - + + var cacheSize = query?.Metadata.HasIncludeOrLoad ?? false + ? LoadedDocumentsCacheSize + : NoLoadedDocumentsCacheSize; _loadedDocumentCache = typeof(TDocument) == typeof(QueriedDocument) && DocumentContext != null - ? (LruDictionary)(object)(new QueriedDocumentCache(DocumentContext, LoadedDocumentsCacheSize)) - : new LruDictionary(LoadedDocumentsCacheSize); + ? (LruDictionary)(object)(new QueriedDocumentCache(DocumentContext, cacheSize)) + : new LruDictionary(cacheSize); }