Check and fail if a DSet is modified while we are iterating over it.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2380 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
//
|
//
|
||||||
// $Id: DSet.java,v 1.27 2003/03/26 00:16:03 ray Exp $
|
// $Id: DSet.java,v 1.28 2003/04/05 20:30:44 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.presents.dobj;
|
package com.threerings.presents.dobj;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.ConcurrentModificationException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import com.samskivert.util.ArrayUtil;
|
import com.samskivert.util.ArrayUtil;
|
||||||
@@ -151,15 +152,23 @@ public class DSet
|
|||||||
{
|
{
|
||||||
return new Iterator() {
|
return new Iterator() {
|
||||||
public boolean hasNext () {
|
public boolean hasNext () {
|
||||||
|
checkComodification();
|
||||||
return (_index < _size);
|
return (_index < _size);
|
||||||
}
|
}
|
||||||
public Object next () {
|
public Object next () {
|
||||||
|
checkComodification();
|
||||||
return _entries[_index++];
|
return _entries[_index++];
|
||||||
}
|
}
|
||||||
public void remove () {
|
public void remove () {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
protected void checkComodification () {
|
||||||
|
if (_modCount != _expectedModCount) {
|
||||||
|
throw new ConcurrentModificationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
protected int _index = 0;
|
protected int _index = 0;
|
||||||
|
protected int _expectedModCount = _modCount;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,6 +237,7 @@ public class DSet
|
|||||||
// stuff the entry into the array and note that we're bigger
|
// stuff the entry into the array and note that we're bigger
|
||||||
_entries[eidx] = elem;
|
_entries[eidx] = elem;
|
||||||
_size++;
|
_size++;
|
||||||
|
_modCount++;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -266,6 +276,7 @@ public class DSet
|
|||||||
// shift the remaining elements down
|
// shift the remaining elements down
|
||||||
System.arraycopy(_entries, eidx+1, _entries, eidx, _size-eidx-1);
|
System.arraycopy(_entries, eidx+1, _entries, eidx, _size-eidx-1);
|
||||||
_entries[--_size] = null;
|
_entries[--_size] = null;
|
||||||
|
_modCount++;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -292,6 +303,7 @@ public class DSet
|
|||||||
// if we found it, update it
|
// if we found it, update it
|
||||||
if (eidx >= 0) {
|
if (eidx >= 0) {
|
||||||
_entries[eidx] = elem;
|
_entries[eidx] = elem;
|
||||||
|
_modCount++;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@@ -307,7 +319,7 @@ public class DSet
|
|||||||
DSet nset = (DSet)super.clone();
|
DSet nset = (DSet)super.clone();
|
||||||
nset._entries = new Entry[_entries.length];
|
nset._entries = new Entry[_entries.length];
|
||||||
System.arraycopy(_entries, 0, nset._entries, 0, _entries.length);
|
System.arraycopy(_entries, 0, nset._entries, 0, _entries.length);
|
||||||
nset._size = _size;
|
nset._modCount = 0;
|
||||||
return nset;
|
return nset;
|
||||||
} catch (CloneNotSupportedException cnse) {
|
} catch (CloneNotSupportedException cnse) {
|
||||||
throw new RuntimeException("WTF? " + cnse);
|
throw new RuntimeException("WTF? " + cnse);
|
||||||
@@ -339,6 +351,9 @@ public class DSet
|
|||||||
/** The number of entries in this set. */
|
/** The number of entries in this set. */
|
||||||
protected int _size;
|
protected int _size;
|
||||||
|
|
||||||
|
/** Used to check for concurrent modification. */
|
||||||
|
protected transient int _modCount;
|
||||||
|
|
||||||
/** The default capacity of a set instance. */
|
/** The default capacity of a set instance. */
|
||||||
protected static final int INITIAL_CAPACITY = 2;
|
protected static final int INITIAL_CAPACITY = 2;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user