All Packages  Class Hierarchy  This Package  Previous  Next  Index

Class collections.IncrImpl

java.lang.Object
   |
   +----collections.IncrImpl

public abstract class IncrImpl
extends Object
implements Immutable, Collection
Base class for Immutable Collection implementations. using `negative deltas'. That is, they update an internally held Collection and set it as the internal Collection for the Immutable Collection serving as the result, but also keep a record of how to undo this change on a copy of the update, so as to reconstruct the original Collection.

Since it's usually the case that applications use updates rather than their sources, negative deltas are generally more efficient than other schemes. Also, because updates don't point to their sources, when a source becomes unreferenced, it and all of its edit records can be garbage collected. The price you pay for these nice aspects is that reconstruction of old versions is not always all that fast or cheap.

The logic of reconstruction is to work our way to the UpdatableCollection serving as the source of the edits, and then apply each undo operation all the way back up to where we are. Subclasses specialize on the exact edit operation to do at each step.

Reconstruction would be two-line recursive procedure of the form:

 UpdatableCollection reconstruct() {
   if (the lastest version) return a clone of the held UpdatableCollection
   else return edit(nextVersion.reconstruct())
 }
 
Except for two problems:
  1. We need to prevent interference among concurrent reconstructions and/or with operations on the collections themselves. But we cannot afford to hold a lock (synch) on every single node in the chain of edits at once. For long edit chains, it would require too many simultaneous locks. The java runtime could even run out of them.
  2. The recursion could get very deep, which is not a good idea in java because of how it uses the stack.

These problems are addressed by:

  1. Using a condition variable, that causes each node to lock without holding all of the locks at once. The variable used, prevVersion_ happens to be the same one used for...
  2. Putting next-links from each node to the one representing the edit which is to follow. This way we can iterate rather than use recursion.

(All this would be a little prettier if we offloaded work into Edit Command objects. But since these operations must be coordinated with the Collection nodes, it works better to roll them together.)

The code is highly particularized for the operations currently supported in the collections package. It would not be very easy to add subclasses beyond those for the four basic flavors of collection subclasses currently implemented.

Some of the basic ideas for this class are due to Mark Miller and unknown people at Xerox Parc.


Variable Index

 o ADD_EDIT
 o firstObjectArg_
Some opportunistic sharing: Subclasses happen to need records of two Object arguments for updates.
 o nextVersion_
When delta'd, a ref to the collection we generated.
 o NO_EDIT
 o op_
We can only handle a known number of undoable operations on collections, encoded into op_
 o REMOVE_EDIT
 o REPLACE_EDIT
 o secondObjectArg_
 o updatable_
The collection performing the actual work.

Constructor Index

 o IncrImpl(UpdatableCollection)

Method Index

 o accessOnly()
Special case of undelta that avoids the pin-check in cases where we are performing only non-mutative operations
 o assert(boolean)
Implements collections.ImplementationCheckable.assert.
 o canInclude(Object)
Implements collections.Collection.canInclude.
 o checkImplementation()
Implements collections.ImplementationCheckable.checkImplementation.
 o doEdit(UpdatableCollection)
Must implement in subclasses to perform subclass-specific edits
 o duplicate()
Wrapper for clone()
 o elements()
Implements collections.Collection.elements.
 o excluding(Object)
Construct a new Collection that is a clone of self except that it does not include any occurrences of the indicated element.
 o includes(Object)
Implements collections.Collection.includes.
 o isEmpty()
Implements collections.Collection.isEmpty.
 o occurrencesOf(Object)
Implements collections.Collection.occurrencesOf.
 o pin(IncrCollectionEnumeration)
Pin during a traversal.
 o removingOneOf(Object)
Construct a new Collection that is a clone of self except that it does not include an occurrence of the indicated element.
 o replacingAllOf(Object, Object)
Construct a new Collection that is a clone of self except that all occurrences of oldElement are replaced with newElement.
 o replacingOneOf(Object, Object)
Construct a new Collection that is a clone of self except that one occurrence of oldElement is replaced with newElement.
 o sameStructure(Collection)
Implements collections.Collection.sameStructure
 o size()
Implements collections.Collection.size.
 o toString()
 o undelta()
Call this as the first statement of EVERY subclass method that performs any kind of constructive update.

Variables

 o updatable_
 protected UpdatableCollection updatable_
The collection performing the actual work. Null if delta'd

 o nextVersion_
 protected IncrImpl nextVersion_
When delta'd, a ref to the collection we generated. Invariant: exactly one of updatable_ or nextVersion_ are non-null at any given time.

 o op_
 protected int op_
We can only handle a known number of undoable operations on collections, encoded into op_

 o NO_EDIT
 protected static final int NO_EDIT
 o ADD_EDIT
 protected static final int ADD_EDIT
 o REMOVE_EDIT
 protected static final int REMOVE_EDIT
 o REPLACE_EDIT
 protected static final int REPLACE_EDIT
 o firstObjectArg_
 protected Object firstObjectArg_
Some opportunistic sharing: Subclasses happen to need records of two Object arguments for updates.

 o secondObjectArg_
 protected Object secondObjectArg_

Constructors

 o IncrImpl
 protected IncrImpl(UpdatableCollection c)

Methods

 o duplicate
 public Collection duplicate()
Wrapper for clone()

See Also:
clone
 o canInclude
 public final synchronized boolean canInclude(Object element)
Implements collections.Collection.canInclude.

See Also:
canInclude
 o isEmpty
 public final synchronized boolean isEmpty()
Implements collections.Collection.isEmpty.

See Also:
isEmpty
 o size
 public final synchronized int size()
Implements collections.Collection.size.

See Also:
size
 o includes
 public final synchronized boolean includes(Object element)
Implements collections.Collection.includes.

See Also:
includes
 o occurrencesOf
 public final synchronized int occurrencesOf(Object element)
Implements collections.Collection.occurrencesOf.

See Also:
occurrencesOf
 o sameStructure
 public final synchronized boolean sameStructure(Collection c)
Implements collections.Collection.sameStructure

See Also:
sameStructure
 o elements
 public final synchronized CollectionEnumeration elements()
Implements collections.Collection.elements.

See Also:
elements
 o toString
 public final synchronized String toString()
Overrides:
toString in class Object
 o undelta
 protected final synchronized void undelta()
Call this as the first statement of EVERY subclass method that performs any kind of constructive update.

 o accessOnly
 protected final UpdatableCollection accessOnly()
Special case of undelta that avoids the pin-check in cases where we are performing only non-mutative operations

 o pin
 protected final synchronized void pin(IncrCollectionEnumeration e)
Pin during a traversal. Call from any method constructing an enumeration.

 o doEdit
 protected abstract UpdatableCollection doEdit(UpdatableCollection c)
Must implement in subclasses to perform subclass-specific edits

 o assert
 public void assert(boolean pred) throws ImplementationError
Implements collections.ImplementationCheckable.assert.

See Also:
assert
 o checkImplementation
 public synchronized void checkImplementation() throws ImplementationError
Implements collections.ImplementationCheckable.checkImplementation.

See Also:
checkImplementation

All Packages  Class Hierarchy  This Package  Previous  Next  Index