org.erights.e.elib.tables
Class EMap

java.lang.Object
  |
  +--org.erights.e.elib.tables.EMap
All Implemented Interfaces:
EPrintable, Iteratable, Marker, Persistent, Serializable
Direct Known Subclasses:
ConstMap, FlexMap, ROMap

public abstract class EMap
extends Object
implements EPrintable, Persistent, Iteratable

Safe: A EMap is a finite single-valued map from keys to values. Equivalently, it can be considered a finite set of pairs, where each is a pair of a key and a value, and no two pairs have the same key. 'EMap' is a query-only interface that's agnostic about whether the data can change and whether a EMap can be cast to an object by which to change it. 'EMap' is also agnostic about the basis for equality between tables. Subtypes do pin these issues down:

ConstMap guarantees immutability, uses value-based equality, and can be transparently passed-by-copy over the network.

FlexMap extends EMap with mutation operations.

Based on java.util.Dictionary, but not polymorphic with it since EMaps don't satisfy Dictionary's contract. In particular, Dictionaries explicitly disallow nulls as keys or values, whereas EMaps explicitly allow them.

Actually, for the sake of determinism, an EMap is a sequence of key-value pairs, where this sequence is the enumeration order, and is derived deterministically from the operations that resulted in this map. Putting in a new key adds it to the end of the sequence. Removing a key causes the last key to take the place of the removed key in the sequence. Other operations, like or(), specify how they determine the resulting sequence.

It is normally considered bad style to attach meaning to the sequence, but is in the contract, so you may if you wish. If you do, document that, since your readers should usually be able to make the no-meaning assumption.

Author:
Mark S. Miller
See Also:
Serialized Form

Field Summary
private static long serialVersionUID
           
private static Object ThePumpkin
          This object must never be stored as a value in a map.
 
Fields inherited from interface org.erights.e.elib.serial.Persistent
HONORARY, HONORED_NAMES
 
Constructor Summary
(package private) EMap()
          Only subclasses within the package
 
Method Summary
 ConstMap and(EMap mask)
          Enabled: The subset of this map whose keys are keys of 'mask'.
 ConstMap butNot(EMap mask)
          Enabled: The subset of this map whose keys are not keys of 'mask'.
 boolean contains(Object candidate)
          Enabled: Is the candidate the same as any of this table's values?
 FlexMap diverge()
          Enabled: 'keyType' and 'valueType' default to Object.class
 FlexMap diverge(Class keyType, Class valueType)
          Enabled: Returns a FlexMap whose initial state is a snapshot of the state of this map at the time of the diverge() request.
abstract  ESet domain()
          Enabled: Returns a set providing a read-only view of the domain of this map.
 Object[] extract(Object key, Object defaultValue)
          Enabled: Like optExtract/1, but allows one to provide a defaultValue for missing keys.
 Object get(Object key)
          Enabled: What value does 'key' map to?
abstract  Object get(Object key, Object instead)
          Enabled: What value does 'key' map to? Returns 'instead' if key doesn't map to anything.
 Object getKeys()
          Enabled: Defaults to an array of keyType()
abstract  Object getKeys(Class type)
          Enabled: Returns a divergent array-of-type of all the keys in order.
 Object[] getPair()
          Enabled: Returns a pair (a two element list) of the results of getKeys() and getValues().
 Object[] getPair(Class keyType, Class valueType)
          Enabled: Returns a pair (a two element list) of the results of getKeys(keyType) and getValues(valueType).
 Object getValues()
          Enabled: Defaults to an array of valueType()
abstract  Object getValues(Class type)
          Enabled: Returns a divergent array-of-type of all the values in order.
 boolean intersects(EMap other)
          Enabled: Do these tables have any keys in common?
 void iterate(AssocFunc func)
          Enabled: Call 'func' with each key-value pair in the table, in order.
abstract  Class keyType()
          Enabled: All keys in this map must be of this type.
 boolean maps(Object key)
          Enabled: Is there a mapping for 'key'?
 Object[] optExtract(Object key)
          Enabled: Used by the expansion of map-patterns.
 ConstMap or(EMap behind)
          Enabled: Defaults to not strict.
 ConstMap or(EMap behind, boolean strict)
          Enabled: Returns a map that has the union of the domains of this map.
