@Override public TriePropertyMap putCopy(Property value) { Object key = key(value); return copyAndPutImpl(key, value); }
@Override public TriePropertyMap removeCopy(Property value) { Object key = key(value); return copyAndRemove(key); }
@Override public boolean containsKey(Object key) { return getEntry(key) != null; }
@Override public TriePropertyMap copyAndRemove(Object key) { int hash = hash(key); LinkedPropertyEntry existing = root.find(key, hash); if (existing == null) { return this; } else if (size == 1) { return empty(); if (existing.getPrevKey() != null) { Object prevKey = existing.getPrevKey(); LinkedPropertyEntry existingPrev = getEntry(prevKey); LinkedPropertyEntry newPrev = existingPrev.withNextKey(existing.getNextKey()); newRoot = newRoot.put(prevKey, hash(prevKey), newPrev); if (existing == tail) { newTail = newPrev; LinkedPropertyEntry existingNext = getEntry(nextKey); LinkedPropertyEntry newNext = existingNext.withPrevKey(existing.getPrevKey()); newRoot = newRoot.put(nextKey, hash(nextKey), newNext); if (existing == head) { newHead = newNext; return new TriePropertyMap(size - 1, newRoot, newHead, newTail);
private TriePropertyMap copyAndPutImpl(Object key, Property value) { int hash = hash(key); LinkedPropertyEntry existing = root.find(key, hash); TrieNode<Object, Property, LinkedPropertyEntry> newRoot = root; newRoot = newRoot.put(tailKey, hash(tailKey), tailWithNext); if (head == tail) { newHead = tailWithNext; assert !newEntry.equals(existing); if (existing.getPrevKey() != null) { assert getEntry(existing.getPrevKey()).getNextKey().equals(key); } else { assert existing == head; assert getEntry(existing.getNextKey()).getPrevKey().equals(key); } else { assert existing == tail; return new TriePropertyMap(newSize, newRoot, newHead, newTail);
@Override public int size() { return TriePropertyMap.this.size(); } };
private boolean verify() { assert (size == 0 && head == null && tail == null) || (size != 0 && head != null && tail != null) : "size=" + size + ", head=" + head + ", tail=" + tail; assert head == null || head == getEntry(head.getKey()); assert tail == null || tail == getEntry(tail.getKey()); if (VERIFY) { assert root.count() == size : root.count() + " != " + size; assert root.verify(0); int count = 0; for (Iterator<Map.Entry<Object, Property>> iterator = orderedEntryIterator(); iterator.hasNext();) { Map.Entry<Object, Property> e = iterator.next(); assert e == getEntry(e.getKey()); count++; } assert count == size : count + " != " + size; } return true; }
@Override public LinkedPropertyEntry getEntry(Object key) { LinkedPropertyEntry entry = root.find(key, hash(key)); assert entry == null || entry.getKey().equals(key); return entry; }
/** @since 0.17 or earlier */ public static PropertyMap empty() { if (ObjectStorageOptions.TriePropertyMap) { return TriePropertyMap.empty(); } else { return ConsListPropertyMap.empty(); } }
@Override public TriePropertyMap replaceCopy(Property oldValue, Property newValue) { return putCopy(newValue); }
@Override public boolean containsValue(Object value) { for (Map.Entry<Object, Property> entry : reverseOrderEntrySet()) { if (Objects.equals(value, entry.getValue())) { return true; } } return false; }
@Override public TriePropertyMap copyAndPut(Object key, Property value) { if (!value.getKey().equals(key)) { throw new IllegalArgumentException("Key must equal extracted key of property."); } return copyAndPutImpl(key, value); }
@Override public TriePropertyMap copyAndRemove(Object key) { int hash = hash(key); LinkedPropertyEntry existing = root.find(key, hash); if (existing == null) { return this; } else if (size == 1) { return empty(); if (existing.getPrevKey() != null) { Object prevKey = existing.getPrevKey(); LinkedPropertyEntry existingPrev = getEntry(prevKey); LinkedPropertyEntry newPrev = existingPrev.withNextKey(existing.getNextKey()); newRoot = newRoot.put(prevKey, hash(prevKey), newPrev); if (existing == tail) { newTail = newPrev; LinkedPropertyEntry existingNext = getEntry(nextKey); LinkedPropertyEntry newNext = existingNext.withPrevKey(existing.getPrevKey()); newRoot = newRoot.put(nextKey, hash(nextKey), newNext); if (existing == head) { newHead = newNext; return new TriePropertyMap(size - 1, newRoot, newHead, newTail);
private TriePropertyMap copyAndPutImpl(Object key, Property value) { int hash = hash(key); LinkedPropertyEntry existing = root.find(key, hash); TrieNode<Object, Property, LinkedPropertyEntry> newRoot = root; newRoot = newRoot.put(tailKey, hash(tailKey), tailWithNext); if (head == tail) { newHead = tailWithNext; assert !newEntry.equals(existing); if (existing.getPrevKey() != null) { assert getEntry(existing.getPrevKey()).getNextKey().equals(key); } else { assert existing == head; assert getEntry(existing.getNextKey()).getPrevKey().equals(key); } else { assert existing == tail; return new TriePropertyMap(newSize, newRoot, newHead, newTail);
@Override public int size() { return TriePropertyMap.this.size(); } };
private boolean verify() { assert (size == 0 && head == null && tail == null) || (size != 0 && head != null && tail != null) : "size=" + size + ", head=" + head + ", tail=" + tail; assert head == null || head == getEntry(head.getKey()); assert tail == null || tail == getEntry(tail.getKey()); if (VERIFY) { assert root.count() == size : root.count() + " != " + size; assert root.verify(0); int count = 0; for (Iterator<Map.Entry<Object, Property>> iterator = orderedEntryIterator(); iterator.hasNext();) { Map.Entry<Object, Property> e = iterator.next(); assert e == getEntry(e.getKey()); count++; } assert count == size : count + " != " + size; } return true; }
@Override public LinkedPropertyEntry getEntry(Object key) { LinkedPropertyEntry entry = root.find(key, hash(key)); assert entry == null || entry.getKey().equals(key); return entry; }
/** @since 0.17 or earlier */ public static PropertyMap empty() { if (ObjectStorageOptions.TriePropertyMap) { return TriePropertyMap.empty(); } else { return ConsListPropertyMap.empty(); } }
@Override public TriePropertyMap replaceCopy(Property oldValue, Property newValue) { return putCopy(newValue); }
@Override public boolean containsValue(Object value) { for (Map.Entry<Object, Property> entry : reverseOrderEntrySet()) { if (Objects.equals(value, entry.getValue())) { return true; } } return false; }