public ObjectIdentityOrdinalMap(int logOfSegmentNumber) { if (logOfSegmentNumber < 1 && logOfSegmentNumber > 32) { throw new RuntimeException("Invalid power level"); } segments = new Segment[2 << logOfSegmentNumber]; for(int i=0; i<segments.length; i++){ segments[i] = new Segment(); } this.mask = (2 << logOfSegmentNumber) - 1; this.logOfSegmentNumber = logOfSegmentNumber; }
public Entry getEntry(Object obj) { int hashCode = System.identityHashCode(obj); int segment = segment(hashCode); return segments[segment].get(obj, hashCode); }
/** * Associating the obj with an ordinal * * @param obj * @param ordinal */ public void put(Object obj, int ordinal) { int hashCode = System.identityHashCode(obj); int segment = segment(hashCode); segments[segment].put(obj, hashCode, ordinal); }
public synchronized void put(Object object, int hashCode, int ordinal) { int index = index(hashCode, entries.length); Entry current = entries[index]; Entry prev = null; while (current != null) { if (current.hash() == hashCode) { Object currentObject = current.getKey(); if( currentObject == null){ deleteEntry(index, current, prev); current = current.next; continue; } else if (currentObject == object) { return; } } prev = current; current = current.next; } count++; Entry first = entries[index]; Entry entry = new Entry(object, hashCode, ordinal, first); entries[index] = entry; entry.next = first; checkSize(); return; }
public synchronized Entry get(Object object, int hashCode) { int index = index(hashCode, entries.length); Entry current = entries[index]; Entry prev = null; while (current != null) { if (current.hash() == hashCode) { Object currentObject = current.getKey(); if( currentObject == null){ deleteEntry(index, current, prev); current = current.next; continue; } else if (currentObject == object) { return current; } } prev = current; current = current.next; } return null; }
private void resize(int newCapacity) { Entry[] newEntries = new Entry[newCapacity]; if( entries != null){ for(Entry entry : entries){ Entry current = entry; while(current != null){ Entry newEntry = current; current = current.next; int index = index(newEntry.hash(), newEntries.length); newEntry.next = newEntries[index]; newEntries[index] = newEntry; } } } minThreshold = (newEntries.length == MINIMUM_CAPACITY) ? 0 : (newEntries.length * LOAD_FACTOR_PERCENT / 200); maxThreshold = (newEntries.length == MAXIMUM_CAPACITY) ? Integer.MAX_VALUE : newEntries.length * LOAD_FACTOR_PERCENT / 100; entries = newEntries; }
private void checkSize() { if( count >= minThreshold && count <= maxThreshold ){ return; } int newCapacity; if( count < minThreshold ) { newCapacity = Math.max(MINIMUM_CAPACITY, entries.length >> 1); } else { newCapacity = Math.min(MAXIMUM_CAPACITY, entries.length << 1); } // nothing should be done, since capacity is not changed if (newCapacity == entries.length) { return; } resize(newCapacity); }
public Segment(){ resize(MINIMUM_CAPACITY); }
public int size() { int size = 0; for (Segment segment : segments) { size += segment.size(); } return size; } }
public void clear(){ for (Segment segment : segments) { segment.clear(); } }
public synchronized void clear() { Arrays.fill(entries, null); count = 0; resize(MINIMUM_CAPACITY); }