@@ -44,6 +44,10 @@ public static Builder builder(Concurrency concurrency) {
4444 return new Builder (concurrency );
4545 }
4646
47+ public static Builder builder (Concurrency concurrency , long capacity ) {
48+ return new Builder (concurrency , capacity );
49+ }
50+
4751 private ShardedByteArrayLongMap (
4852 HugeObjectArray <byte []> internalNodeMapping ,
4953 ObjectLongMap <byte []>[] originalNodeMappingShards ,
@@ -108,14 +112,16 @@ private static <S extends MapShard> ShardedByteArrayLongMap build(
108112 var mapShards = new ObjectLongMap [shards .length ];
109113
110114 // ignoring concurrency limitation 🤷
111- Arrays .parallelSetAll (mapShards , idx -> {
112- var shard = shards [idx ];
113- var mapping = shard .intoMapping ();
114- mapping .forEachKeyValue ((originalId , mappedId ) -> {
115- internalNodeMapping .set (mappedId , originalId );
116- });
117- return mapping ;
118- });
115+ Arrays .parallelSetAll (
116+ mapShards , idx -> {
117+ var shard = shards [idx ];
118+ var mapping = shard .intoMapping ();
119+ mapping .forEachKeyValue ((originalId , mappedId ) -> {
120+ internalNodeMapping .set (mappedId , originalId );
121+ });
122+ return mapping ;
123+ }
124+ );
119125
120126 return new ShardedByteArrayLongMap (
121127 internalNodeMapping ,
@@ -148,6 +154,15 @@ public boolean equals(byte[] object1, byte[] object2) {
148154 this .lockWrapper = new AbstractMultiReaderMutableCollection .LockWrapper (lock );
149155 }
150156
157+ MapShard (long capacity ) {
158+ this .mapping = new ObjectLongHashMapWithHashingStrategy <>(
159+ new ArrayHashingStrategy (),
160+ Math .toIntExact (capacity )
161+ );
162+ this .lock = new ReentrantLock ();
163+ this .lockWrapper = new AbstractMultiReaderMutableCollection .LockWrapper (lock );
164+ }
165+
151166 final AbstractMultiReaderMutableCollection .LockWrapper acquireLock () {
152167 this .lock .lock ();
153168 return this .lockWrapper ;
@@ -179,6 +194,16 @@ public static final class Builder {
179194 .toArray (Shard []::new );
180195 }
181196
197+ Builder (Concurrency concurrency , long capacity ) {
198+ this .nodeCount = new AtomicLong ();
199+ int numberOfShards = numberOfShards (concurrency );
200+ this .shardShift = Long .SIZE - Integer .numberOfTrailingZeros (numberOfShards );
201+ this .shardMask = numberOfShards - 1 ;
202+ this .shards = IntStream .range (0 , numberOfShards )
203+ .mapToObj (__ -> new Shard (this .nodeCount , BitUtil .ceilDiv (capacity , numberOfShards )))
204+ .toArray (Shard []::new );
205+ }
206+
182207 /**
183208 * Add a node to the mapping.
184209 *
@@ -208,6 +233,11 @@ private Shard(AtomicLong nextId) {
208233 this .nextId = nextId ;
209234 }
210235
236+ private Shard (AtomicLong nextId , long capacity ) {
237+ super (capacity );
238+ this .nextId = nextId ;
239+ }
240+
211241 long addNode (byte [] nodeId ) {
212242 this .assertIsUnderLock ();
213243 long mappedId = mapping .getIfAbsent (nodeId , IdMap .NOT_FOUND );
0 commit comments