Skip to content

Commit 2b395b6

Browse files
committed
✨ handle undefined key-values in InvertedIndexMap
1 parent 334feb5 commit 2b395b6

2 files changed

Lines changed: 70 additions & 0 deletions

File tree

src/lang.spec.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,4 +706,71 @@ describe("Lang.InvertedIndexMap", () => {
706706
expect(age40Results.length).toBe(50);
707707
expect(peopleIndex.size).toBe(100);
708708
});
709+
710+
test("should return undefined for non-existent keys", () => {
711+
const alice: Person = { id: "p1", name: "Alice", age: 30 };
712+
peopleIndex.add(alice);
713+
714+
expect(peopleIndex.get("nonexistent")).toBeUndefined();
715+
});
716+
717+
test("should ignore undefined values in query", () => {
718+
const alice: Person = { id: "p1", name: "Alice", age: 30 };
719+
const bob: Person = { id: "p2", name: "Bob", age: 25 };
720+
peopleIndex.add(alice);
721+
peopleIndex.add(bob);
722+
723+
// Query with undefined field should ignore that field
724+
const result = peopleIndex.query({ name: "Alice", age: undefined });
725+
expect(result).toEqual([alice]);
726+
});
727+
728+
test("should handle multiple fields with same value", () => {
729+
const alice1: Person = { id: "p1", name: "Alice", age: 30 };
730+
const alice2: Person = { id: "p2", name: "Alice", age: 30 };
731+
const bob: Person = { id: "p3", name: "Bob", age: 30 };
732+
733+
peopleIndex.add(alice1);
734+
peopleIndex.add(alice2);
735+
peopleIndex.add(bob);
736+
737+
const result = peopleIndex.query({ name: "Alice", age: 30 });
738+
expect(result.sort((a, b) => a.id.localeCompare(b.id))).toEqual(
739+
[alice1, alice2].sort((a, b) => a.id.localeCompare(b.id)),
740+
);
741+
});
742+
743+
test("should maintain index integrity with multiple add/remove operations", () => {
744+
const alice: Person = { id: "p1", name: "Alice", age: 30 };
745+
const bob: Person = { id: "p2", name: "Bob", age: 25 };
746+
747+
peopleIndex.add(alice);
748+
peopleIndex.add(bob);
749+
peopleIndex.add({ ...alice, age: 31 }); // Update alice
750+
peopleIndex.add({ ...bob, name: "Bobby" }); // Update bob
751+
752+
expect(peopleIndex.query({ age: 30 })).toEqual([]);
753+
expect(peopleIndex.query({ age: 31 })).toEqual([{ ...alice, age: 31 }]);
754+
expect(peopleIndex.query({ name: "Bob" })).toEqual([]);
755+
expect(peopleIndex.query({ name: "Bobby" })).toEqual([
756+
{ ...bob, name: "Bobby" },
757+
]);
758+
});
759+
760+
test("should handle field values changing between numeric and string types", () => {
761+
interface FlexibleRecord {
762+
id: string;
763+
value: string | number;
764+
}
765+
766+
const flexIndex = new Lang.InvertedIndexMap<FlexibleRecord>((r) => r.id);
767+
768+
const record = { id: "r1", value: "123" };
769+
flexIndex.add(record);
770+
expect(flexIndex.query({ value: "123" })).toEqual([record]);
771+
772+
const updated = { id: "r1", value: 123 };
773+
flexIndex.add(updated);
774+
expect(flexIndex.query({ value: 123 })).toEqual([updated]);
775+
});
709776
});

src/lang.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,9 @@ export class InvertedIndexMap<R extends Record<keyof R, unknown>> {
587587
const matched = new Set<number>();
588588
let first = true;
589589
for (const [qk, qv] of qentries) {
590+
if (qv === undefined) {
591+
continue;
592+
}
590593
const idx = this.invIdxes[qk];
591594
if (!idx) {
592595
// unknown field

0 commit comments

Comments
 (0)