4040import org .elasticsearch .search .rank .RankDoc ;
4141import org .elasticsearch .search .rank .RankDocShardInfo ;
4242import org .elasticsearch .tasks .TaskCancelledException ;
43+ import org .elasticsearch .transport .LeakTracker ;
4344import org .elasticsearch .xcontent .XContentType ;
4445
4546import java .io .IOException ;
@@ -302,23 +303,20 @@ private static HitContext prepareNonNestedHitContext(
302303
303304 String id = idLoader .getId (subDocId );
304305 if (id == null ) {
305- SearchHit hit = new SearchHit (docId );
306+ MemoryAccountingBytesRefCounted memAccountingRefCounted = MemoryAccountingBytesRefCounted .create (circuitBreaker );
307+ SearchHit hit = new SearchHit (docId , null , null , LeakTracker .wrap (memAccountingRefCounted ));
306308 // TODO: can we use real pooled buffers here as well?
307- Source source = Source .lazy (lazyStoredSourceLoader (profiler , subReaderContext , subDocId , hit , circuitBreaker ));
309+ Source source = Source .lazy (lazyStoredSourceLoader (profiler , subReaderContext , subDocId , memAccountingRefCounted ));
308310 return new HitContext (hit , subReaderContext , subDocId , Map .of (), source , rankDoc );
309311 } else {
310- SearchHit hit = new SearchHit (docId , id );
312+ MemoryAccountingBytesRefCounted memAccountingRefCounted = MemoryAccountingBytesRefCounted .create (circuitBreaker );
313+ SearchHit hit = new SearchHit (docId , id , null , LeakTracker .wrap (memAccountingRefCounted ));
311314 Source source ;
312315 if (requiresSource ) {
313316 Timer timer = profiler .startLoadingSource ();
314317 try {
315318 source = sourceLoader .source (leafStoredFieldLoader , subDocId );
316- MemoryAccountingBytesRefCounted sourceRef = MemoryAccountingBytesRefCounted .createAndAccountForBytes (
317- source .internalSourceRef (),
318- circuitBreaker ,
319- "fetch phase source loader"
320- );
321- hit .unfilteredSource (sourceRef );
319+ memAccountingRefCounted .account (source .internalSourceRef ().length (), "fetch phase source loader" );
322320 } catch (CircuitBreakingException e ) {
323321 hit .decRef ();
324322 throw e ;
@@ -328,7 +326,7 @@ private static HitContext prepareNonNestedHitContext(
328326 }
329327 }
330328 } else {
331- source = Source .lazy (lazyStoredSourceLoader (profiler , subReaderContext , subDocId , hit , circuitBreaker ));
329+ source = Source .lazy (lazyStoredSourceLoader (profiler , subReaderContext , subDocId , memAccountingRefCounted ));
332330 }
333331 return new HitContext (hit , subReaderContext , subDocId , leafStoredFieldLoader .storedFields (), source , rankDoc );
334332 }
@@ -338,28 +336,15 @@ private static Supplier<Source> lazyStoredSourceLoader(
338336 Profiler profiler ,
339337 LeafReaderContext ctx ,
340338 int doc ,
341- SearchHit hit ,
342- CircuitBreaker circuitBreaker
339+ MemoryAccountingBytesRefCounted memAccountingRefCounted
343340 ) {
344341 return () -> {
345342 StoredFieldLoader rootLoader = profiler .storedFields (StoredFieldLoader .create (true , Collections .emptySet ()));
346343 try {
347344 LeafStoredFieldLoader leafRootLoader = rootLoader .getLoader (ctx , null );
348345 leafRootLoader .advanceTo (doc );
349346 BytesReference source = leafRootLoader .source ();
350- MemoryAccountingBytesRefCounted memAccountingSourceRef = MemoryAccountingBytesRefCounted .createAndAccountForBytes (
351- source ,
352- circuitBreaker ,
353- "fetch phase source loader"
354- );
355- // Saving the entire source we loaded in the hit, so that we can release it entirely when the hit is released
356- // This is important for the circuit breaker accounting - note that this lazy loader can be triggered in the case of
357- // inner hits even though the top hit source is not requested (see {@link FetchPhase#prepareNestedHitContext} when
358- // the `nestedSource` is created), so we need to save the entire source on the hit - we account
359- // for the top level source via the {@link SearchHit#unfilteredSourceRef(BytesReference)} method because the
360- // {@link SearchHit#source()} method can be null when the top level source is not requested.
361- // NB all of the above also applies for source filtering and field collapsing
362- hit .unfilteredSource (memAccountingSourceRef );
347+ memAccountingRefCounted .account (source .length (), "fetch phase source loader" );
363348 return Source .fromBytes (source );
364349 } catch (IOException e ) {
365350 throw new UncheckedIOException (e );
@@ -404,7 +389,6 @@ private static HitContext prepareNestedHitContext(
404389 if (requiresSource ) {
405390 BytesReference source = leafRootLoader .source ();
406391 if (source != null ) {
407- NOOP_CIRCUIT_BREAKER .addEstimateBytesAndMaybeBreak (source .length (), "fetch phase nested hit source loader" );
408392 rootSource = Source .fromBytes (source );
409393 }
410394 }
0 commit comments