1
1
/*
2
- * Copyright (c) 2016-2021 Digital Bazaar, Inc. All rights reserved.
2
+ * Copyright (c) 2016-2023 Digital Bazaar, Inc. All rights reserved.
3
3
*/
4
4
'use strict' ;
5
5
@@ -9,12 +9,14 @@ module.exports = class IdentifierIssuer {
9
9
* identifiers, keeping track of any previously issued identifiers.
10
10
*
11
11
* @param prefix the prefix to use ('<prefix><counter>').
12
- * @param existing an existing Map to use.
12
+ * @param existing an existing refs and Map object to use.
13
13
* @param counter the counter to use.
14
14
*/
15
- constructor ( prefix , existing = new Map ( ) , counter = 0 ) {
15
+ constructor ( prefix , existing = { refs : 0 , map : new Map ( ) } , counter = 0 ) {
16
16
this . prefix = prefix ;
17
- this . _existing = existing ;
17
+ this . existing = existing ;
18
+ // add ref to shared map
19
+ this . existing . refs ++ ;
18
20
this . counter = counter ;
19
21
}
20
22
@@ -24,8 +26,8 @@ module.exports = class IdentifierIssuer {
24
26
* @return a copy of this IdentifierIssuer.
25
27
*/
26
28
clone ( ) {
27
- const { prefix, _existing , counter} = this ;
28
- return new IdentifierIssuer ( prefix , new Map ( _existing ) , counter ) ;
29
+ const { prefix, existing , counter} = this ;
30
+ return new IdentifierIssuer ( prefix , existing , counter ) ;
29
31
}
30
32
31
33
/**
@@ -38,7 +40,7 @@ module.exports = class IdentifierIssuer {
38
40
*/
39
41
getId ( old ) {
40
42
// return existing old identifier
41
- const existing = old && this . _existing . get ( old ) ;
43
+ const existing = old && this . existing . map . get ( old ) ;
42
44
if ( existing ) {
43
45
return existing ;
44
46
}
@@ -49,7 +51,26 @@ module.exports = class IdentifierIssuer {
49
51
50
52
// save mapping
51
53
if ( old ) {
52
- this . _existing . set ( old , identifier ) ;
54
+ if ( this . existing . refs > 1 ) {
55
+ // copy-on-write shared map
56
+ // TODO: improve copy-on-write reference handling
57
+ // - current code handles copying the 'existing' maps when it is
58
+ // shared
59
+ // - it will remove a reference when doing a copy
60
+ // - a reference is NOT removed when a copy is no longer used
61
+ // - need a `release()` call or similar to do this and add it
62
+ // throughout the code as needed
63
+ // - this won't result in errors, only extra copies if a child does
64
+ // not do an update, is done, and a parent then does an update
65
+ // unref shared map
66
+ this . existing . refs -- ;
67
+ // copy to new map
68
+ this . existing = {
69
+ refs : 1 ,
70
+ map : new Map ( this . existing . map )
71
+ } ;
72
+ }
73
+ this . existing . map . set ( old , identifier ) ;
53
74
}
54
75
55
76
return identifier ;
@@ -65,7 +86,7 @@ module.exports = class IdentifierIssuer {
65
86
* false if not.
66
87
*/
67
88
hasId ( old ) {
68
- return this . _existing . has ( old ) ;
89
+ return this . existing . map . has ( old ) ;
69
90
}
70
91
71
92
/**
@@ -75,6 +96,6 @@ module.exports = class IdentifierIssuer {
75
96
* @return the list of old IDs that has been issued new IDs in order.
76
97
*/
77
98
getOldIds ( ) {
78
- return [ ...this . _existing . keys ( ) ] ;
99
+ return [ ...this . existing . map . keys ( ) ] ;
79
100
}
80
101
} ;
0 commit comments