From 220b402b3be785bf6de1d5c5cd9338c8767c2da9 Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Wed, 2 Jul 2025 18:43:41 -0400 Subject: [PATCH] Optimize the append method to check if the data is already sorted --- src/types/CircularQueue.ts | 7 ++++++- test/types/CircularQueue.test.ts | 29 +++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/types/CircularQueue.ts b/src/types/CircularQueue.ts index 9ef6ca0..8d7db7d 100644 --- a/src/types/CircularQueue.ts +++ b/src/types/CircularQueue.ts @@ -38,6 +38,9 @@ export class CircularQueue { return; } + const lastItem = this.get(this._size - 1); + const isAlreadyInOrder = lastItem && sortingCallback(lastItem, data) <= 0; + if (this._size < this._capacity) { this.endIndex = (this.endIndex + 1) % this._capacity; this._data[this.endIndex] = data; @@ -48,7 +51,9 @@ export class CircularQueue { this._data[this.endIndex] = data; } - this.sortData(sortingCallback); + if (!isAlreadyInOrder) { + this.sortData(sortingCallback); + } } popFront = () => { diff --git a/test/types/CircularQueue.test.ts b/test/types/CircularQueue.test.ts index 60ac085..748396d 100644 --- a/test/types/CircularQueue.test.ts +++ b/test/types/CircularQueue.test.ts @@ -69,6 +69,31 @@ describe("CircularQueue", () => { expect(queue.size()).toBe(1); expect(queue.get(0)).toEqual(testItems.test); }); + + it("optimizes append when items are already in order", () => { + const queue = new CircularQueue(5); + let sortCallCount = 0; + + const trackingSortCallback = (a: TestItem, b: TestItem) => { + sortCallCount++; + return a.id - b.id; + }; + + queue.appendWithSorting(testItems.first, trackingSortCallback); + expect(sortCallCount).toBe(0); + + queue.appendWithSorting(testItems.second, trackingSortCallback); + expect(sortCallCount).toBe(1); + + queue.appendWithSorting(testItems.third, trackingSortCallback); + expect(sortCallCount).toBe(2); + + queue.appendWithSorting({ id: 0, value: "zero" }, trackingSortCallback); + expect(sortCallCount).toBeGreaterThan(3); + + expect(queue.get(0)).toEqual({ id: 0, value: "zero" }); + expect(queue.get(1)).toEqual(testItems.first); + }); }); describe("popFront", () => { @@ -150,7 +175,7 @@ describe("CircularQueue", () => { it("maintains sorted order assumption", () => { const queue = createQueueWithItems(5, [testItems.d, testItems.a, testItems.c, testItems.b], sortingCallbacks.byValue); - + expect(queue.binarySearch("a", keyExtractors.value)).toEqual(testItems.a); expect(queue.binarySearch("b", keyExtractors.value)).toEqual(testItems.b); expect(queue.binarySearch("c", keyExtractors.value)).toEqual(testItems.c); @@ -173,4 +198,4 @@ describe("CircularQueue", () => { expect(queue.binarySearch(4, keyExtractors.id)).toEqual(testItems.fourth); }); }); -}); \ No newline at end of file +});