@@ -2,22 +2,42 @@ import { getMD5Hash } from '../obfuscation';
2
2
3
3
import { LRUCache } from './lru-cache' ;
4
4
5
+ export type AssignmentCacheValue = {
6
+ allocationKey : string ;
7
+ variationKey : string ;
8
+ } ;
9
+
5
10
export type AssignmentCacheKey = {
6
11
subjectKey : string ;
7
12
flagKey : string ;
8
- allocationKey : string ;
9
- variationKey : string ;
10
13
} ;
11
14
15
+ export type AssignmentCacheEntry = AssignmentCacheKey & AssignmentCacheValue ;
16
+
17
+ /** Converts an {@link AssignmentCacheKey} to a string. */
18
+ export function assignmentCacheKeyToString ( { subjectKey, flagKey } : AssignmentCacheKey ) : string {
19
+ return getMD5Hash ( [ subjectKey , flagKey ] . join ( ';' ) ) ;
20
+ }
21
+
22
+ export function assignmentCacheValueToString ( {
23
+ allocationKey,
24
+ variationKey,
25
+ } : AssignmentCacheValue ) : string {
26
+ return getMD5Hash ( [ allocationKey , variationKey ] . join ( ';' ) ) ;
27
+ }
28
+
12
29
export interface AsyncMap < K , V > {
13
30
get ( key : K ) : Promise < V | undefined > ;
31
+
14
32
set ( key : K , value : V ) : Promise < void > ;
33
+
15
34
has ( key : K ) : Promise < boolean > ;
16
35
}
17
36
18
37
export interface AssignmentCache {
19
- set ( key : AssignmentCacheKey ) : void ;
20
- has ( key : AssignmentCacheKey ) : boolean ;
38
+ set ( key : AssignmentCacheEntry ) : void ;
39
+
40
+ has ( key : AssignmentCacheEntry ) : boolean ;
21
41
}
22
42
23
43
export abstract class AbstractAssignmentCache < T extends Map < string , string > >
@@ -26,30 +46,29 @@ export abstract class AbstractAssignmentCache<T extends Map<string, string>>
26
46
// key -> variation value hash
27
47
protected constructor ( protected readonly delegate : T ) { }
28
48
29
- has ( key : AssignmentCacheKey ) : boolean {
30
- const isPresent = this . delegate . has ( this . toCacheKeyString ( key ) ) ;
31
- if ( ! isPresent ) {
32
- // no cache key present
33
- return false ;
34
- }
35
-
36
- // the subject has been assigned to a different variation
37
- // than was previously logged.
38
- // in this case we need to log the assignment again.
39
- const cachedValue = this . get ( key ) ;
40
- return cachedValue === getMD5Hash ( key . variationKey ) ;
49
+ /** Returns whether the provided {@link AssignmentCacheEntry} is present in the cache. */
50
+ has ( entry : AssignmentCacheEntry ) : boolean {
51
+ return this . get ( entry ) === assignmentCacheValueToString ( entry ) ;
41
52
}
42
53
43
54
private get ( key : AssignmentCacheKey ) : string | undefined {
44
- return this . delegate . get ( this . toCacheKeyString ( key ) ) ;
55
+ return this . delegate . get ( assignmentCacheKeyToString ( key ) ) ;
45
56
}
46
57
47
- set ( key : AssignmentCacheKey ) : void {
48
- this . delegate . set ( this . toCacheKeyString ( key ) , getMD5Hash ( key . variationKey ) ) ;
58
+ /**
59
+ * Stores the provided {@link AssignmentCacheEntry} in the cache. If the key already exists, it
60
+ * will be overwritten.
61
+ */
62
+ set ( entry : AssignmentCacheEntry ) : void {
63
+ this . delegate . set ( assignmentCacheKeyToString ( entry ) , assignmentCacheValueToString ( entry ) ) ;
49
64
}
50
65
51
- private toCacheKeyString ( { subjectKey, flagKey, allocationKey } : AssignmentCacheKey ) : string {
52
- return [ `subject:${ subjectKey } ` , `flag:${ flagKey } ` , `allocation:${ allocationKey } ` ] . join ( ';' ) ;
66
+ /**
67
+ * Returns an array with all {@link AssignmentCacheEntry} entries in the cache as an array of
68
+ * {@link string}s.
69
+ */
70
+ entries ( ) : IterableIterator < [ string , string ] > {
71
+ return this . delegate . entries ( ) ;
53
72
}
54
73
}
55
74
@@ -62,8 +81,8 @@ export abstract class AbstractAssignmentCache<T extends Map<string, string>>
62
81
export class NonExpiringInMemoryAssignmentCache extends AbstractAssignmentCache <
63
82
Map < string , string >
64
83
> {
65
- constructor ( ) {
66
- super ( new Map < string , string > ( ) ) ;
84
+ constructor ( store = new Map < string , string > ( ) ) {
85
+ super ( store ) ;
67
86
}
68
87
}
69
88
0 commit comments