Skip to content

Commit c6f8a33

Browse files
committed
Make bulk SF trim O(S) with a single range removal in drainTrimmable
drainTrimmable retired fully-acked sealed segments with per-element remove(0), shifting the remaining suffix on every iteration -- a bulk trim of S segments cost O(S^2) element moves. Collect the eligible prefix first, then remove it with one ObjList.remove(0, eligible - 1) range removal (inclusive bounds), all under the same monitor as before, so the I/O thread's snapshotSealedSegments() still cannot observe a partially shifted list. Covered by the existing multi-segment bulk-drain assertion in SegmentRingTest.
1 parent 76db2e0 commit c6f8a33

1 file changed

Lines changed: 11 additions & 4 deletions

File tree

  • core/src/main/java/io/questdb/client/cutlass/qwp/client/sf/cursor

core/src/main/java/io/questdb/client/cutlass/qwp/client/sf/cursor/SegmentRing.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -573,9 +573,13 @@ public synchronized ObjList<MmapSegment> drainTrimmable() {
573573
// Sealed segments are in baseSeq order, oldest first; once we hit one
574574
// that isn't fully acked, none of the later ones can be either.
575575
// Synchronized so the I/O thread's snapshotSealedSegments() can't
576-
// race against the remove(0) shuffling slots underneath it.
577-
while (sealedSegments.size() > 0) {
578-
MmapSegment s = sealedSegments.get(0);
576+
// race against the range removal shuffling slots underneath it.
577+
// Collect the eligible prefix first, then remove it with a single
578+
// range removal -- per-element remove(0) would shift the suffix on
579+
// every iteration, making a bulk trim of S segments O(S^2).
580+
int eligible = 0;
581+
for (int i = 0, n = sealedSegments.size(); i < n; i++) {
582+
MmapSegment s = sealedSegments.get(i);
579583
long lastSeq = s.baseSeq() + s.frameCount() - 1;
580584
if (lastSeq > acked) {
581585
break;
@@ -584,7 +588,10 @@ public synchronized ObjList<MmapSegment> drainTrimmable() {
584588
out = new ObjList<>();
585589
}
586590
out.add(s);
587-
sealedSegments.remove(0);
591+
eligible++;
592+
}
593+
if (eligible > 0) {
594+
sealedSegments.remove(0, eligible - 1);
588595
}
589596
return out;
590597
}

0 commit comments

Comments
 (0)