private  ConstMap permute(Number[] permutation, Object oldKeys, Object oldVals)
           
 void printOn(String left, String map, String sep, String right, TextWriter out)
          Enabled: Onto out, print 'left' key0 'map' value0 'sep' ...
abstract  EMap readOnly()
          Enabled: Returns a read-only facet on this map.
abstract  int size()
          Enabled: How many entries are in the table?
abstract  ConstMap snapshot()
          Enabled: Returns a ConstMap whose state is a snapshot of the state of this map at the time of the snapshot() request.
 ConstMap sortKeys()
          Enabled: Returns a snapshot of this mapping, but reordered so the keys are in ascending order.
 ConstMap sortKeys(CompFunc func)
          Enabled: Returns a snapshot of this mapping, but reordered so the keys are in ascending order according to func.
 ConstMap sortValues()
          Enabled: Returns a snapshot of this mapping, but reordered so the values are in ascending order.
 ConstMap sortValues(CompFunc func)
          Enabled: Returns a snapshot of this mapping, but reordered so the values are in ascending order according to func.
 String toString()
          Suppressed:
abstract  Class valueType()
          Enabled: All values in this map must be of this type
 ConstMap with(Object key, Object newValue)
          Enabled: Returns a ConstMap just like this one, except that 'key' maps to 'newValue'.
 ConstMap without(Object key)
          Enabled: Returns a ConstMap just like this one, except that there is no ConstMap for 'key'.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface org.erights.e.elib.oldeio.EPrintable
__printOn
 

Field Detail

serialVersionUID

private static final long serialVersionUID

ThePumpkin

private static final Object ThePumpkin
This object must never be stored as a value in a map. It's used as an 'instead' to get/2 to simultaneously do a maps() test.

Constructor Detail

EMap

EMap()
Only subclasses within the package

Method Detail

snapshot

public abstract ConstMap snapshot()
Enabled: Returns a ConstMap whose state is a snapshot of the state of this map at the time of the snapshot() request. A ConstMap returns itself.


readOnly

public abstract EMap readOnly()
Enabled: Returns a read-only facet on this map. Someone holding this facet may see changes, but they cannot cause them.


diverge

public FlexMap diverge(Class keyType,
                       Class valueType)
Enabled: Returns a FlexMap whose initial state is a snapshot of the state of this map at the time of the diverge() request.

Further changes to the original and/or the new map are independent -- they diverge.

The new map is constrained to only hold associations from 'keyType' to 'valueType'. XXX keyType and valueType should be declared as ValueGuards rather than Classes.


diverge

public FlexMap diverge()
Enabled: 'keyType' and 'valueType' default to Object.class


get

public Object get(Object key)
           throws IndexOutOfBoundsException
Enabled: What value does 'key' map to?

Parameters:
key - nullOk;
Returns:
nullOk;
Throws:
IndexOutOfBoundsException - if key doesn't map to anything.
See Also:
org.erights.e.elib.ref.Ref#isSettled

optExtract

public Object[] optExtract(Object key)
Enabled: Used by the expansion of map-patterns.

Parameters:
key - nullOk;
Returns:
nullOk; If the key is found, returns a pair of the corresponding value and a ConstMap that's a snapshot of this one, but without(java.lang.Object) that key-value association. If the key is not found, optExtract/1 returns null.

extract

public Object[] extract(Object key,
                        Object defaultValue)
Enabled: Like optExtract/1, but allows one to provide a defaultValue for missing keys.

Parameters:
key - nullOk;
Returns:
If the key is found, returns a pair of the corresponding value and a ConstMap that's a snapshot of this one, but without(java.lang.Object) that key-value association. If the key is not found, extract/2 returns a pair of defaultValue and this map.

contains

public boolean contains(Object candidate)
Enabled: Is the candidate the same as any of this table's values?


intersects

public boolean intersects(EMap other)
Enabled: Do these tables have any keys in common?


size

public abstract int size()
Enabled: How many entries are in the table?


iterate

public void iterate(AssocFunc func)
Enabled: Call 'func' with each key-value pair in the table, in order.

Specified by:
iterate in interface Iteratable

or

public ConstMap or(EMap behind,
                   boolean strict)
Enabled: Returns a map that has the union of the domains of this map.

If both maps have keys in common, then if strict, throw an exception. Otherwise, take the value from the receiver (the left-hand operand). We can think of the receiver as being in front of and occluding 'behind'.

