/** * Creates a new, empty map with the specified strategy, initial capacity and concurrency level. */ MapMakerInternalMap(MapMaker builder) { concurrencyLevel = Math.min(builder.getConcurrencyLevel(), MAX_SEGMENTS); keyStrength = builder.getKeyStrength(); valueStrength = builder.getValueStrength(); keyEquivalence = builder.getKeyEquivalence(); valueEquivalence = valueStrength.defaultEquivalence(); maximumSize = builder.maximumSize; expireAfterAccessNanos = builder.getExpireAfterAccessNanos(); expireAfterWriteNanos = builder.getExpireAfterWriteNanos(); entryFactory = EntryFactory.getFactory(keyStrength, expires(), evictsBySize()); ticker = builder.getTicker(); removalListener = builder.getRemovalListener(); removalNotificationQueue = (removalListener == NullListener.INSTANCE) ? MapMakerInternalMap.<RemovalNotification<K, V>>discardingQueue() : new ConcurrentLinkedQueue<RemovalNotification<K, V>>(); int initialCapacity = Math.min(builder.getInitialCapacity(), MAXIMUM_CAPACITY); if (evictsBySize()) { initialCapacity = Math.min(initialCapacity, maximumSize); } // Find power-of-two sizes best matching arguments. Constraints: // (segmentCount <= maximumSize) // && (concurrencyLevel > maximumSize || segmentCount > concurrencyLevel) int segmentShift = 0; int segmentCount = 1; while (segmentCount < concurrencyLevel && (!evictsBySize() || segmentCount * 2 <= maximumSize)) { ++segmentShift; segmentCount <<= 1; } this.segmentShift = 32 - segmentShift; segmentMask = segmentCount - 1; this.segments = newSegmentArray(segmentCount); int segmentCapacity = initialCapacity / segmentCount; if (segmentCapacity * segmentCount < initialCapacity) { ++segmentCapacity; } int segmentSize = 1; while (segmentSize < segmentCapacity) { segmentSize <<= 1; } if (evictsBySize()) { // Ensure sum of segment max sizes = overall max size int maximumSegmentSize = maximumSize / segmentCount + 1; int remainder = maximumSize % segmentCount; for (int i = 0; i < this.segments.length; ++i) { if (i == remainder) { maximumSegmentSize--; } this.segments[i] = createSegment(segmentSize, maximumSegmentSize); } } else { for (int i = 0; i < this.segments.length; ++i) { this.segments[i] = createSegment(segmentSize, MapMaker.UNSET_INT); } } }