[Red5commits] [2441] store objects to update in one Map only

jbauch luke at codegent.com
Tue Oct 30 23:50:33 PDT 2007


store objects to update in one Map only


Timestamp: 10/25/07 15:17:29 EST (5 days ago) 
Change: 2441 
Author: jbauch

Files (see diff or trac for details): 
java/server/trunk/src/org/red5/server/persistence/FilePersistenceThread.java


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

Index: /java/server/trunk/src/org/red5/server/persistence/FilePersistenceThread.java
===================================================================
--- /java/server/trunk/src/org/red5/server/persistence/FilePersistenceThread.java (revision 2439)
+++ /java/server/trunk/src/org/red5/server/persistence/FilePersistenceThread.java (revision 2441)
@@ -20,12 +20,9 @@
  */
 
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
-import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.locks.ReentrantLock;
 
 import org.red5.server.api.persistence.IPersistable;
@@ -55,12 +52,7 @@
 
 	/**
-	 * Modified objects that need to be stored.
-	 */
-	private Map<IPersistable, FilePersistence> modifiedObjects = new HashMap<IPersistable, FilePersistence>();
-
-	/**
-	 * Modified objects for each store.
-	 */
-	private Map<FilePersistence, Set<IPersistable>> objectStores = new HashMap<FilePersistence, Set<IPersistable>>();
+	 * Modified objects.
+	 */
+	private Map<UpdateEntry, FilePersistence> objects = new ConcurrentHashMap<UpdateEntry, FilePersistence>();
 
 	/**
@@ -75,10 +67,4 @@
 	private final ScheduledExecutorService scheduler = Executors
 			.newSingleThreadScheduledExecutor();
-
-	/**
-	 * Extra functionality above and beyond normal sync is available via this type.
-	 * http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/ReentrantLock.html
-	 */
-	private final ReentrantLock lock = new ReentrantLock();
 
 	/**
@@ -112,29 +98,9 @@
 	 */
 	protected void modified(IPersistable object, FilePersistence store) {
-		FilePersistence previous = modifiedObjects.put(object, store);
-		Set<IPersistable> objects = objectStores.get(store);
-		if (objects == null) {
-			lock.lock(); // block until condition holds
-			try {
-				// Probably created by another thread in the meantime?
-				objects = objectStores.get(store);
-				if (objects == null) {
-					objects = new HashSet<IPersistable>();
-					objectStores.put(store, objects);
-				}
-			} finally {
-				lock.unlock();
-			}
-		}
-		objects.add(object);
-
+		FilePersistence previous = objects.put(new UpdateEntry(object, store), store);
 		if (previous != null && !previous.equals(store)) {
 			log.warn("Object {} was also modified in {}, saving instantly",
 					new Object[] { object, previous });
 			previous.saveObject(object);
-			objects = objectStores.get(previous);
-			if (objects != null) {
-				objects.remove(previous);
-			}
 		}
 	}
@@ -146,23 +112,17 @@
 	 */
 	protected void notifyClose(FilePersistence store) {
-		// Get snapshot of currently modified objects.
-		Set<IPersistable> objects = objectStores.remove(store);
-		if (objects != null) {
-			for (IPersistable object : objects) {
-				modifiedObjects.remove(object);
-			}
-		}
-
-		if (objects == null || objects.isEmpty()) {
-			return;
-		}
-
-		// Store pending objects
-		for (IPersistable object : objects) {
+		// Store pending objects for this store
+		for (UpdateEntry entry : objects.keySet()) {
+			if (!store.equals(entry.store)) {
+				// Object is from different store
+				continue;
+			}
+			
 			try {
-				store.saveObject(object);
+				objects.remove(entry);
+				store.saveObject(entry.object);
 			} catch (Throwable e) {
 				log.error("Error while saving {} in {}. {}", new Object[] {
-						object, store, e });
+						entry.object, store, e });
 			}
 		}
@@ -173,18 +133,16 @@
 	 */
 	public void run() {
-		if (!modifiedObjects.isEmpty()) {
-			// Get snapshot of currently modified objects.
-			Map<IPersistable, FilePersistence> objects = new HashMap<IPersistable, FilePersistence>(
-					modifiedObjects);
-			modifiedObjects.clear();
-			objectStores.clear();
-			for (Map.Entry<IPersistable, FilePersistence> entry : objects
-					.entrySet()) {
-				try {
-					entry.getValue().saveObject(entry.getKey());
-				} catch (Throwable e) {
-					log.error("Error while saving {} in {}. {}", new Object[] {
-							entry.getKey(), entry.getValue(), e });
-				}
+		if (objects.isEmpty()) {
+			// No objects to store
+			return;
+		}
+		
+		for (UpdateEntry entry : objects.keySet()) {
+			try {
+				objects.remove(entry);
+				entry.store.saveObject(entry.object);
+			} catch (Throwable e) {
+				log.error("Error while saving {} in {}. {}", new Object[] {
+						entry.object, entry.store, e });
 			}
 		}
@@ -198,3 +156,51 @@
 	}
 
+	/**
+	 * Informations about one entry to object.
+	 */
+	private class UpdateEntry {
+		
+		/** Object to store. */
+		IPersistable object;
+		/** Store the object should be serialized to. */
+		FilePersistence store;
+		
+		/**
+		 * Create new update entry.
+		 * 
+		 * @param object	object to serialize
+		 * @param store		store the object should be serialized in
+		 */
+		UpdateEntry(IPersistable object, FilePersistence store) {
+			this.object = object;
+			this.store = store;
+		}
+		
+		/**
+		 * Compare with another entry.
+		 * 
+		 * @param other		entry to compare to
+		 * @return <code>true</code> if entries match, otherwise <code>false</code>
+		 */
+		@Override
+		public boolean equals(Object other) {
+			if (!(other instanceof UpdateEntry)) {
+				return false;
+			}
+			
+			return (object.equals(((UpdateEntry) other).object) && store.equals(((UpdateEntry) other).store));
+		}
+		
+		/**
+		 * Return hash value for entry.
+		 * 
+		 * @return the hash value
+		 */
+		@Override
+		public int hashCode() {
+			return object.hashCode() + store.hashCode();
+		}
+		
+	}
+	
 }


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