[Red5commits] [1601] Shared objects package documenting is complete. Some minor code improvements.

mklishin luke at codegent.com
Wed Jan 24 11:03:48 EST 2007


Shared objects package documenting is complete. Some minor code improvements.


Timestamp: 12/24/06 22:15:19 EST (1 month ago) 
Change: 1601 
Author: mklishin

Files (see diff or trac for details): 
java/server/trunk/src/org/red5/server/messaging/AbstractMessage.java
java/server/trunk/src/org/red5/server/so/ClientSharedObject.java
java/server/trunk/src/org/red5/server/so/ISharedObjectMessage.java
java/server/trunk/src/org/red5/server/so/SharedObject.java
java/server/trunk/src/org/red5/server/so/SharedObjectEvent.java
java/server/trunk/src/org/red5/server/so/SharedObjectMessage.java
java/server/trunk/src/org/red5/server/so/SharedObjectScope.java
java/server/trunk/src/org/red5/server/so/SharedObjectService.java


Trac: http://mirror1.cvsdude.com/trac/osflash/red5/changeset/1601

Index: /java/server/trunk/src/org/red5/server/so/SharedObjectEvent.java
===================================================================
--- /java/server/trunk/src/org/red5/server/so/SharedObjectEvent.java (revision 1597)
+++ /java/server/trunk/src/org/red5/server/so/SharedObjectEvent.java (revision 1601)
@@ -20,12 +20,24 @@
  */
 
