[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