mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 16:02:26 +00:00
- Replaced `NostrClient.rawEvents` standard Map with `EventsMap` - Implemented `EventsMap` to maintain an author-based index - Updated `js/channelProfile.js` to use `getEventsByAuthor` for efficient lookup - Added unit tests for `EventsMap` - Added benchmark script verifying ~15x performance improvement (637ms -> 41ms for 1M events) Co-authored-by: PR0M3TH3AN <[email protected]>
91 lines
2.2 KiB
JavaScript
91 lines
2.2 KiB
JavaScript
/**
|
|
* A Map extension that maintains an author-based index for fast lookups.
|
|
* Used for `rawEvents` in NostrClient.
|
|
*/
|
|
export class EventsMap extends Map {
|
|
constructor(entries) {
|
|
super(entries);
|
|
this.authorIndex = new Map(); // pubkey -> Set<Event>
|
|
|
|
// If entries provided, index them
|
|
if (entries) {
|
|
for (const [key, value] of this.entries()) {
|
|
this._addToIndex(value);
|
|
}
|
|
}
|
|
}
|
|
|
|
_normalizePubkey(pubkey) {
|
|
if (typeof pubkey !== "string") return "";
|
|
return pubkey.trim().toLowerCase();
|
|
}
|
|
|
|
_addToIndex(event) {
|
|
if (!event || typeof event !== "object") return;
|
|
const pubkey = this._normalizePubkey(event.pubkey);
|
|
if (!pubkey) return;
|
|
|
|
let set = this.authorIndex.get(pubkey);
|
|
if (!set) {
|
|
set = new Set();
|
|
this.authorIndex.set(pubkey, set);
|
|
}
|
|
set.add(event);
|
|
}
|
|
|
|
_removeFromIndex(event) {
|
|
if (!event || typeof event !== "object") return;
|
|
const pubkey = this._normalizePubkey(event.pubkey);
|
|
if (!pubkey) return;
|
|
|
|
const set = this.authorIndex.get(pubkey);
|
|
if (set) {
|
|
set.delete(event);
|
|
if (set.size === 0) {
|
|
this.authorIndex.delete(pubkey);
|
|
}
|
|
}
|
|
}
|
|
|
|
set(key, value) {
|
|
const existing = this.get(key);
|
|
// If the value is identical, we still set it in the map,
|
|
// but the index doesn't strictly need updating.
|
|
// However, if the key was mapped to a DIFFERENT object with the SAME pubkey,
|
|
// we must update the Set (remove old object, add new object).
|
|
if (existing) {
|
|
if (existing === value) {
|
|
// No index change needed
|
|
return super.set(key, value);
|
|
}
|
|
this._removeFromIndex(existing);
|
|
}
|
|
|
|
super.set(key, value);
|
|
this._addToIndex(value);
|
|
return this;
|
|
}
|
|
|
|
delete(key) {
|
|
const value = this.get(key);
|
|
const result = super.delete(key);
|
|
if (result && value) {
|
|
this._removeFromIndex(value);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
clear() {
|
|
super.clear();
|
|
this.authorIndex.clear();
|
|
}
|
|
|
|
getEventsByAuthor(pubkey) {
|
|
const normalized = this._normalizePubkey(pubkey);
|
|
if (!normalized) return [];
|
|
const set = this.authorIndex.get(normalized);
|
|
// Return array to allow iteration
|
|
return set ? Array.from(set) : [];
|
|
}
|
|
}
|