Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: osmwp/MeMoPlayer
...
head fork: yalp/MeMoPlayer
Checking mergeability… Don't worry, you can still create the pull request.
  • 2 commits
  • 2 files changed
  • 0 commit comments
  • 1 contributor
Commits on Jul 02, 2012
Marc Capdevielle Fix RMS3 flush implementation
Previous implementation used a complex way to flush and was buggy...
This implementation is much more simple !

 * Replaced Thread.interrupt() by m_threadLock.notify()
   This will prevent interrupting IO operations !
 * Flushing the records is just emptying the queue.
e30bdc4
Marc Capdevielle Fix RMS3 implementation (pack and thread wakeup)
 * only start pack when 3/4 of the entries were deleted
 * pack is now just adding all entries to add again after a ERASE_ALL operation
 * simplified background thread wakeup : start flush every FLUSH_DELAY
 * close the master CacheManager at last
d9de468
View
9 java/src/memoplayer/CacheManager.java
@@ -154,10 +154,6 @@ public static void setStore (String s) {
// Clean up on application exit
public static void clean () {
- if (s_masterMgr != null) {
- s_masterMgr.close ();
- s_masterMgr = null;
- }
// If closing midlet while still on another Manager
if (s_mgr != s_masterMgr) {
s_mgr.close ();
@@ -167,7 +163,6 @@ public static void clean () {
// When using namespace also clean other Managers
Namespace.clean ();
//#endif
-
//#ifdef MM.CacheUseRms2
// RMSCacheManager2 ignores close() calls, only the closeAll() call
// will close all RecordStores on application exit !
@@ -182,6 +177,10 @@ public static void clean () {
RMSCacheManager3.closeAll ();
}
//#endif
+ if (s_masterMgr != null) {
+ s_masterMgr.close ();
+ s_masterMgr = null;
+ }
}
// instantiate a manager, according to the jad preperty
View
207 java/src/memoplayer/RMSCacheManager3.java
@@ -39,7 +39,7 @@
private final static int FLUSH_DELAY = 3000;
// Delay to wait before freeing the in memory cache.
- private final static int INACTIVITY_DELAY = 7000;
+ private final static int INACTIVITY_DELAY = 10000;
private final static String ERASE_ALL = "__ERASE_ALL_RECORDS";
@@ -117,15 +117,14 @@ public static synchronized void closeAll () {
private RecordStore m_recordStore;
private int m_availableSize;
- private boolean m_pack;
private RMSCacheManager3 m_next;
private ObjLink queue;
private boolean m_quit;
private Thread m_thread; // worker thread in charge of async operations
+ private Object m_threadLock = new Object();
private Object m_flushLock = new Object();
- private boolean m_immediateFlush;
private RMSCacheManager3 (String name, RMSCacheManager3 next) {
super (name);
@@ -168,9 +167,15 @@ private boolean loadEntries () {
recordId += 2;
}
sortEntries();
- if (deleted > m_nbEntries / 4) {
+ if (deleted > m_nbEntries * 3 / 4) {
Logger.println("RMS3: Packing needed for "+m_storeName);
- m_pack = true;
+ // Add all entries to queue after ERASE_ALL operation
+ addAsyncOperation(ERASE_ALL, null);
+ for (int i = 0; i<m_nbEntries; i++) {
+ final Entry e = m_entries[i];
+ e.index = 0; // force add operation
+ addAsyncOperation(e.name, e);
+ }
}
m_tableLoaded = true;
closeStore();
@@ -231,7 +236,7 @@ private int addEntry (String name, int index, byte[] data, boolean sort) {
e.index = index;
e.data = data;
if (m_nbEntries >= m_entries.length) { // expand the array
- Entry [] tmp = new Entry [m_entries.length+INITIAL_CAPACITY];
+ Entry [] tmp = new Entry [m_entries.length*2];
System.arraycopy (m_entries, 0, tmp, 0, m_nbEntries);
m_entries = tmp;
}
@@ -289,8 +294,8 @@ private void finalClose() {
java.lang.Thread t = m_thread;
if (!m_quit && t != null && t.isAlive()) {
m_quit = true;
- synchronized (t) {
- t.interrupt();
+ synchronized (m_threadLock) {
+ m_threadLock.notify();
}
try {
t.join();
@@ -310,7 +315,6 @@ public synchronized void erase () {
}
m_nbEntries = 0;
}
- m_pack = false; // no need to pack after erase
addAsyncOperation(ERASE_ALL, null);
}
@@ -368,24 +372,6 @@ public synchronized int getSizeAvailable () {
return m_availableSize;
}
- /** This call will block until all pending operations are done */
- public void flushRecords() {
- //Logger.println("RMS3: flushRecords for "+m_storeName);
- Thread thread = m_thread;
- if (queue != null && thread != null) {
- try {
- synchronized (m_flushLock) {
- m_immediateFlush = true;
- synchronized (thread) {
- thread.interrupt();
- }
- m_flushLock.wait();
- }
- } catch (InterruptedException e) {
- }
- }
- }
-
private synchronized void addAsyncOperation (String key, Entry e) {
if (queue == null) {
queue = ObjLink.create (key, e, null);
@@ -405,131 +391,90 @@ private synchronized void addAsyncOperation (String key, Entry e) {
wakeThread(); // ensure thread is awake to execute delayed operations
}
- private void wakeThread() {
- synchronized (this) {
- if (m_thread == null || !m_thread.isAlive()) {
- m_thread = new java.lang.Thread(this);
- m_thread.start();
- return;
- }
- }
- synchronized (m_thread) {
- m_thread.interrupt();
+ private synchronized void wakeThread() {
+ if (m_thread == null || !m_thread.isAlive()) {
+ m_thread = new java.lang.Thread(this);
+ m_thread.start();
}
}
- private void executeAsyncOperations() {
- ObjLink pendingOp;
- synchronized(this) {
- pendingOp = queue; // Get pending operations
- queue = null; // and empty the queue
- }
- while (pendingOp != null) {
- if (pendingOp.m_object.equals(ERASE_ALL)) {
- closeStore();
- try {
- RecordStore.deleteRecordStore(m_storeName);
- } catch (RecordStoreException e) {
- Logger.println("RMS3: Erase error: "+e+" for "+m_storeName);
- }
- } else if (openStore()) {
- final Entry e = (Entry)pendingOp.m_param;
- byte[] data;
- int index;
- synchronized (this) {
- data = e.data;
- index = e.index;
- }
- try {
- if (data == null) { // delete
- if (index > 0) { // index could be 0 if data is deleted just after creation
- //Logger.println("RMS3: Delete "+e.name+" at "+index);
- m_recordStore.deleteRecord(index);
- m_recordStore.deleteRecord(index+1);
+ /** This call will block until all pending operations are done */
+ public void flushRecords() {
+ synchronized (m_flushLock) {
+ //Logger.println("RMS3: flushRecords for "+m_storeName);
+ ObjLink pendingOp;
+ synchronized(this) {
+ pendingOp = queue; // Get pending operations
+ queue = null; // and empty the queue
+ }
+ while (pendingOp != null) {
+ if (pendingOp.m_object.equals(ERASE_ALL)) {
+ closeStore();
+ try {
+ RecordStore.deleteRecordStore(m_storeName);
+ } catch (RecordStoreException e) {
+ Logger.println("RMS3: Erase error: "+e+" for "+m_storeName);
+ }
+ } else if (openStore()) {
+ final Entry e = (Entry)pendingOp.m_param;
+ byte[] data;
+ int index;
+ synchronized (this) {
+ data = e.data;
+ index = e.index;
+ }
+ try {
+ if (data == null) { // delete
+ if (index > 0) { // index could be 0 if data is deleted just after creation
+ //Logger.println("RMS3: Delete "+e.name+" at "+index);
+ m_recordStore.deleteRecord(index);
+ m_recordStore.deleteRecord(index+1);
+ }
+ } else if (index > 0) { // set
+ //Logger.println("RMS3: Write "+e.name+" at "+index);
+ m_recordStore.setRecord(index+1, data, 0, data.length);
+ } else { // add
+ //Logger.println("RMS3: Add "+e.name);
+ byte[] stringBuff = e.name.getBytes();
+ index = m_recordStore.addRecord(stringBuff, 0, stringBuff.length);
+ m_recordStore.addRecord(data, 0, data.length);
+ synchronized (this) {
+ e.index = index;
+ }
}
- } else if (index > 0) { // set
- //Logger.println("RMS3: Write "+e.name+" at "+index);
- m_recordStore.setRecord(index+1, data, 0, data.length);
- } else { // add
- //Logger.println("RMS3: Add "+e.name);
- byte[] stringBuff = e.name.getBytes();
- index = m_recordStore.addRecord(stringBuff, 0, stringBuff.length);
- m_recordStore.addRecord(data, 0, data.length);
- e.index = index;
+ } catch (RecordStoreException ex) {
+ Logger.println("RMS3: write error: "+ex+" for "+e.name);
}
- } catch (RecordStoreException ex) {
- Logger.println("RMS3: write error: "+ex+" for "+e.name);
- }
- }
- pendingOp = ObjLink.release(pendingOp);
- }
- closeStore();
- }
-
- private synchronized void pack () {
- try {
- RecordStore.deleteRecordStore(m_storeName);
- } catch (RecordStoreException e) {
- Logger.println("RMS3: Pack erase error: "+e+" for "+m_storeName);
- }
- if (openStore()) {
- for (int i=0; i<m_nbEntries; i++) {
- Entry e = m_entries[i];
- byte[] name = e.name.getBytes();
- byte[] data = e.data;
- if (data == null) continue;
- try {
- m_recordStore.addRecord(name, 0, name.length);
- m_recordStore.addRecord(data, 0, data.length);
- } catch (RecordStoreException ex) {
- Logger.println("RMS3: pack error: "+ex+" for "+e.name);
}
+ pendingOp = ObjLink.release(pendingOp);
}
closeStore();
}
}
- private synchronized void unloadEntries() {
- m_entries = null;
- m_tableLoaded = false;
- }
-
// Main loop for the background thread
public void run() {
try {
while (!m_quit) {
- try {
- Thread.sleep(FLUSH_DELAY);
- //long ts = System.currentTimeMillis();
- executeAsyncOperations();
- //Logger.println("RMS3: Flush in "+(System.currentTimeMillis()-ts)+"ms for "+m_storeName);
- if (queue == null) {
- Thread.sleep(INACTIVITY_DELAY);
- if (m_pack) {
- //ts = System.currentTimeMillis();
- pack();
- //Logger.println("RMS3: Packed in "+(System.currentTimeMillis()-ts)+"ms for "+m_storeName);
- }
- // Never unload entries for Master manager
- if (CacheManager.getMasterManager() != this &&
- System.currentTimeMillis() - m_lastAccess > 10000) {
- unloadEntries();
+ synchronized (m_threadLock) {
+ m_threadLock.wait(FLUSH_DELAY);
+ }
+ //long ts = System.currentTimeMillis();
+ flushRecords();
+ //Logger.println("RMS3: Flush in "+(System.currentTimeMillis()-ts)+"ms for "+m_storeName);
+ // Never unload entries for Master manager
+ if (s_masterMgr != this) {
+ synchronized (this) {
+ if (queue == null && System.currentTimeMillis() - m_lastAccess > INACTIVITY_DELAY) {
+ m_entries = null;
+ m_tableLoaded = false;
//Logger.println("RMS3: Free memory cache for "+m_storeName);
break; // exit loop
}
}
- } catch (InterruptedException e) {
- // When interrupted for flush handle it immediately
- synchronized (m_flushLock) {
- if (m_immediateFlush) {
- executeAsyncOperations();
- m_immediateFlush = false;
- m_flushLock.notifyAll();
- }
- }
}
}
- executeAsyncOperations();
+ flushRecords();
//Logger.println ("RMS3: Thread ended for "+m_storeName);
} catch (Throwable t) {
Logger.println ("RMS3: Thread died: "+t+" for "+m_storeName);

No commit comments for this range

Something went wrong with that request. Please try again.