/* File: IncrBag.java Originally written by Doug Lea and released into the public domain. Thanks for the assistance and support of Sun Microsystems Labs, Agorics Inc, Loral, and everyone contributing, testing, and using this code. History: Date Who What 24Sep95 dl@cs.oswego.edu Create from collections.java working file 13Oct95 dl Changed to use accessOnly */ package collections; import java.util.Enumeration; import java.util.NoSuchElementException; /** * * * Incremental Implementation of Immutable Bag * @author Doug Lea * @version 0.93 * *
For an introduction to this package see Overview . **/ public final class IncrBag extends IncrImpl implements Immutable, Bag { private int occurrencesArg_; /** * Make a new pure bag using the default underlying Bag implementation **/ public IncrBag() { this(DefaultImplementations.bag()); } /** * Make a pure bag managing the given updatable bag s. * Warning: Do not modify s during the the lifetime of the constructed pure bag! **/ public IncrBag(UpdatableBag s) { super(s); occurrencesArg_ = 0; } /** * Make a copy. Uses lazy update. **/ protected Object clone() throws CloneNotSupportedException { undelta(); IncrBag s = new IncrBag((UpdatableBag)(updatable_)); nextVersion_ = s; updatable_ = null; op_ = NO_EDIT; return s; } /** * Implements collections.Bag.addingIfAbsent * @see collections.Bag#addingIfAbsent **/ public synchronized /* IncrBag */ Bag addingIfAbsent(Object element) throws IllegalElementException { undelta(); UpdatableBag u = (UpdatableBag)updatable_; boolean has = u.includes(element); if (has) return this; else { u.add(element); IncrBag s = new IncrBag(u); nextVersion_ = s; updatable_ = null; firstObjectArg_ = element; occurrencesArg_ = 1; op_ = REMOVE_EDIT; return s; } } /** * Implements collections.Bag.adding * @see collections.Bag#adding **/ public synchronized /* IncrBag */ Bag adding(Object element) throws IllegalElementException { undelta(); UpdatableBag u = (UpdatableBag)updatable_; u.add(element); IncrBag s = new IncrBag(u); nextVersion_ = s; updatable_ = null; occurrencesArg_ = 1; firstObjectArg_ = element; op_ = REMOVE_EDIT; return s; } /** * Implements collections.Collection.excluding. * @see collections.Collection#excluding **/ public synchronized /* IncrBag */ Collection excluding(Object element) { undelta(); UpdatableBag u = (UpdatableBag)updatable_; int occ = u.occurrencesOf(element); if (occ == 0) return this; else { u.exclude(element); IncrBag s = new IncrBag(u); nextVersion_ = s; updatable_ = null; firstObjectArg_ = element; occurrencesArg_ = occ; op_ = ADD_EDIT; return s; } } /** * Implements collections.Collection.removingOneOf * @see collections.Collection#removingOneOf **/ public synchronized /* IncrBag */ Collection removingOneOf(Object element) { undelta(); UpdatableBag u = (UpdatableBag)updatable_; int occ = u.occurrencesOf(element); if (occ == 0) return this; else { u.removeOneOf(element); IncrBag s = new IncrBag(u); nextVersion_ = s; updatable_ = null; firstObjectArg_ = element; occurrencesArg_ = 1; op_ = ADD_EDIT; return s; } } /** * Implements collections.Collection.replacingAllOf * @see collections.Collection#replacingAllOf **/ public synchronized /* IncrBag */ Collection replacingAllOf(Object oldElement, Object newElement) throws IllegalElementException { undelta(); UpdatableBag u = (UpdatableBag)updatable_; int oldocc = u.occurrencesOf(oldElement); if (oldocc == 0) return this; else { u.replaceAllOf(oldElement, newElement); IncrBag s = new IncrBag(u); nextVersion_ = s; updatable_ = null; firstObjectArg_ = newElement; secondObjectArg_ = oldElement; op_ = REPLACE_EDIT; occurrencesArg_ = oldocc; return s; } } /** * Implements collections.Collection.replacingOneOf * @see collections.Collection#replacingOneOf **/ public synchronized /* IncrBag */ Collection replacingOneOf(Object oldElement, Object newElement) throws IllegalElementException { undelta(); UpdatableBag u = (UpdatableBag)updatable_; boolean has = u.includes(oldElement); if (!has) return this; else { u.replaceOneOf(oldElement, newElement); IncrBag s = new IncrBag(u); nextVersion_ = s; updatable_ = null; firstObjectArg_ = newElement; secondObjectArg_ = oldElement; op_ = REPLACE_EDIT; occurrencesArg_ = 1; return s; } } /** * Perform updates within an edit chain **/ protected synchronized UpdatableCollection doEdit(UpdatableCollection c) { UpdatableBag u = (UpdatableBag)c; try { for (int i = 0; i < occurrencesArg_; ++i) { if (op_ == ADD_EDIT) u.add(firstObjectArg_); else if (op_ == REMOVE_EDIT) u.removeOneOf(firstObjectArg_); else if (op_ == REPLACE_EDIT) u.replaceOneOf(firstObjectArg_, secondObjectArg_); } } catch (IllegalElementException ex) {} // we've screened for all possible return u; } }