In the order, the 'behind' keys come first in their original order, then the receiver's remaining keys in their original order.


or

public ConstMap or(EMap behind)
Enabled: Defaults to not strict.


and

public ConstMap and(EMap mask)
Enabled: The subset of this map whose keys are keys of 'mask'.

The order of keys in the intersection is taken from the smaller of the original two. If they're the same size, then the receiver's order is used.


butNot

public ConstMap butNot(EMap mask)
Enabled: The subset of this map whose keys are not keys of 'mask'.

The order is the order of the receiver, as modified by removal of the keys in mask in mask's order.


maps

public boolean maps(Object key)
Enabled: Is there a mapping for 'key'?

Parameters:
key - nullOk;

get

public abstract Object get(Object key,
                           Object instead)
Enabled: What value does 'key' map to? Returns 'instead' if key doesn't map to anything.

Parameters:
key - nullOk;
instead - nullOk;
Returns:
nullOk;
See Also:
org.erights.e.elib.ref.Ref#isSettled

getKeys

public Object getKeys()
Enabled: Defaults to an array of keyType()


getKeys

public abstract Object getKeys(Class type)
Enabled: Returns a divergent array-of-type of all the keys in order.

XXX Should 'type' be a ValueGuard rather than a Class?


domain

public abstract ESet domain()
Enabled: Returns a set providing a read-only view of the domain of this map.


getValues

public Object getValues()
Enabled: Defaults to an array of valueType()


getValues

public abstract Object getValues(Class type)
Enabled: Returns a divergent array-of-type of all the values in order.

XXX Should 'type' be a ValueGuard rather than a Class?


getPair

public Object[] getPair()
Enabled: Returns a pair (a two element list) of the results of getKeys() and getValues().

Unlike calling them individually, by getting them both together, they are guaranteed to correspond.


getPair

public Object[] getPair(Class keyType,
                        Class valueType)
Enabled: Returns a pair (a two element list) of the results of getKeys(keyType) and getValues(valueType).

Unlike calling them individually, by getting them both together, they are guaranteed to correspond. The default implementation here does just call getKeys(keyType), and then calls getValues(valueType), as that is fine for everything but the WeakValuesMap.

XXX Should keyType and valueType be ValueGuards rather than Classes?


with

public ConstMap with(Object key,
                     Object newValue)
Enabled: Returns a ConstMap just like this one, except that 'key' maps to 'newValue'. The order is the same as the original; if 'key' is new, it is added to the end of the order.

This is currently horribly inefficient. Can be made efficient by using backward deltas.

Parameters:
key - nullOk;
newValue - nullOk;

without

public ConstMap without(Object key)
Enabled: Returns a ConstMap just like this one, except that there is no ConstMap for 'key'. The order is the same as the original, except that if 'key' was in the original, the last key in the ordering is moved into its place (as in the standard removal spec).

This is currently horribly inefficient. Can be made efficient by using backward deltas.

Parameters:
key - nullOk;

sortKeys

public ConstMap sortKeys()
Enabled: Returns a snapshot of this mapping, but reordered so the keys are in ascending order.


sortKeys

public ConstMap sortKeys(CompFunc func)
Enabled: Returns a snapshot of this mapping, but reordered so the keys are in ascending order according to func.


sortValues

public ConstMap sortValues()
Enabled: Returns a snapshot of this mapping, but reordered so the values are in ascending order.


sortValues

public ConstMap sortValues(CompFunc func)
Enabled: Returns a snapshot of this mapping, but reordered so the values are in ascending order according to func.


permute

private ConstMap permute(Number[] permutation,
                         Object oldKeys,
                         Object oldVals)

keyType

public abstract Class keyType()
Enabled: All keys in this map must be of this type.

XXX Should this return a ValueGuard rather than a Class?


valueType

public abstract Class valueType()
Enabled: All values in this map must be of this type

XXX Should this return a ValueGuard rather than a Class?


printOn

public void printOn(String left,
                    String map,
                    String sep,
                    String right,
                    TextWriter out)
             throws IOException
Enabled: Onto out, print 'left' key0 'map' value0 'sep' ... 'right'

IOException

toString

public String toString()
Suppressed:

Overrides:
toString in class Object
Returns:
a string representation of the object.


comments?