Skip to content

Commit 39fbe08

Browse files
committed
vibe coding a summary data strcuture
1 parent bd32039 commit 39fbe08

File tree

1 file changed

+272
-0
lines changed

1 file changed

+272
-0
lines changed
Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
/**
2+
* Enum representing the types of events that can be tracked
3+
*/
4+
export enum EventType {
5+
EVALUATE = "evaluate",
6+
CHECK = "check",
7+
}
8+
9+
/**
10+
* Represents an event entry with its values
11+
*/
12+
interface EventEntry {
13+
hasTrue: boolean;
14+
hasFalse: boolean;
15+
}
16+
17+
/**
18+
* A simple bitset implementation for efficient boolean storage
19+
*/
20+
class BitSet {
21+
private bits: Uint32Array;
22+
23+
constructor(size: number = 32) {
24+
// Initialize with enough 32-bit integers to store the requested bits
25+
const arraySize = Math.ceil(size / 32);
26+
this.bits = new Uint32Array(arraySize);
27+
}
28+
29+
/**
30+
* Sets a bit at the specified position
31+
*/
32+
set(position: number, value: boolean): void {
33+
const index = Math.floor(position / 32);
34+
const offset = position % 32;
35+
36+
// Ensure we have enough space
37+
if (index >= this.bits.length) {
38+
const newSize = index + 1;
39+
const newBits = new Uint32Array(newSize);
40+
newBits.set(this.bits);
41+
this.bits = newBits;
42+
}
43+
44+
if (value) {
45+
// Set the bit
46+
this.bits[index] |= 1 << offset;
47+
} else {
48+
// Clear the bit
49+
this.bits[index] &= ~(1 << offset);
50+
}
51+
}
52+
53+
/**
54+
* Gets the bit at the specified position
55+
*/
56+
get(position: number): boolean {
57+
const index = Math.floor(position / 32);
58+
const offset = position % 32;
59+
60+
if (index >= this.bits.length) {
61+
return false;
62+
}
63+
64+
return (this.bits[index] & (1 << offset)) !== 0;
65+
}
66+
67+
/**
68+
* Checks if a bit is set at the specified position
69+
*/
70+
isSet(position: number): boolean {
71+
return this.get(position);
72+
}
73+
}
74+
75+
/**
76+
* SummaryEvent class that efficiently summarizes events by company ID and feature key
77+
* using bitsets for memory efficiency.
78+
*/
79+
export class SummaryEvent {
80+
// Store unique feature keys once to prevent duplication across companies
81+
private featureKeyMap: Map<string, number>; // Maps feature keys to unique IDs
82+
private featureKeyArray: string[]; // Array to lookup feature keys by their ID
83+
84+
// For each company and event type, we store:
85+
// 1. A bitset tracking true values
86+
// 2. A bitset tracking false values
87+
// 3. A bitset tracking which positions have been set
88+
private companies: Map<
89+
string,
90+
Map<
91+
EventType,
92+
{
93+
trueValues: BitSet;
94+
falseValues: BitSet;
95+
present: BitSet;
96+
}
97+
>
98+
>;
99+
100+
constructor() {
101+
this.featureKeyMap = new Map();
102+
this.featureKeyArray = [];
103+
this.companies = new Map();
104+
}
105+
106+
/**
107+
* Gets or creates a unique ID for a feature key
108+
*/
109+
private getFeatureKeyId(featureKey: string): number {
110+
let keyId = this.featureKeyMap.get(featureKey);
111+
if (keyId === undefined) {
112+
keyId = this.featureKeyArray.length;
113+
this.featureKeyMap.set(featureKey, keyId);
114+
this.featureKeyArray.push(featureKey);
115+
}
116+
return keyId;
117+
}
118+
119+
/**
120+
* Records an event occurrence
121+
*/
122+
public addEvent(
123+
companyId: string,
124+
featureKey: string,
125+
eventType: EventType,
126+
value: boolean,
127+
): void {
128+
const featureKeyId = this.getFeatureKeyId(featureKey);
129+
130+
// Get or create company entry
131+
let companyEvents = this.companies.get(companyId);
132+
if (!companyEvents) {
133+
companyEvents = new Map();
134+
this.companies.set(companyId, companyEvents);
135+
}
136+
137+
// Get or create event type entry
138+
let eventData = companyEvents.get(eventType);
139+
if (!eventData) {
140+
eventData = {
141+
trueValues: new BitSet(),
142+
falseValues: new BitSet(),
143+
present: new BitSet(),
144+
};
145+
companyEvents.set(eventType, eventData);
146+
}
147+
148+
// Mark the appropriate value bitset
149+
if (value) {
150+
eventData.trueValues.set(featureKeyId, true);
151+
} else {
152+
eventData.falseValues.set(featureKeyId, true);
153+
}
154+
155+
// Mark as present
156+
eventData.present.set(featureKeyId, true);
157+
}
158+
159+
/**
160+
* Gets all companies that have recorded events
161+
*/
162+
public getCompanies(): string[] {
163+
return Array.from(this.companies.keys());
164+
}
165+
166+
/**
167+
* Gets all feature keys for a specific company
168+
*/
169+
public getFeatureKeys(companyId: string): string[] {
170+
const companyEvents = this.companies.get(companyId);
171+
if (!companyEvents) {
172+
return [];
173+
}
174+
175+
// Collect all feature IDs that are present in any event type
176+
const featureIds = new Set<number>();
177+
for (const eventData of companyEvents.values()) {
178+
// For each bit that is set in the 'present' bitset, add the feature ID
179+
for (let i = 0; i < this.featureKeyArray.length; i++) {
180+
if (eventData.present.isSet(i)) {
181+
featureIds.add(i);
182+
}
183+
}
184+
}
185+
186+
// Convert feature IDs to feature keys
187+
return Array.from(featureIds).map((id) => this.featureKeyArray[id]);
188+
}
189+
190+
/**
191+
* Checks if an event exists for a given company, feature and event type
192+
*/
193+
public hasEvent(
194+
companyId: string,
195+
featureKey: string,
196+
eventType: EventType,
197+
): boolean {
198+
const featureKeyId = this.featureKeyMap.get(featureKey);
199+
if (featureKeyId === undefined) return false;
200+
201+
const companyEvents = this.companies.get(companyId);
202+
if (!companyEvents) return false;
203+
204+
const eventData = companyEvents.get(eventType);
205+
if (!eventData) return false;
206+
207+
return eventData.present.isSet(featureKeyId);
208+
}
209+
210+
/**
211+
* Gets the event value for a specific company, feature and event type
212+
*/
213+
public getEventDetails(
214+
companyId: string,
215+
featureKey: string,
216+
eventType: EventType,
217+
): EventEntry | undefined {
218+
const featureKeyId = this.featureKeyMap.get(featureKey);
219+
if (featureKeyId === undefined) return undefined;
220+
221+
const companyEvents = this.companies.get(companyId);
222+
if (!companyEvents) return undefined;
223+
224+
const eventData = companyEvents.get(eventType);
225+
if (!eventData || !eventData.present.isSet(featureKeyId)) return undefined;
226+
227+
const hasTrue = eventData.trueValues.isSet(featureKeyId);
228+
const hasFalse = eventData.falseValues.isSet(featureKeyId);
229+
230+
return { hasTrue, hasFalse };
231+
}
232+
233+
/**
234+
* Gets statistics about the stored events
235+
*/
236+
public getStats(): {
237+
companies: number;
238+
uniqueFeatures: number;
239+
totalFeatureReferences: number;
240+
} {
241+
let totalFeatureReferences = 0;
242+
243+
for (const companyEvents of this.companies.values()) {
244+
for (const eventData of companyEvents.values()) {
245+
// Count set bits in the present bitset
246+
let companyFeatureCount = 0;
247+
for (let i = 0; i < this.featureKeyArray.length; i++) {
248+
if (eventData.present.isSet(i)) {
249+
companyFeatureCount++;
250+
}
251+
}
252+
253+
totalFeatureReferences += companyFeatureCount;
254+
}
255+
}
256+
257+
return {
258+
companies: this.companies.size,
259+
uniqueFeatures: this.featureKeyArray.length,
260+
totalFeatureReferences,
261+
};
262+
}
263+
264+
/**
265+
* Clear all stored events
266+
*/
267+
public clear(): void {
268+
this.featureKeyMap.clear();
269+
this.featureKeyArray = [];
270+
this.companies.clear();
271+
}
272+
}

0 commit comments

Comments
 (0)