From 7336f11d6f4fe01f1078e53e756fcb77c57b89b5 Mon Sep 17 00:00:00 2001 From: Ray Greenwell Date: Sat, 11 Mar 2006 02:43:32 +0000 Subject: [PATCH] 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 --- .../com/threerings/presents/dobj/DSet.java | 48 +++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/src/java/com/threerings/presents/dobj/DSet.java b/src/java/com/threerings/presents/dobj/DSet.java index a15683c40..b7aaf4c72 100644 --- a/src/java/com/threerings/presents/dobj/DSet.java +++ b/src/java/com/threerings/presents/dobj/DSet.java @@ -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];