+/**
+ * {@inheritDoc}
+ */
 public class SharedObjectEvent implements ISharedObjectEvent {
-
+    /**
+     * Event type
+     */
 	private Type type;
-
+    /**
+     * Changed pair key
+     */
 	private String key;
-
+    /**
+     * Changed pair value
+     */
 	private Object value;
 
+    /**
+     * {@inheritDoc}
+     */
 	public SharedObjectEvent(Type type, String key, Object value) {
 		this.type = type;
Index: /java/server/trunk/src/org/red5/server/so/SharedObjectMessage.java
===================================================================
--- /java/server/trunk/src/org/red5/server/so/SharedObjectMessage.java (revision 1597)
+++ /java/server/trunk/src/org/red5/server/so/SharedObjectMessage.java (revision 1601)
@@ -20,27 +20,55 @@
  */
 
+import org.red5.server.api.event.IEventListener;
+import org.red5.server.net.rtmp.event.BaseEvent;
+
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 
-import org.red5.server.api.event.IEventListener;
-import org.red5.server.net.rtmp.event.BaseEvent;
-
+/**
+ * Shared object event
+ */
 public class SharedObjectMessage extends BaseEvent implements
 		ISharedObjectMessage {
 
-	private String name;
+    /**
+     * SO event name
+     */
+    private String name;
 
-	private LinkedList<ISharedObjectEvent> events = new LinkedList<ISharedObjectEvent>();
+    /**
+     * SO events chain
+     */
+    private LinkedList<ISharedObjectEvent> events = new LinkedList<ISharedObjectEvent>();
+    /**
+     * SO version, used for synchronization purposes
+     */
+	private int version;
+    /**
+     * Whether SO persistent
+     */
+	private boolean persistent;
 
-	private int version = 0;
-
-	private boolean persistent = false;
-
-	public SharedObjectMessage(String name, int version, boolean persistent) {
+    /**
+     * Creates Shared Object event with given name, version and persistence flag
+     *
+     * @param name          Event name
+     * @param version       SO version
+     * @param persistent    SO persistence flag
+     */
+    public SharedObjectMessage(String name, int version, boolean persistent) {
 		this(null, name, version, persistent);
 	}
 
-	public SharedObjectMessage(IEventListener source, String name, int version,
+    /**
+     * Creates Shared Object event with given listener, name, SO version and persistence flag
+     *
+     * @param source         Event listener
+     * @param name           Event name
+     * @param version        SO version
+     * @param persistent     SO persistence flag
+     */
+    public SharedObjectMessage(IEventListener source, String name, int version,
 			boolean persistent) {
 		super(Type.SHARED_OBJECT, source);
@@ -62,7 +90,7 @@
 
 	/**
-     * Setter for property 'version'.
+     * Setter for version
      *
-     * @param version Value to set for property 'version'.
+     * @param version  New version
      */
     protected void setVersion(int version) {
@@ -76,7 +104,7 @@
 
 	/**
-     * Setter for property 'name'.
+     * Setter for name
      *
-     * @param name Value to set for property 'name'.
+     * @param name  Event name
      */
     protected void setName(String name) {
@@ -90,7 +118,7 @@
 
 	/**
-     * Setter for property 'isPersistent'.
+     * Setter for persistence flag
      *
-     * @param persistent Value to set for property 'isPersistent'.
+     * @param persistent  Persistence flag
      */
     protected void setIsPersistent(boolean persistent) {
Index: /java/server/trunk/src/org/red5/server/so/SharedObjectScope.java
===================================================================
--- /java/server/trunk/src/org/red5/server/so/SharedObjectScope.java (revision 1597)
+++ /java/server/trunk/src/org/red5/server/so/SharedObjectScope.java (revision 1601)
@@ -20,14 +20,4 @@
  */
 
-import java.lang.reflect.Method;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.locks.ReentrantLock;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -44,16 +34,40 @@
 import org.red5.server.service.ServiceUtils;
 
+import java.lang.reflect.Method;
+import java.util.*;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Special scope for shared objects
+ */
 public class SharedObjectScope extends BasicScope implements ISharedObject {
-
+    /**
+     *
+     */
 	private Log log = LogFactory.getLog(SharedObjectScope.class.getName());
-
+    /**
+     * Lock to synchronize shared object updates from multiple threads
+     */
 	private final ReentrantLock lock = new ReentrantLock();
-
+    /**
+     * Server-side listeners
+     */
 	private HashSet<ISharedObjectListener> serverListeners = new HashSet<ISharedObjectListener>();
-
+    /**
+     * Event handlers
+     */
 	private HashMap<String, Object> handlers = new HashMap<String, Object>();
-
+    /**
+     * Scoped shared object
+     */
 	protected SharedObject so;
 
+    /**
+     * Creates shared object with given parent scope, name, persistence flag state and store object
+     * @param parent                    Parent scope
+     * @param name                      Name
+     * @param persistent                Persistence flag state
+     * @param store                     Persistence store
+     */
 	public SharedObjectScope(IScope parent, String name, boolean persistent,
 			IPersistenceStore store) {
@@ -65,11 +79,14 @@
 			path = '/' + path;
 		}
-		so = (SharedObject) store.load(TYPE + path + '/' + name);
-		if (so == null) {
+        // Load SO
+        so = (SharedObject) store.load(TYPE + path + '/' + name);
+		// Create if it doesn't exist
+        if (so == null) {
 			so = new SharedObject(attributes, name, path, persistent, store);
-
+            // Save
 			store.save(so);
 		} else {
-			so.setName(name);
+            // Rename and set path
+            so.setName(name);
 			so.setPath(parent.getContextPath());
 		}
@@ -77,7 +94,7 @@
 
 	/**
-     * Setter for property 'persistenceClass'.
+     * Setter for persistence class.
      *
-     * @param persistenceClass Value to set for property 'persistenceClass'.
+     * @param persistenceClass  Persistence class.
      */
     public void setPersistenceClass(String persistenceClass) {
@@ -136,14 +153,18 @@
 	/** {@inheritDoc} */
     public synchronized void beginUpdate(IEventListener listener) {
-		if (!lock.isHeldByCurrentThread()) {
+        // If lock is not held by current thread then lock it
+        if (!lock.isHeldByCurrentThread()) {
 			lock.lock();
 		}
-		so.beginUpdate(listener);
+        // Begin updating SO with this listener
+        so.beginUpdate(listener);
 	}
 
 	/** {@inheritDoc} */
     public synchronized void endUpdate() {
-		so.endUpdate();
-		if (so.updateCounter == 0) {
+		// End update of SO
+        so.endUpdate();
+        // Release lock
+        if (so.updateCounter == 0) {
 			lock.unlock();
 		}
@@ -208,10 +229,8 @@
 
 		// Notify server listeners
-		Iterator<ISharedObjectListener> it = serverListeners.iterator();
-		while (it.hasNext()) {
-			ISharedObjectListener listener = it.next();
-			listener.onSharedObjectSend(this, handler, arguments);
-		}
-	}
+        for (ISharedObjectListener listener : serverListeners) {
+            listener.onSharedObjectSend(this, handler, arguments);
+        }
+    }
 
 	/** {@inheritDoc} */
@@ -223,10 +242,8 @@
 
 		if (success) {
-			Iterator<ISharedObjectListener> it = serverListeners.iterator();
-			while (it.hasNext()) {
-				ISharedObjectListener listener = it.next();
-				listener.onSharedObjectDelete(this, name);
-			}
-		}
+            for (ISharedObjectListener listener : serverListeners) {
+                listener.onSharedObjectDelete(this, name);
+            }
+        }
 		return success;
 	}
@@ -239,10 +256,8 @@
 		endUpdate();
 
-		Iterator<ISharedObjectListener> it = serverListeners.iterator();
-		while (it.hasNext()) {
-			ISharedObjectListener listener = it.next();
-			listener.onSharedObjectClear(this);
-		}
-	}
+        for (ISharedObjectListener listener : serverListeners) {
+            listener.onSharedObjectClear(this);
+        }
+    }
 
 	/** {@inheritDoc} */
@@ -252,10 +267,8 @@
 		so.register(listener);
 
-		Iterator<ISharedObjectListener> it = serverListeners.iterator();
-		while (it.hasNext()) {
-			ISharedObjectListener soListener = it.next();
-			soListener.onSharedObjectConnect(this);
-		}
-	}
+        for (ISharedObjectListener soListener : serverListeners) {
+            soListener.onSharedObjectConnect(this);
+        }
+    }
 
 	/** {@inheritDoc} */
@@ -268,10 +281,8 @@
 		}
 
-		Iterator<ISharedObjectListener> it = serverListeners.iterator();
-		while (it.hasNext()) {
-			ISharedObjectListener soListener = it.next();
-			soListener.onSharedObjectDisconnect(this);
-		}
-	}
+        for (ISharedObjectListener soListener : serverListeners) {
+            soListener.onSharedObjectDisconnect(this);
+        }
+    }
 
 	/** {@inheritDoc} */
@@ -361,10 +372,8 @@
 
 		if (success) {
-			Iterator<ISharedObjectListener> it = serverListeners.iterator();
-			while (it.hasNext()) {
-				ISharedObjectListener listener = it.next();
-				listener.onSharedObjectUpdate(this, name, value);
-			}
-		}
+            for (ISharedObjectListener listener : serverListeners) {
+                listener.onSharedObjectUpdate(this, name, value);
+            }
+        }
 		return success;
 	}
@@ -377,10 +386,8 @@
 		endUpdate();
 
-		Iterator<ISharedObjectListener> it = serverListeners.iterator();
-		while (it.hasNext()) {
-			ISharedObjectListener listener = it.next();
-			listener.onSharedObjectUpdate(this, values);
-		}
-	}
+        for (ISharedObjectListener listener : serverListeners) {
+            listener.onSharedObjectUpdate(this, values);
+        }
+    }
 
 	/** {@inheritDoc} */
