public void testNewEntry() { for (MapMaker maker : allWeakValueStrengthMakers()) { MapMakerInternalMap<Object, Object, ?, ?> map = makeMap(maker); Segment<Object, Object, ?, ?> segment = map.segments[0]; Object keyOne = new Object(); Object valueOne = new Object(); int hashOne = map.hash(keyOne); InternalEntry<Object, Object, ?> entryOne = segment.newEntryForTesting(keyOne, hashOne, null); WeakValueReference<Object, Object, ?> valueRefOne = segment.newWeakValueReferenceForTesting(entryOne, valueOne); assertSame(valueOne, valueRefOne.get()); segment.setWeakValueReferenceForTesting(entryOne, valueRefOne); assertSame(keyOne, entryOne.getKey()); assertEquals(hashOne, entryOne.getHash()); assertNull(entryOne.getNext()); assertSame(valueRefOne, segment.getWeakValueReferenceForTesting(entryOne)); Object keyTwo = new Object(); Object valueTwo = new Object(); int hashTwo = map.hash(keyTwo); InternalEntry<Object, Object, ?> entryTwo = segment.newEntryForTesting(keyTwo, hashTwo, entryOne); WeakValueReference<Object, Object, ?> valueRefTwo = segment.newWeakValueReferenceForTesting(entryTwo, valueTwo); assertSame(valueTwo, valueRefTwo.get()); segment.setWeakValueReferenceForTesting(entryTwo, valueRefTwo); assertSame(keyTwo, entryTwo.getKey()); assertEquals(hashTwo, entryTwo.getHash()); assertSame(entryOne, entryTwo.getNext()); assertSame(valueRefTwo, segment.getWeakValueReferenceForTesting(entryTwo)); } }
public void testSegmentReplace() { MapMakerInternalMap<Object, Object, ?, ?> map = makeMap(createMapMaker().concurrencyLevel(1).weakValues()); Segment<Object, Object, ?, ?> segment = map.segments[0]; // TODO(fry): check recency ordering Object key = new Object(); int hash = map.hash(key); Object oldValue = new Object(); Object newValue = new Object(); AtomicReferenceArray<? extends InternalEntry<Object, Object, ?>> table = segment.table; int index = hash & (table.length() - 1); InternalEntry<Object, Object, ?> entry = segment.newEntryForTesting(key, hash, null); WeakValueReference<Object, Object, ?> oldValueRef = segment.newWeakValueReferenceForTesting(entry, oldValue); segment.setWeakValueReferenceForTesting(entry, oldValueRef); // no entry assertNull(segment.replace(key, hash, newValue)); assertEquals(0, segment.count); // same key segment.setTableEntryForTesting(index, entry); segment.count++; assertEquals(1, segment.count); assertSame(oldValue, segment.get(key, hash)); assertSame(oldValue, segment.replace(key, hash, newValue)); assertEquals(1, segment.count); assertSame(newValue, segment.get(key, hash)); // cleared segment.setWeakValueReferenceForTesting(entry, oldValueRef); oldValueRef.clear(); assertNull(segment.replace(key, hash, newValue)); assertEquals(0, segment.count); assertNull(segment.get(key, hash)); }
public void testSegmentPut() { MapMakerInternalMap<Object, Object, ?, ?> map = makeMap(createMapMaker().concurrencyLevel(1).weakValues()); Segment<Object, Object, ?, ?> segment = map.segments[0]; // TODO(fry): check recency ordering Object key = new Object(); int hash = map.hash(key); Object oldValue = new Object(); Object newValue = new Object(); // no entry assertEquals(0, segment.count); assertNull(segment.put(key, hash, oldValue, false)); assertEquals(1, segment.count); // same key assertSame(oldValue, segment.put(key, hash, newValue, false)); assertEquals(1, segment.count); assertSame(newValue, segment.get(key, hash)); // cleared InternalEntry<Object, Object, ?> entry = segment.getEntry(key, hash); WeakValueReference<Object, Object, ?> oldValueRef = segment.newWeakValueReferenceForTesting(entry, oldValue); segment.setWeakValueReferenceForTesting(entry, oldValueRef); assertSame(oldValue, segment.get(key, hash)); oldValueRef.clear(); assertNull(segment.put(key, hash, newValue, false)); assertEquals(1, segment.count); assertSame(newValue, segment.get(key, hash)); }
public void testSegmentPutIfAbsent() { MapMakerInternalMap<Object, Object, ?, ?> map = makeMap(createMapMaker().concurrencyLevel(1).weakValues()); Segment<Object, Object, ?, ?> segment = map.segments[0]; // TODO(fry): check recency ordering Object key = new Object(); int hash = map.hash(key); Object oldValue = new Object(); Object newValue = new Object(); // no entry assertEquals(0, segment.count); assertNull(segment.put(key, hash, oldValue, true)); assertEquals(1, segment.count); // same key assertSame(oldValue, segment.put(key, hash, newValue, true)); assertEquals(1, segment.count); assertSame(oldValue, segment.get(key, hash)); // cleared InternalEntry<Object, Object, ?> entry = segment.getEntry(key, hash); WeakValueReference<Object, Object, ?> oldValueRef = segment.newWeakValueReferenceForTesting(entry, oldValue); segment.setWeakValueReferenceForTesting(entry, oldValueRef); assertSame(oldValue, segment.get(key, hash)); oldValueRef.clear(); assertNull(segment.put(key, hash, newValue, true)); assertEquals(1, segment.count); assertSame(newValue, segment.get(key, hash)); }
public void testSegmentRemove() { MapMakerInternalMap<Object, Object, ?, ?> map = makeMap(createMapMaker().concurrencyLevel(1).weakValues()); Segment<Object, Object, ?, ?> segment = map.segments[0]; Object key = new Object(); int hash = map.hash(key); Object oldValue = new Object(); AtomicReferenceArray<? extends InternalEntry<Object, Object, ?>> table = segment.table; int index = hash & (table.length() - 1); InternalEntry<Object, Object, ?> entry = segment.newEntryForTesting(key, hash, null); WeakValueReference<Object, Object, ?> oldValueRef = segment.newWeakValueReferenceForTesting(entry, oldValue); segment.setWeakValueReferenceForTesting(entry, oldValueRef); // no entry assertEquals(0, segment.count); assertNull(segment.remove(key, hash)); assertEquals(0, segment.count); // same key segment.setTableEntryForTesting(index, entry); segment.count++; assertEquals(1, segment.count); assertSame(oldValue, segment.get(key, hash)); assertSame(oldValue, segment.remove(key, hash)); assertEquals(0, segment.count); assertNull(segment.get(key, hash)); // cleared segment.setTableEntryForTesting(index, entry); segment.count++; assertEquals(1, segment.count); assertSame(oldValue, segment.get(key, hash)); oldValueRef.clear(); assertNull(segment.remove(key, hash)); assertEquals(0, segment.count); assertNull(segment.get(key, hash)); }
public void testClearValue() { MapMakerInternalMap<Object, Object, ?, ?> map = makeMap(createMapMaker().concurrencyLevel(1).initialCapacity(1).weakValues()); Segment<Object, Object, ?, ?> segment = map.segments[0]; AtomicReferenceArray<? extends InternalEntry<Object, Object, ?>> table = segment.table; assertEquals(1, table.length()); Object key = new Object(); Object value = new Object(); int hash = map.hash(key); InternalEntry<Object, Object, ?> entry = segment.newEntryForTesting(key, hash, null); segment.setValueForTesting(entry, value); WeakValueReference<Object, Object, ?> valueRef = segment.getWeakValueReferenceForTesting(entry); // clear absent assertFalse(segment.clearValueForTesting(key, hash, valueRef)); segment.setTableEntryForTesting(0, entry); // don't increment count; this is used during computation assertTrue(segment.clearValueForTesting(key, hash, valueRef)); // no notification sent with clearValue assertEquals(0, segment.count); assertNull(table.get(0)); // clear wrong value reference segment.setTableEntryForTesting(0, entry); WeakValueReference<Object, Object, ?> otherValueRef = segment.newWeakValueReferenceForTesting(entry, value); segment.setWeakValueReferenceForTesting(entry, otherValueRef); assertFalse(segment.clearValueForTesting(key, hash, valueRef)); segment.setWeakValueReferenceForTesting(entry, valueRef); assertTrue(segment.clearValueForTesting(key, hash, valueRef)); }
public void testDrainValueReferenceQueueOnWrite() { for (MapMaker maker : allWeakValueStrengthMakers()) { MapMakerInternalMap<Object, Object, ?, ?> map = makeMap(maker.concurrencyLevel(1)); if (maker.getValueStrength() == Strength.WEAK) { Segment<Object, Object, ?, ?> segment = map.segments[0]; Object keyOne = new Object(); int hashOne = map.hash(keyOne); Object valueOne = new Object(); Object keyTwo = new Object(); Object valueTwo = new Object(); map.put(keyOne, valueOne); @SuppressWarnings("unchecked") WeakValueEntry<Object, Object, ?> entry = (WeakValueEntry<Object, Object, ?>) segment.getEntry(keyOne, hashOne); WeakValueReference<Object, Object, ?> valueReference = entry.getValueReference(); @SuppressWarnings("unchecked") Reference<Object> reference = (Reference) valueReference; reference.enqueue(); map.put(keyTwo, valueTwo); assertFalse(map.containsKey(keyOne)); assertFalse(map.containsValue(valueOne)); assertNull(map.get(keyOne)); assertEquals(1, map.size()); assertNull(segment.getValueReferenceQueueForTesting().poll()); } } }
public void testDrainValueReferenceQueueOnRead() { for (MapMaker maker : allWeakValueStrengthMakers()) { MapMakerInternalMap<Object, Object, ?, ?> map = makeMap(maker.concurrencyLevel(1)); if (maker.getValueStrength() == Strength.WEAK) { Segment<Object, Object, ?, ?> segment = map.segments[0]; Object keyOne = new Object(); int hashOne = map.hash(keyOne); Object valueOne = new Object(); Object keyTwo = new Object(); map.put(keyOne, valueOne); @SuppressWarnings("unchecked") WeakValueEntry<Object, Object, ?> entry = (WeakValueEntry<Object, Object, ?>) segment.getEntry(keyOne, hashOne); WeakValueReference<Object, Object, ?> valueReference = entry.getValueReference(); @SuppressWarnings("unchecked") Reference<Object> reference = (Reference) valueReference; reference.enqueue(); for (int i = 0; i < SMALL_MAX_SIZE; i++) { Object unused = map.get(keyTwo); } assertFalse(map.containsKey(keyOne)); assertFalse(map.containsValue(valueOne)); assertNull(map.get(keyOne)); assertEquals(0, map.size()); assertNull(segment.getValueReferenceQueueForTesting().poll()); } } }
public void testSegmentGetAndContains() { MapMakerInternalMap<Object, Object, ?, ?> map = makeMap(createMapMaker().concurrencyLevel(1).weakValues()); Segment<Object, Object, ?, ?> segment = map.segments[0]; // TODO(fry): check recency ordering Object key = new Object(); int hash = map.hash(key); Object value = new Object(); AtomicReferenceArray<? extends InternalEntry<Object, Object, ?>> table = segment.table; int index = hash & (table.length() - 1); InternalEntry<Object, Object, ?> entry = segment.newEntryForTesting(key, hash, null); segment.setValueForTesting(entry, value); assertNull(segment.get(key, hash)); // count == 0 segment.setTableEntryForTesting(index, entry); assertNull(segment.get(key, hash)); assertFalse(segment.containsKey(key, hash)); assertFalse(segment.containsValue(value)); // count == 1 segment.count++; assertSame(value, segment.get(key, hash)); assertTrue(segment.containsKey(key, hash)); assertTrue(segment.containsValue(value)); // don't see absent values now that count > 0 assertNull(segment.get(new Object(), hash)); // null key InternalEntry<Object, Object, ?> nullEntry = segment.newEntryForTesting(null, hash, entry); Object nullValue = new Object(); WeakValueReference<Object, Object, ?> nullValueRef = segment.newWeakValueReferenceForTesting(nullEntry, nullValue); segment.setWeakValueReferenceForTesting(nullEntry, nullValueRef); segment.setTableEntryForTesting(index, nullEntry); // skip the null key assertSame(value, segment.get(key, hash)); assertTrue(segment.containsKey(key, hash)); assertTrue(segment.containsValue(value)); assertFalse(segment.containsValue(nullValue)); // hash collision InternalEntry<Object, Object, ?> dummyEntry = segment.newEntryForTesting(new Object(), hash, entry); Object dummyValue = new Object(); WeakValueReference<Object, Object, ?> dummyValueRef = segment.newWeakValueReferenceForTesting(dummyEntry, dummyValue); segment.setWeakValueReferenceForTesting(dummyEntry, dummyValueRef); segment.setTableEntryForTesting(index, dummyEntry); assertSame(value, segment.get(key, hash)); assertTrue(segment.containsKey(key, hash)); assertTrue(segment.containsValue(value)); assertTrue(segment.containsValue(dummyValue)); // key collision dummyEntry = segment.newEntryForTesting(key, hash, entry); dummyValue = new Object(); dummyValueRef = segment.newWeakValueReferenceForTesting(dummyEntry, dummyValue); segment.setWeakValueReferenceForTesting(dummyEntry, dummyValueRef); segment.setTableEntryForTesting(index, dummyEntry); // returns the most recent entry assertSame(dummyValue, segment.get(key, hash)); assertTrue(segment.containsKey(key, hash)); assertTrue(segment.containsValue(value)); assertTrue(segment.containsValue(dummyValue)); }
public void testSegmentReplaceValue() { MapMakerInternalMap<Object, Object, ?, ?> map = makeMap(createMapMaker().concurrencyLevel(1).weakValues()); Segment<Object, Object, ?, ?> segment = map.segments[0]; // TODO(fry): check recency ordering Object key = new Object(); int hash = map.hash(key); Object oldValue = new Object(); Object newValue = new Object(); AtomicReferenceArray<? extends InternalEntry<Object, Object, ?>> table = segment.table; int index = hash & (table.length() - 1); InternalEntry<Object, Object, ?> entry = segment.newEntryForTesting(key, hash, null); WeakValueReference<Object, Object, ?> oldValueRef = segment.newWeakValueReferenceForTesting(entry, oldValue); segment.setWeakValueReferenceForTesting(entry, oldValueRef); // no entry assertFalse(segment.replace(key, hash, oldValue, newValue)); assertEquals(0, segment.count); // same value segment.setTableEntryForTesting(index, entry); segment.count++; assertEquals(1, segment.count); assertSame(oldValue, segment.get(key, hash)); assertTrue(segment.replace(key, hash, oldValue, newValue)); assertEquals(1, segment.count); assertSame(newValue, segment.get(key, hash)); // different value assertFalse(segment.replace(key, hash, oldValue, newValue)); assertEquals(1, segment.count); assertSame(newValue, segment.get(key, hash)); // cleared segment.setWeakValueReferenceForTesting(entry, oldValueRef); oldValueRef.clear(); assertFalse(segment.replace(key, hash, oldValue, newValue)); assertEquals(0, segment.count); assertNull(segment.get(key, hash)); }
public void testSegmentRemoveValue() { MapMakerInternalMap<Object, Object, ?, ?> map = makeMap(createMapMaker().concurrencyLevel(1).weakValues()); Segment<Object, Object, ?, ?> segment = map.segments[0]; Object key = new Object(); int hash = map.hash(key); Object oldValue = new Object(); Object newValue = new Object(); AtomicReferenceArray<? extends InternalEntry<Object, Object, ?>> table = segment.table; int index = hash & (table.length() - 1); InternalEntry<Object, Object, ?> entry = segment.newEntryForTesting(key, hash, null); WeakValueReference<Object, Object, ?> oldValueRef = segment.newWeakValueReferenceForTesting(entry, oldValue); segment.setWeakValueReferenceForTesting(entry, oldValueRef); // no entry assertEquals(0, segment.count); assertNull(segment.remove(key, hash)); assertEquals(0, segment.count); // same value segment.setTableEntryForTesting(index, entry); segment.count++; assertEquals(1, segment.count); assertSame(oldValue, segment.get(key, hash)); assertTrue(segment.remove(key, hash, oldValue)); assertEquals(0, segment.count); assertNull(segment.get(key, hash)); // different value segment.setTableEntryForTesting(index, entry); segment.count++; assertEquals(1, segment.count); assertSame(oldValue, segment.get(key, hash)); assertFalse(segment.remove(key, hash, newValue)); assertEquals(1, segment.count); assertSame(oldValue, segment.get(key, hash)); // cleared assertSame(oldValue, segment.get(key, hash)); oldValueRef.clear(); assertFalse(segment.remove(key, hash, oldValue)); assertEquals(0, segment.count); assertNull(segment.get(key, hash)); }