Added some warnings for illegal DSet operations and added a small

optimization in the process.
Previously, we dumped stack on the server if a entry add was illegal but
did nothing for update/remove.
On the client, we complained for updates and (indirectly) adds, but not
removes.
Now we complain everywhere.
And- as an added bonus, on the server we now do only one binary search for
updates and removals. Whee!


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3528 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Ray Greenwell
2005-04-29 02:30:23 +00:00
parent f5e5d273e7
commit 16322b1422
5 changed files with 39 additions and 26 deletions
@@ -866,8 +866,10 @@ public class DObject extends TrackedObject
// if we're on the authoritative server, we update the set immediately // if we're on the authoritative server, we update the set immediately
DSet.Entry oldEntry = null; DSet.Entry oldEntry = null;
if (_omgr != null && _omgr.isManager(this)) { if (_omgr != null && _omgr.isManager(this)) {
oldEntry = set.get(key); oldEntry = set.removeKey(key);
set.removeKey(key); if (oldEntry == null) {
Thread.dumpStack();
}
} }
// dispatch an entry removed event // dispatch an entry removed event
postEvent(new EntryRemovedEvent(_oid, name, key, oldEntry)); postEvent(new EntryRemovedEvent(_oid, name, key, oldEntry));
@@ -881,8 +883,10 @@ public class DObject extends TrackedObject
// if we're on the authoritative server, we update the set immediately // if we're on the authoritative server, we update the set immediately
DSet.Entry oldEntry = null; DSet.Entry oldEntry = null;
if (_omgr != null && _omgr.isManager(this)) { if (_omgr != null && _omgr.isManager(this)) {
oldEntry = set.get(entry.getKey()); oldEntry = set.update(entry);
set.update(entry); if (oldEntry == null) {
Thread.dumpStack();
}
} }
// dispatch an entry updated event // dispatch an entry updated event
postEvent(new EntryUpdatedEvent(_oid, name, entry, oldEntry)); postEvent(new EntryUpdatedEvent(_oid, name, entry, oldEntry));
+13 -11
View File
@@ -295,7 +295,7 @@ public class DSet
*/ */
protected boolean remove (Entry elem) protected boolean remove (Entry elem)
{ {
return removeKey(elem.getKey()); return (null != removeKey(elem.getKey()));
} }
/** /**
@@ -304,10 +304,10 @@ public class DSet
* <code>removeFrom{Set}()</code> method should be called on the * <code>removeFrom{Set}()</code> method should be called on the
* distributed object that contains the set in question. * distributed object that contains the set in question.
* *
* @return true if a matching entry was removed, false if no entry * @return the old matching entry if found and removed, null if not
* in the set matched the key. * found.
*/ */
protected boolean removeKey (Object key) protected Entry removeKey (Object key)
{ {
// look up this entry's position in our set // look up this entry's position in our set
int eidx = ArrayUtil.binarySearch( int eidx = ArrayUtil.binarySearch(
@@ -316,13 +316,14 @@ public class DSet
// if we found it, remove it // if we found it, remove it
if (eidx >= 0) { if (eidx >= 0) {
// shift the remaining elements down // shift the remaining elements down
Entry oldEntry = _entries[eidx];
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++; _modCount++;
return true; return oldEntry;
} else { } else {
return false; return null;
} }
} }
@@ -333,10 +334,10 @@ public class DSet
* <code>update{Set}()</code> method should be called on the * <code>update{Set}()</code> method should be called on the
* distributed object that contains the set in question. * distributed object that contains the set in question.
* *
* @return true if the entry was updated, false if it was not * @return the old entry that was replaced, or null if it was not
* already in the set (in which case nothing is updated). * found (in which case nothing is updated).
*/ */
protected boolean update (Entry elem) protected Entry update (Entry elem)
{ {
// look up this entry's position in our set // look up this entry's position in our set
int eidx = ArrayUtil.binarySearch( int eidx = ArrayUtil.binarySearch(
@@ -344,11 +345,12 @@ public class DSet
// if we found it, update it // if we found it, update it
if (eidx >= 0) { if (eidx >= 0) {
Entry oldEntry = _entries[eidx];
_entries[eidx] = elem; _entries[eidx] = elem;
_modCount++; _modCount++;
return true; return oldEntry;
} else { } else {
return false; return null;
} }
} }
@@ -84,7 +84,10 @@ public class EntryAddedEvent extends NamedEvent
throws ObjectAccessException throws ObjectAccessException
{ {
if (!_alreadyApplied) { if (!_alreadyApplied) {
((DSet)target.getAttribute(_name)).add(_entry); boolean added = ((DSet)target.getAttribute(_name)).add(_entry);
if (!added) {
Log.warning("Duplicate entry found [event=" + this + "].");
}
} }
return true; return true;
} }
@@ -1,5 +1,5 @@
// //
// $Id: EntryRemovedEvent.java,v 1.17 2004/08/27 02:20:20 mdb Exp $ // $Id$
// //
// Narya library - tools for developing networked games // Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved // Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
@@ -21,6 +21,8 @@
package com.threerings.presents.dobj; package com.threerings.presents.dobj;
import com.threerings.presents.Log;
/** /**
* An entry removed event is dispatched when an entry is removed from a * An entry removed event is dispatched when an entry is removed from a
* {@link DSet} attribute of a distributed object. It can also be * {@link DSet} attribute of a distributed object. It can also be
@@ -82,10 +84,14 @@ public class EntryRemovedEvent extends NamedEvent
{ {
if (_oldEntry == UNSET_OLD_ENTRY) { if (_oldEntry == UNSET_OLD_ENTRY) {
DSet set = (DSet)target.getAttribute(_name); DSet set = (DSet)target.getAttribute(_name);
// fetch the previous value for interested callers // remove, fetch the previous value for interested callers
_oldEntry = set.get(_key); _oldEntry = set.removeKey(_key);
// remove it from the set if (_oldEntry == null) {
set.removeKey(_key); // complain if there was actually nothing there
Log.warning("No matching entry to remove [key=" + _key +
", set=" + set + "].");
return false;
}
} }
return true; return true;
} }
@@ -1,5 +1,5 @@
// //
// $Id: EntryUpdatedEvent.java,v 1.13 2004/08/27 02:20:20 mdb Exp $ // $Id$
// //
// Narya library - tools for developing networked games // Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved // Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
@@ -87,10 +87,8 @@ public class EntryUpdatedEvent extends NamedEvent
if (_oldEntry == UNSET_OLD_ENTRY) { if (_oldEntry == UNSET_OLD_ENTRY) {
DSet set = (DSet)target.getAttribute(_name); DSet set = (DSet)target.getAttribute(_name);
// fetch the previous value for interested callers // fetch the previous value for interested callers
_oldEntry = set.get(_entry.getKey()); _oldEntry = set.update(_entry);
if (_oldEntry == null) {
// update the entry
if (!set.update(_entry)) {
// complain if we didn't update anything // complain if we didn't update anything
Log.warning("No matching entry to update [entry=" + this + Log.warning("No matching entry to update [entry=" + this +
", set=" + set + "]."); ", set=" + set + "].");