Shrink capacity in DSets upon element removal if the capacity is 8x larger
than it needs to be. Broke streaming compatibility in order to be much more efficient over the wire. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3938 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -21,6 +21,8 @@
|
||||
|
||||
package com.threerings.presents.dobj;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
@@ -28,6 +30,8 @@ import java.util.Iterator;
|
||||
import com.samskivert.util.ArrayUtil;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
import com.threerings.io.ObjectOutputStream;
|
||||
import com.threerings.io.Streamable;
|
||||
|
||||
import com.threerings.presents.Log;
|
||||
@@ -315,10 +319,22 @@ public class DSet
|
||||
|
||||
// if we found it, remove it
|
||||
if (eidx >= 0) {
|
||||
// shift the remaining elements down
|
||||
// extract the old entry
|
||||
Entry oldEntry = _entries[eidx];
|
||||
System.arraycopy(_entries, eidx+1, _entries, eidx, _size-eidx-1);
|
||||
_entries[--_size] = null;
|
||||
_size--;
|
||||
if ((_entries.length > INITIAL_CAPACITY) &&
|
||||
(_size < _entries.length/8)) {
|
||||
// if we're using less than 1/8 of our capacity, shrink by half
|
||||
Entry[] newEnts = new Entry[_entries.length/2];
|
||||
System.arraycopy(_entries, 0, newEnts, 0, eidx);
|
||||
System.arraycopy(_entries, eidx+1, newEnts, eidx, _size-eidx);
|
||||
_entries = newEnts;
|
||||
|
||||
} else {
|
||||
// shift entries past the removed one downwards
|
||||
System.arraycopy(_entries, eidx+1, _entries, eidx, _size-eidx);
|
||||
_entries[_size] = null;
|
||||
}
|
||||
_modCount++;
|
||||
return oldEntry;
|
||||
|
||||
@@ -389,6 +405,32 @@ public class DSet
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/** Custom writer method. @see Streamable. */
|
||||
public void writeObject (ObjectOutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeInt(_size);
|
||||
for (int ii = 0; ii < _size; ii++) {
|
||||
out.writeObject(_entries[ii]);
|
||||
}
|
||||
}
|
||||
|
||||
/** Custom reader method. @see Streamable. */
|
||||
public void readObject (ObjectInputStream in)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
_size = in.readInt();
|
||||
// ensure our capacity is a power of 2 (for consistency)
|
||||
int capacity = INITIAL_CAPACITY;
|
||||
while (capacity < _size) {
|
||||
capacity <<= 1;
|
||||
}
|
||||
_entries = new Entry[capacity];
|
||||
for (int ii = 0; ii < _size; ii++) {
|
||||
_entries[ii] = (Entry) in.readObject();
|
||||
}
|
||||
}
|
||||
|
||||
/** The entries of the set (in a sparse array). */
|
||||
protected Entry[] _entries = new Entry[INITIAL_CAPACITY];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user