From 24d3b52e0b58747e6fb37567f084827cecfc6011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Mon, 22 Jul 2024 09:56:08 +0800 Subject: [PATCH] refactor: Message Unique --- src/common/utils/MessageUnique.ts | 94 +++++++++++++++++++++++++++---- 1 file changed, 82 insertions(+), 12 deletions(-) diff --git a/src/common/utils/MessageUnique.ts b/src/common/utils/MessageUnique.ts index 509dc750..db2e8d77 100644 --- a/src/common/utils/MessageUnique.ts +++ b/src/common/utils/MessageUnique.ts @@ -1,20 +1,63 @@ import crypto from 'crypto'; +class CircularQueue { + private items: T[] = []; + private front: number = 0; + private maxSize: number; + constructor(maxSize: number) { + this.maxSize = maxSize; + } + + enqueue(item: T): void { + if (this.items.length == this.maxSize) { + this.front = (this.front + 1) % this.maxSize; + } + this.items[(this.front + this.items.length) % this.maxSize] = item; + } + + dequeue(): T | undefined { + return this.items.length == 0 ? undefined : this.items[(this.front + 1) % this.items.length]; + } + + size(): number { + return this.items.length; + } +} + class LimitedHashTable { private keyToValue: Map = new Map(); private valueToKey: Map = new Map(); + private keyQueue: CircularQueue = new CircularQueue(0); + private valueQueue: CircularQueue = new CircularQueue(0); private maxSize: number; - private KeyQueneList: K[] = []; - private ValueQueneList: V[] = []; + constructor(maxSize: number) { this.maxSize = maxSize; } + + private removeFromQueues(key: K, value: V): void { + this.keyQueue.dequeue(); + this.valueQueue.dequeue(); + } + set(key: K, value: V): void { + let isExist = this.keyToValue.get(key); + if (isExist && isExist === value) { + return; + } this.keyToValue.set(key, value); this.valueToKey.set(value, key); - if (this.KeyQueneList.length >= this.maxSize || this.ValueQueneList.length >= this.maxSize) { - this.KeyQueneList.shift(); - this.ValueQueneList.shift(); + this.keyQueue.enqueue(key); + this.valueQueue.enqueue(value); + + if (this.keyQueue.size() > this.maxSize || this.valueQueue.size() > this.maxSize) { + const removedKey = this.keyQueue.dequeue(); + const removedValue = this.valueQueue.dequeue(); + if (removedKey !== undefined && removedValue !== undefined) { + this.keyToValue.delete(removedKey); + this.valueToKey.delete(removedValue); + this.removeFromQueues(removedKey, removedValue); + } } } @@ -26,27 +69,54 @@ class LimitedHashTable { return this.valueToKey.get(value); } - delete(key: K): void { + deleteByValue(value: V) { + const key = this.valueToKey.get(value); + if (key !== undefined) { + this.keyToValue.delete(key); + this.valueToKey.delete(value); + this.removeFromQueues(key, value); + } + } + + deleteByKey(key: K): void { const value = this.keyToValue.get(key); if (value !== undefined) { this.keyToValue.delete(key); this.valueToKey.delete(value); + this.removeFromQueues(key, value); } } } class MessageUniqueWrapper { - private msgIdMap: LimitedHashTable = new LimitedHashTable(1000); + private msgIdMap: LimitedHashTable; + constructor(MaxMap: number = 1000) { + this.msgIdMap = new LimitedHashTable(MaxMap); + } + createMsg(MsgId: string) { - const ShortId = parseInt(crypto.createHash('sha1').update('2345').digest('hex').slice(0, 8), 16); - this.msgIdMap.set(ShortId, MsgId); - return ShortId; + const hash = crypto.createHash('sha256'); + hash.update(MsgId); + const ShortId = parseInt(hash.digest('hex').slice(0, 8), 16); + let isExist = this.msgIdMap.getKey(ShortId) + if (isExist && isExist === MsgId) { + return true; + } + return this.msgIdMap.set(MsgId, ShortId); } + getMsgIdByShortId(ShortId: number) { - return this.msgIdMap.getValue(ShortId); + return this.msgIdMap.getKey(ShortId); } + getShortIdByMsgId(MsgId: string) { - return this.msgIdMap.getKey(MsgId); + return this.msgIdMap.getValue(MsgId); + } + + CreateMsgIdList(MsgIdList: string[]) { + return MsgIdList.map((MsgId) => { + return this.createMsg(MsgId); + }); } }