Skip to content

Commit 070104f

Browse files
updated to store nextKeyId instead of lastKeyId
1 parent 221aad8 commit 070104f

File tree

1 file changed

+18
-17
lines changed

1 file changed

+18
-17
lines changed

src/main/java/com/uid2/admin/salt/KeyIdGenerator.java

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,49 +6,50 @@
66
import java.util.concurrent.atomic.AtomicInteger;
77

88
/**
9+
* Assumptions:
10+
* - The latest assigned key ids are from the latest updated buckets
11+
* - Key ids from these buckets will always be monotonically increasing (apart from wraparound) as they have not rotated again after last assignment
12+
*
913
* Intended outcomes of KeyIdGenerator:
10-
* - Key ids are always consecutive, starting from 0
14+
* - Key ids are always monotonically increasing, starting from 0
1115
* - When the last allocated key id reaches 16777215, the next key id will wrap around to 0
1216
* - Continuing to increment from the highest key id will result in monotonic incrementation of key ids for all newly rotated buckets
13-
*
14-
* Assumptions:
15-
* - The latest assigned key ids are from the latest updated buckets
16-
* - Key ids from these buckets will always be consecutive (apart from wraparound) as they have not rotated again after last assignment
17-
*/
17+
**/
1818
public class KeyIdGenerator {
1919
private static final int MAX_KEY_ID = 16777215; // 3 bytes
20-
private final AtomicInteger lastActiveKeyId;
20+
private final AtomicInteger nextActiveKeyId;
2121

2222
public KeyIdGenerator(SaltEntry[] buckets) {
23-
this.lastActiveKeyId = new AtomicInteger(getLastActiveKeyId(buckets));
23+
this.nextActiveKeyId = new AtomicInteger(getNextActiveKeyId(buckets));
2424
}
2525

26-
private static int getLastActiveKeyId(SaltEntry[] buckets) {
27-
long maxLastUpdated = Arrays.stream(buckets).mapToLong(SaltEntry::lastUpdated).max().orElse(0);
26+
private static int getNextActiveKeyId(SaltEntry[] buckets) {
27+
long lastUpdatedTimestampWithKey = Arrays.stream(buckets).filter(s -> s.currentKey() != null).mapToLong(SaltEntry::lastUpdated).max().orElse(0);
28+
if (lastUpdatedTimestampWithKey == 0) return 0;
29+
2830
int[] lastActiveKeyIdsSorted = Arrays.stream(buckets)
29-
.filter(s -> s.lastUpdated() == maxLastUpdated && s.currentKey() != null)
31+
.filter(s -> s.lastUpdated() == lastUpdatedTimestampWithKey && s.currentKey() != null)
3032
.mapToInt(s -> s.currentKey().id())
3133
.sorted()
3234
.toArray();
3335

34-
if (lastActiveKeyIdsSorted.length == 0) return MAX_KEY_ID; // so that next ID will start at 0
35-
3636
int highestId = lastActiveKeyIdsSorted[lastActiveKeyIdsSorted.length - 1];
3737

38-
if (highestId < MAX_KEY_ID) return highestId;
38+
int nextKeyId = highestId + 1;
39+
if (nextKeyId <= MAX_KEY_ID) return nextKeyId;
3940

4041
// Wrapped case - find the last consecutive ID from 0
4142
for (int i = 0; i < lastActiveKeyIdsSorted.length - 1; i++) {
4243
if (lastActiveKeyIdsSorted[i + 1] - lastActiveKeyIdsSorted[i] > 1) {
43-
return lastActiveKeyIdsSorted[i];
44+
return lastActiveKeyIdsSorted[i] + 1;
4445
}
4546
}
4647

47-
return highestId;
48+
return 0;
4849
}
4950

5051
public int getNextKeyId() {
51-
return lastActiveKeyId.updateAndGet(id ->
52+
return nextActiveKeyId.getAndUpdate(id ->
5253
id + 1 > MAX_KEY_ID ? 0 : id + 1
5354
);
5455
}

0 commit comments

Comments
 (0)