Mercurial > hg > truffle
diff truffle/com.oracle.truffle.object/src/com/oracle/truffle/object/PropertyMap.java @ 22153:b59d06483580
PropertyMap refactoring
author | Andreas Woess <andreas.woess@oracle.com> |
---|---|
date | Mon, 14 Sep 2015 18:32:54 +0200 |
parents | 9c8c0937da41 |
children | dc83cc1f94f2 |
line wrap: on
line diff
--- a/truffle/com.oracle.truffle.object/src/com/oracle/truffle/object/PropertyMap.java Mon Sep 14 18:07:17 2015 +0200 +++ b/truffle/com.oracle.truffle.object/src/com/oracle/truffle/object/PropertyMap.java Mon Sep 14 18:32:54 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,332 +26,54 @@ import com.oracle.truffle.api.object.*; -public final class PropertyMap implements Map<Object, Property> { - private final PropertyMap car; - private final Property cdr; - private final int size; - - private static final PropertyMap EMPTY = new PropertyMap(); - - private PropertyMap() { - this.car = null; - this.cdr = null; - this.size = 0; - } - - private PropertyMap(PropertyMap parent, Property added) { - this.car = Objects.requireNonNull(parent); - this.cdr = added; - this.size = parent.size + 1; - } +/** + * Immutable property map. + */ +public abstract class PropertyMap implements ImmutableMap<Object, Property> { public static PropertyMap empty() { - return EMPTY; - } - - public int size() { - return size; + return ConsListPropertyMap.empty(); } - public boolean isEmpty() { - return size() == 0; - } + public abstract Iterator<Object> orderedKeyIterator(); + + public abstract Iterator<Object> reverseOrderedKeyIterator(); - public boolean containsKey(Object key) { - for (Map.Entry<Object, Property> entry : reverseOrderEntrySet()) { - if (entry.getKey().equals(key)) { - return true; - } - } - return false; - } + public abstract Iterator<Property> orderedValueIterator(); + + public abstract Iterator<Property> reverseOrderedValueIterator(); + + public abstract Property getLastProperty(); - public boolean containsValue(Object value) { - for (Map.Entry<Object, Property> entry : reverseOrderEntrySet()) { - if (entry.getValue().equals(value)) { - return true; - } - } - return false; - } + public abstract PropertyMap putCopy(final Property element); + + public abstract PropertyMap replaceCopy(final Property oldValue, final Property newValue); - public Property get(Object key) { - for (Map.Entry<Object, Property> entry : reverseOrderEntrySet()) { - if (entry.getKey().equals(key)) { - return entry.getValue(); - } - } - return null; - } + public abstract PropertyMap removeCopy(final Property value); - public Property put(Object key, Property value) { + public abstract PropertyMap getParentMap(); + + @Override + public Property put(final Object key, final Property value) { throw unmodifiableException(); } - public Property remove(Object key) { + @Override + public void putAll(final Map<? extends Object, ? extends Property> m) { throw unmodifiableException(); } - public void putAll(Map<? extends Object, ? extends Property> m) { + @Override + public Property remove(final Object key) { throw unmodifiableException(); } + @Override public void clear() { throw unmodifiableException(); } - public Set<Object> keySet() { - return new AbstractSet<Object>() { - @Override - public Iterator<Object> iterator() { - Object[] keys = new Object[size()]; - Iterator<Map.Entry<Object, Property>> iterator = reverseOrderEntrySet().iterator(); - for (int pos = size() - 1; pos >= 0; pos--) { - keys[pos] = iterator.next().getKey(); - } - return Arrays.asList(keys).iterator(); - } - - @Override - public int size() { - return PropertyMap.this.size(); - } - }; - } - - public Collection<Property> values() { - return new AbstractSet<Property>() { - @Override - public Iterator<Property> iterator() { - Property[] values = new Property[size()]; - Iterator<Map.Entry<Object, Property>> iterator = reverseOrderEntrySet().iterator(); - for (int pos = size() - 1; pos >= 0; pos--) { - values[pos] = iterator.next().getValue(); - } - return Arrays.asList(values).iterator(); - } - - @Override - public int size() { - return PropertyMap.this.size(); - } - }; - } - - public Set<Map.Entry<Object, Property>> entrySet() { - return new AbstractSet<Map.Entry<Object, Property>>() { - @Override - public Iterator<Map.Entry<Object, Property>> iterator() { - @SuppressWarnings("unchecked") - Map.Entry<Object, Property>[] entries = (Map.Entry<Object, Property>[]) new Map.Entry<?, ?>[size()]; - Iterator<Map.Entry<Object, Property>> iterator = reverseOrderEntrySet().iterator(); - for (int pos = size() - 1; pos >= 0; pos--) { - entries[pos] = iterator.next(); - } - return Arrays.asList(entries).iterator(); - } - - @Override - public int size() { - return PropertyMap.this.size(); - } - }; - } - - public Set<Map.Entry<Object, Property>> reverseOrderEntrySet() { - return new AbstractSet<Map.Entry<Object, Property>>() { - @Override - public Iterator<Map.Entry<Object, Property>> iterator() { - return new Iterator<Map.Entry<Object, Property>>() { - PropertyMap current = PropertyMap.this; - - public Entry<Object, Property> next() { - if (hasNext()) { - try { - return new MapEntryImpl(current.cdr); - } finally { - current = current.car; - } - } else { - throw new NoSuchElementException(); - } - } - - public boolean hasNext() { - return current != empty(); - } - - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - - @Override - public int size() { - return PropertyMap.this.size(); - } - }; - } - - public Set<Object> reverseOrderKeys() { - return new AbstractSet<Object>() { - @Override - public Iterator<Object> iterator() { - return new Iterator<Object>() { - PropertyMap current = PropertyMap.this; - - public Object next() { - if (hasNext()) { - try { - return current.cdr.getKey(); - } finally { - current = current.car; - } - } else { - throw new NoSuchElementException(); - } - } - - public boolean hasNext() { - return current != empty(); - } - - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - - @Override - public int size() { - return PropertyMap.this.size(); - } - }; - } - - public Set<Property> reverseOrderValues() { - return new AbstractSet<Property>() { - @Override - public Iterator<Property> iterator() { - return new Iterator<Property>() { - PropertyMap current = PropertyMap.this; - - public Property next() { - if (hasNext()) { - try { - return current.cdr; - } finally { - current = current.car; - } - } else { - throw new NoSuchElementException(); - } - } - - public boolean hasNext() { - return current != empty(); - } - - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - - @Override - public int size() { - return PropertyMap.this.size(); - } - }; - } - - private static final class MapEntryImpl implements Map.Entry<Object, Property> { - private final Property backingProperty; - - public MapEntryImpl(Property backingProperty) { - this.backingProperty = backingProperty; - } - - public Object getKey() { - return backingProperty.getKey(); - } - - public Property getValue() { - return backingProperty; - } - - public Property setValue(Property value) { - throw unmodifiableException(); - } - } - - private static UnsupportedOperationException unmodifiableException() { - throw new UnsupportedOperationException("unmodifiable"); - } - - public PropertyMap putCopy(Property value) { - return new PropertyMap(this, value); - } - - public PropertyMap removeCopy(Property value) { - Deque<Property> shelve = new ArrayDeque<>(); - PropertyMap current = this; - while (!current.isEmpty()) { - if (current.getLastProperty().equals(value)) { - PropertyMap newMap = current.getParentMap(); - for (Property property : shelve) { - newMap = newMap.putCopy(property); - } - return newMap; - } else { - shelve.push(current.getLastProperty()); - current = current.getParentMap(); - } - } - return this; - } - - public PropertyMap replaceCopy(Property oldValue, Property newValue) { - Deque<Property> shelve = new ArrayDeque<>(); - PropertyMap current = this; - while (!current.isEmpty()) { - if (current.getLastProperty().equals(oldValue)) { - PropertyMap newMap = current.getParentMap(); - newMap = newMap.putCopy(newValue); - for (Property property : shelve) { - newMap = newMap.putCopy(property); - } - return newMap; - } else { - shelve.push(current.getLastProperty()); - current = current.getParentMap(); - } - } - return this; - } - - public PropertyMap getOwningMap(Property value) { - PropertyMap current = this; - while (!current.isEmpty()) { - if (current.getLastProperty().equals(value)) { - return current; - } - current = current.getParentMap(); - } - return null; - } - - PropertyMap getParentMap() { - return car; - } - - public Property getLastProperty() { - return cdr; - } - - @Override - public String toString() { - return values().toString(); + protected static RuntimeException unmodifiableException() { + throw new UnsupportedOperationException(); } }