@@ -391,10 +398,8 @@
 		endUpdate();
 
-		Iterator<ISharedObjectListener> it = serverListeners.iterator();
-		while (it.hasNext()) {
-			ISharedObjectListener listener = it.next();
-			listener.onSharedObjectUpdate(this, values);
-		}
-	}
+        for (ISharedObjectListener listener : serverListeners) {
+            listener.onSharedObjectUpdate(this, values);
+        }
+    }
 
 	/** {@inheritDoc} */
Index: /java/server/trunk/src/org/red5/server/so/ISharedObjectMessage.java
===================================================================
--- /java/server/trunk/src/org/red5/server/so/ISharedObjectMessage.java (revision 1597)
+++ /java/server/trunk/src/org/red5/server/so/ISharedObjectMessage.java (revision 1601)
@@ -20,8 +20,11 @@
  */
 
+import org.red5.server.net.rtmp.event.IRTMPEvent;
+
 import java.util.List;
 
-import org.red5.server.net.rtmp.event.IRTMPEvent;
-
+/**
+ * Shared object message
+ */
 public interface ISharedObjectMessage extends IRTMPEvent {
 
@@ -56,14 +59,27 @@
 	public List<ISharedObjectEvent> getEvents();
 
-	public void addEvent(ISharedObjectEvent.Type type, String key, Object value);
+    /**
+     * Addition event handler
+     * @param type           Event type
+     * @param key            Handler key
+     * @param value          Event value (like arguments)
+     */
+    public void addEvent(ISharedObjectEvent.Type type, String key, Object value);
 
+    /**
+     * Add event handler
+     * @param event          SO event
+     */
 	public void addEvent(ISharedObjectEvent event);
 
-	public void clear();
+    /**
+     * Clear shared object
+     */
+    public void clear();
 
 	/**
-     * Getter for property 'empty'.
+     * Is empty?
      *
-     * @return Value for property 'empty'.
+     * @return  <code>true</code> if shared object is empty, <code>false</code> otherwise
      */
     public boolean isEmpty();
Index: /java/server/trunk/src/org/red5/server/so/ClientSharedObject.java
===================================================================
--- /java/server/trunk/src/org/red5/server/so/ClientSharedObject.java (revision 1597)
+++ /java/server/trunk/src/org/red5/server/so/ClientSharedObject.java (revision 1601)
@@ -20,13 +20,4 @@
  */
 
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.locks.ReentrantLock;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -41,15 +32,40 @@
 import org.red5.server.so.ISharedObjectEvent.Type;
 
+import java.util.*;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Works with client-side shared object
+ */
 public class ClientSharedObject extends SharedObject implements
 		IClientSharedObject, IEventDispatcher {
 
-	protected static Log log = LogFactory.getLog(ClientSharedObject.class.getName());
-
-	private boolean initialSyncReceived = false;
-	private final ReentrantLock lock = new ReentrantLock();
-	private HashSet<ISharedObjectListener> listeners = new HashSet<ISharedObjectListener>();
-	private HashMap<String, Object> handlers = new HashMap<String, Object>();
-
-	public ClientSharedObject(String name, boolean persistent) {
+    /**
+     * Logger
+     */
+    protected static Log log = LogFactory.getLog(ClientSharedObject.class.getName());
+    /**
+     * Initial synchronization flag
+     */
+	private boolean initialSyncReceived;
+    /**
+     * Synchronization lock
+     */
+    private final ReentrantLock lock = new ReentrantLock();
+    /**
+     * Set of listeners
+     */
+    private HashSet<ISharedObjectListener> listeners = new HashSet<ISharedObjectListener>();
+    /**
+     * Set of event handlers
+     */
+    private HashMap<String, Object> handlers = new HashMap<String, Object>();
+
+    /**
+     * Create new client SO with
+     * @param name              Shared Object name
+     * @param persistent        Persistence flag
+     */
+    public ClientSharedObject(String name, boolean persistent) {
 		super();
 		this.name = name;
@@ -60,5 +76,5 @@
 	 * Connect the shared object using the passed connection.
 	 * 
-	 * @param conn
+	 * @param conn              Attach SO to given connection
 	 */
 	public void connect(IConnection conn) {
@@ -77,5 +93,5 @@
 	
 	/**
-	 * Disconnect the shared object.
+	 * Disconnect shared object.
 	 */
 	public void disconnect() {
@@ -156,29 +172,39 @@
 	}
 
-	protected void notifyConnect() {
-		Iterator<ISharedObjectListener> it = listeners.iterator();
-		while (it.hasNext()) {
-			ISharedObjectListener listener = it.next();
-			listener.onSharedObjectConnect(this);
-		}
-	}
-	
-	protected void notifyDisconnect() {
-		Iterator<ISharedObjectListener> it = listeners.iterator();
-		while (it.hasNext()) {
-			ISharedObjectListener listener = it.next();
-			listener.onSharedObjectDisconnect(this);
-		}
-	}
-	
-	protected void notifyUpdate(String key, Object value) {
-		Iterator<ISharedObjectListener> it = listeners.iterator();
-		while (it.hasNext()) {
-			ISharedObjectListener listener = it.next();
-			listener.onSharedObjectUpdate(this, key, value);
-		}
-	}
-	
-	protected void notifyUpdate(String key, Map<String, Object> value) {
+    /**
+     * Notify listeners on event
+     */
+    protected void notifyConnect() {
+        for (ISharedObjectListener listener : listeners) {
+            listener.onSharedObjectConnect(this);
+        }
+    }
+
+    /**
+     * Notify listeners on disconnect
+     */
+    protected void notifyDisconnect() {
+        for (ISharedObjectListener listener : listeners) {
+            listener.onSharedObjectDisconnect(this);
+        }
+    }
+
+    /**
+     * Notify listeners on update
+     * @param key         Updated attribute key
+     * @param value       Updated attribute value
+     */
+    protected void notifyUpdate(String key, Object value) {
+        for (ISharedObjectListener listener : listeners) {
+            listener.onSharedObjectUpdate(this, key, value);
+        }
+    }
+
+    /**
+     * Notify listeners on map attribute update
+     * @param key         Updated attribute key
+     * @param value       Updated attribute value
+     */
+    protected void notifyUpdate(String key, Map<String, Object> value) {
 		if (value.size() == 1) {
 			Map.Entry<String, Object> entry = value.entrySet().iterator().next();
@@ -186,34 +212,38 @@
 			return;
 		}
-		Iterator<ISharedObjectListener> it = listeners.iterator();
-		while (it.hasNext()) {
-			ISharedObjectListener listener = it.next();
-			listener.onSharedObjectUpdate(this, key, value);
-		}
-	}
-	
-	protected void notifyDelete(String key) {
-		Iterator<ISharedObjectListener> it = listeners.iterator();
-		while (it.hasNext()) {
-			ISharedObjectListener listener = it.next();
-			listener.onSharedObjectDelete(this, key);
-		}
-	}
-
-	protected void notifyClear() {
-		Iterator<ISharedObjectListener> it = listeners.iterator();
-		while (it.hasNext()) {
-			ISharedObjectListener listener = it.next();
-			listener.onSharedObjectClear(this);
-		}
-	}
-
-	protected void notifySendMessage(String method, List params) {
-		Iterator<ISharedObjectListener> it = listeners.iterator();
-		while (it.hasNext()) {
-			ISharedObjectListener listener = it.next();
-			listener.onSharedObjectSend(this, method, params);
-		}
-	}
+        for (ISharedObjectListener listener : listeners) {
+            listener.onSharedObjectUpdate(this, key, value);
+        }
+    }
+
+    /**
+     * Notify listeners on attribute delete
+     * @param key       Attribute name
+     */
+    protected void notifyDelete(String key) {
+        for (ISharedObjectListener listener : listeners) {
+            listener.onSharedObjectDelete(this, key);
+        }
+    }
+
+    /**
+     * Notify listeners on clear
+     */
+    protected void notifyClear() {
+        for (ISharedObjectListener listener : listeners) {
+            listener.onSharedObjectClear(this);
+        }
+    }
+
+    /**
+     * Broadcast send event to listeners
+     * @param method        Method name
+     * @param params        Params
+     */
+    protected void notifySendMessage(String method, List params) {
+        for (ISharedObjectListener listener : listeners) {
+            listener.onSharedObjectSend(this, method, params);
+        }
+    }
 
 	/** {@inheritDoc} */
@@ -245,10 +275,8 @@
 		// TODO: there must be a direct way to clear the SO on the client
 		// side...
-		Iterator keys = data.keySet().iterator();
-		while (keys.hasNext()) {
-			String key = (String) keys.next();
-			ownerMessage.addEvent(Type.SERVER_DELETE_ATTRIBUTE, key, null);
-		}
-		notifyModified();
+        for (String key : data.keySet()) {
+            ownerMessage.addEvent(Type.SERVER_DELETE_ATTRIBUTE, key, null);
+        }
+        notifyModified();
 	}
 
@@ -377,5 +405,5 @@
 
 	/** {@inheritDoc} */
-    synchronized public Object getAttribute(String name, Object defaultValue) {
+    public synchronized Object getAttribute(String name, Object defaultValue) {
 		if (!hasAttribute(name)) {
 			setAttribute(name, defaultValue);
Index: /java/server/trunk/src/org/red5/server/so/SharedObject.java
===================================================================
--- /java/server/trunk/src/org/red5/server/so/SharedObject.java (revision 1597)
+++ /java/server/trunk/src/org/red5/server/so/SharedObject.java (revision 1601)
@@ -20,17 +20,4 @@
  */
 
-import static org.red5.server.api.so.ISharedObject.TYPE;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -43,4 +30,5 @@
 import org.red5.server.api.persistence.IPersistable;
 import org.red5.server.api.persistence.IPersistenceStore;
+import static org.red5.server.api.so.ISharedObject.TYPE;
 import org.red5.server.net.rtmp.Channel;
 import org.red5.server.net.rtmp.RTMPConnection;
@@ -48,71 +36,167 @@
 import org.red5.server.so.ISharedObjectEvent.Type;
 
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Represents shared object on server-side. Shared Objects in Flash are like cookies that are stored
+ * on client side. In Red5 and Flash Media Server there's one more special type of SOs : remote Shared Objects.
+ *
+ * These are shared by multiple clients and synchronized between them automatically on each data change. This is done
+ * asynchronously, used as events handling and is widely used in multiplayer Flash online games.
+ *
+ * Shared object can be persistent or transient. The difference is that first are saved to the disk and can be
+ * accessed later on next connection, transient objects are not saved and get lost each time they last client
+ * disconnects from it.
+ *
+ * Shared Objects has name identifiers and path on server's HD (if persistent). On deeper level server-side
+ * Shared Object in this implementation actually uses IPersistenceStore to delegate all (de)serialization work.
+ *
+ * SOs store data as simple map, that is, "name-value" pairs. Each value in turn can be complex object or map.
+ */
 public class SharedObject implements IPersistable, Constants {
-
+    /**
+     * Logger
+     */
 	protected static Log log = LogFactory.getLog(SharedObject.class.getName());
 
-	protected String name = "";
-
-	protected String path = "";
-
-	// true if the SharedObject was stored by the persistence framework 
-	protected boolean persistent = false;
-
-	// true if the client / server created the SO to be persistent
-	protected boolean persistentSO = false;
-
-	protected IPersistenceStore storage = null;
-
-	protected int version = 1;
-
-	protected Map<String, Object> data = null;
-
-	protected Map<String, Integer> hashes = new HashMap<String, Integer>();
-
-	protected int updateCounter = 0;
-
-	protected boolean modified = false;
-
-	protected long lastModified = -1;
-
-	protected SharedObjectMessage ownerMessage;
-
-	protected LinkedList<ISharedObjectEvent> syncEvents = new LinkedList<ISharedObjectEvent>();
-
-	protected HashSet<IEventListener> listeners = new HashSet<IEventListener>();
-
-	protected IEventListener source = null;
+    /**
+     * Shared Object name (identifier)
+     */
+    protected String name = "";
+
+    /**
+     * SO path
+     */
+    protected String path = "";
+
+    /**
+     * true if the SharedObject was stored by the persistence framework (NOT in database,
+     * just plain serialization to the disk) and can be used later on reconnection
+     */
+
+	protected boolean persistent;
+
+    /**
+     * true if the client / server created the SO to be persistent
+     */
+	protected boolean persistentSO;
+
+    /**
+     * Object that is delegated with all storage work for persistent SOs
+     */
+    protected IPersistenceStore storage;
+
+    /**
+     * Version. Used on synchronization purposes.
+     */
+    protected int version = 1;
+
+    /**
+     * SO data
+     */
+    protected Map<String, Object> data;
+
+    /**
+     * SO hashes
+     */
+    protected Map<String, Integer> hashes = new HashMap<String, Integer>();
+
+    /**
+     * Number of pending update operations
+     */
+    protected int updateCounter;
+
+    /**
+     * Has changes? flag
+     */
+    protected boolean modified;
+
+    /**
+     * Last modified timestamp
+     */
+    protected long lastModified = -1;
+
+    /**
+     * Owner event
+     */
+    protected SharedObjectMessage ownerMessage;
+
+    /**
+     * Synchronization events
+     */
+    protected LinkedList<ISharedObjectEvent> syncEvents = new LinkedList<ISharedObjectEvent>();
+
+    /**
+     * Liste

Note:
Diffs are chopped if more than 25k.
This is to get past the limit on the mailing list.



More information about the Red5commits mailing list