@libp2p/utils 5.3.2 → 5.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/src/filters/bloom-filter.d.ts +34 -0
  2. package/dist/src/filters/bloom-filter.d.ts.map +1 -0
  3. package/dist/src/filters/bloom-filter.js +113 -0
  4. package/dist/src/filters/bloom-filter.js.map +1 -0
  5. package/dist/src/filters/bucket.d.ts +10 -0
  6. package/dist/src/filters/bucket.d.ts.map +1 -0
  7. package/dist/src/filters/bucket.js +53 -0
  8. package/dist/src/filters/bucket.js.map +1 -0
  9. package/dist/src/filters/cuckoo-filter.d.ts +41 -0
  10. package/dist/src/filters/cuckoo-filter.d.ts.map +1 -0
  11. package/dist/src/filters/cuckoo-filter.js +134 -0
  12. package/dist/src/filters/cuckoo-filter.js.map +1 -0
  13. package/dist/src/filters/fingerprint.d.ts +11 -0
  14. package/dist/src/filters/fingerprint.d.ts.map +1 -0
  15. package/dist/src/filters/fingerprint.js +34 -0
  16. package/dist/src/filters/fingerprint.js.map +1 -0
  17. package/dist/src/filters/hashes.d.ts +8 -0
  18. package/dist/src/filters/hashes.d.ts.map +1 -0
  19. package/dist/src/filters/hashes.js +29 -0
  20. package/dist/src/filters/hashes.js.map +1 -0
  21. package/dist/src/filters/index.d.ts +9 -0
  22. package/dist/src/filters/index.d.ts.map +1 -0
  23. package/dist/src/filters/index.js +4 -0
  24. package/dist/src/filters/index.js.map +1 -0
  25. package/dist/src/filters/scalable-cuckoo-filter.d.ts +24 -0
  26. package/dist/src/filters/scalable-cuckoo-filter.d.ts.map +1 -0
  27. package/dist/src/filters/scalable-cuckoo-filter.js +87 -0
  28. package/dist/src/filters/scalable-cuckoo-filter.js.map +1 -0
  29. package/dist/src/filters/utils.d.ts +2 -0
  30. package/dist/src/filters/utils.d.ts.map +1 -0
  31. package/dist/src/filters/utils.js +4 -0
  32. package/dist/src/filters/utils.js.map +1 -0
  33. package/package.json +15 -7
  34. package/src/filters/bloom-filter.ts +142 -0
  35. package/src/filters/bucket.ts +64 -0
  36. package/src/filters/cuckoo-filter.ts +197 -0
  37. package/src/filters/fingerprint.ts +44 -0
  38. package/src/filters/hashes.ts +38 -0
  39. package/src/filters/index.ts +9 -0
  40. package/src/filters/scalable-cuckoo-filter.ts +111 -0
  41. package/src/filters/utils.ts +3 -0
@@ -0,0 +1,111 @@
1
+ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
2
+ import { CuckooFilter, optimize, type CuckooFilterInit } from './cuckoo-filter.js'
3
+ import { fnv1a, type Hash } from './hashes.js'
4
+ import { getRandomInt } from './utils.js'
5
+ import type { Filter } from './index.js'
6
+
7
+ export interface ScalableCuckooFilterInit extends CuckooFilterInit {
8
+ /**
9
+ * A number to multiply maxItems by when adding new sub-filters
10
+ */
11
+ scale?: number
12
+ }
13
+
14
+ export class ScalableCuckooFilter implements Filter {
15
+ private readonly filterSize: number
16
+ private readonly bucketSize: number
17
+ private readonly fingerprintSize: number
18
+ private readonly scale: number
19
+ private readonly filterSeries: CuckooFilter[]
20
+ private readonly hash: Hash
21
+ private readonly seed: number
22
+
23
+ constructor (init: ScalableCuckooFilterInit) {
24
+ this.bucketSize = init.bucketSize ?? 4
25
+ this.filterSize = init.filterSize ?? (1 << 18) / this.bucketSize
26
+ this.fingerprintSize = init.fingerprintSize ?? 2
27
+ this.scale = init.scale ?? 2
28
+ this.hash = init.hash ?? fnv1a
29
+ this.seed = init.seed ?? getRandomInt(0, Math.pow(2, 10))
30
+ this.filterSeries = [
31
+ new CuckooFilter({
32
+ filterSize: this.filterSize,
33
+ bucketSize: this.bucketSize,
34
+ fingerprintSize: this.fingerprintSize,
35
+ hash: this.hash,
36
+ seed: this.seed
37
+ })
38
+ ]
39
+ }
40
+
41
+ add (item: Uint8Array | string): boolean {
42
+ if (typeof item === 'string') {
43
+ item = uint8ArrayFromString(item)
44
+ }
45
+
46
+ if (this.has(item)) {
47
+ return true
48
+ }
49
+
50
+ let current = this.filterSeries.find((cuckoo) => {
51
+ return cuckoo.reliable
52
+ })
53
+
54
+ if (current == null) {
55
+ const curSize = this.filterSize * Math.pow(this.scale, this.filterSeries.length)
56
+
57
+ current = new CuckooFilter({
58
+ filterSize: curSize,
59
+ bucketSize: this.bucketSize,
60
+ fingerprintSize: this.fingerprintSize,
61
+ hash: this.hash,
62
+ seed: this.seed
63
+ })
64
+
65
+ this.filterSeries.push(current)
66
+ }
67
+
68
+ return current.add(item)
69
+ }
70
+
71
+ has (item: Uint8Array | string): boolean {
72
+ if (typeof item === 'string') {
73
+ item = uint8ArrayFromString(item)
74
+ }
75
+
76
+ for (let i = 0; i < this.filterSeries.length; i++) {
77
+ if (this.filterSeries[i].has(item)) {
78
+ return true
79
+ }
80
+ }
81
+
82
+ return false
83
+ }
84
+
85
+ remove (item: Uint8Array | string): boolean {
86
+ if (typeof item === 'string') {
87
+ item = uint8ArrayFromString(item)
88
+ }
89
+
90
+ for (let i = 0; i < this.filterSeries.length; i++) {
91
+ if (this.filterSeries[i].remove(item)) {
92
+ return true
93
+ }
94
+ }
95
+
96
+ return false
97
+ }
98
+
99
+ get count (): number {
100
+ return this.filterSeries.reduce((acc, curr) => {
101
+ return acc + curr.count
102
+ }, 0)
103
+ }
104
+ }
105
+
106
+ export function createScalableCuckooFilter (maxItems: number, errorRate: number = 0.001, options?: Pick<ScalableCuckooFilterInit, 'hash' | 'seed' | 'scale'>): Filter {
107
+ return new ScalableCuckooFilter({
108
+ ...optimize(maxItems, errorRate),
109
+ ...(options ?? {})
110
+ })
111
+ }
@@ -0,0 +1,3 @@
1
+ export function getRandomInt (min: number, max: number): number {
2
+ return Math.floor(Math.random() * (max - min)) + min
3
+ }