Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #10 from ovidiuiliescu/pull-request-content

Improved content caching mechanism. Bugfixes related to it.
  • Loading branch information...
commit 9258ea66f3cc23a07700938bd8bf42fd2c4a31ff 2 parents f77f34e + b979331
@robert-virkus robert-virkus authored
View
3  enough-polish-j2me/source/src/de/enough/polish/content/ContentDescriptor.java
@@ -16,6 +16,9 @@
*
*/
public class ContentDescriptor implements Externalizable {
+
+ public static int PRIORITY_CRITICAL = Integer.MAX_VALUE;
+
/**
* the default version
*/
View
8 enough-polish-j2me/source/src/de/enough/polish/content/filter/impl/HttpContentFilter.java
@@ -3,8 +3,16 @@
import de.enough.polish.content.ContentDescriptor;
import de.enough.polish.content.filter.ContentFilter;
+/**
+ * Filter for HTTP content
+ * @author Ovidiu Iliescu
+ *
+ */
public class HttpContentFilter implements ContentFilter {
+ /* (non-Javadoc)
+ * @see de.enough.polish.content.filter.ContentFilter#filter(de.enough.polish.content.ContentDescriptor)
+ */
public boolean filter(ContentDescriptor descriptor) {
return descriptor.getUrl().startsWith("http://");
}
View
8 ...gh-polish-j2me/source/src/de/enough/polish/content/filter/impl/ResourceContentFilter.java
@@ -3,8 +3,16 @@
import de.enough.polish.content.ContentDescriptor;
import de.enough.polish.content.filter.ContentFilter;
+/**
+ * Filter for Resource content
+ * @author Ovidiu Iliescu
+ *
+ */
public class ResourceContentFilter implements ContentFilter {
+ /* (non-Javadoc)
+ * @see de.enough.polish.content.filter.ContentFilter#filter(de.enough.polish.content.ContentDescriptor)
+ */
public boolean filter(ContentDescriptor descriptor) {
return descriptor.getUrl().startsWith("resources://");
}
View
133 enough-polish-j2me/source/src/de/enough/polish/content/source/ContentSource.java
@@ -112,7 +112,7 @@ public void attachSource(ContentSource source) {
this.sources.add(source);
//#debug debug
- info("attached source : " + source);
+ System.out.println(this.id + " : " + "attached source : " + source);
}
/**
@@ -139,42 +139,64 @@ public void detachSource(ContentSource source) {
this.sources.remove(source);
//#debug debug
- info("detached source : " + source);
+ System.out.println(this.id + " : " + "detached source : " + source);
}
+ /**
+ * Sets the content filter
+ * @param filter the filter to set
+ */
public void setContentFilter(ContentFilter filter) {
this.filter = filter;
//#debug debug
- info("set filter : " + filter);
+ System.out.println(this.id + " : " + "set filter : " + filter);
}
+ /**
+ * Returns the content filter
+ * @return the filter
+ */
public ContentFilter getFilter() {
return this.filter;
}
+ /**
+ * Adds a content transformation
+ * @param transformer the transformation
+ */
public void addContentTransform(ContentTransform transformer) {
String id = transformer.getTransformId();
if (!id.equals(ContentDescriptor.TRANSFORM_NONE)
&& this.transformers.containsKey(id)) {
//#debug info
- info("overwriting transformer with id \"" + id + "\"");
+ System.out.println(this.id + " : " + "overwriting transformer with id \"" + id + "\"");
}
this.transformers.put(id, transformer);
//#debug debug
- info("added transform : " + transformer);
+ System.out.println(this.id + " : " + "added transform : " + transformer);
}
+ /**
+ * Removes a content transformation
+ * @param transformer the transformation
+ */
public void removeContentTransform(ContentTransform transformer) {
String id = transformer.getTransformId();
this.transformers.remove(id);
//#debug debug
- info("removed transform : " + transformers);
+ System.out.println(this.id + " : " + "removed transform : " + transformers);
}
+ /**
+ * Loads content from all underlying sources
+ * @param descriptor the content descriptor to load
+ * @return the content Object
+ * @throws ContentException
+ */
public Object loadContent(ContentDescriptor descriptor)
throws ContentException {
Object data = loadContentData(descriptor);
@@ -188,25 +210,25 @@ public Object loadContent(ContentDescriptor descriptor)
ContentFilter filter = source.getFilter();
if (filter != null && !filter.filter(descriptor)) {
//#debug debug
- info("filtered source : " + source);
+ System.out.println(this.id + " : " + "filtered source : " + source);
continue;
}
//#debug debug
- info("load content : " + descriptor + " : with source : "
+ System.out.println(this.id + " : " + "load content : " + descriptor + " : with source : "
+ source);
data = source.loadContent(descriptor);
if (data != null) {
data = transformContent(descriptor, data);
//#debug debug
- info("transformed content : " + data);
+ System.out.println(this.id + " : " + "transformed content : " + data);
if(descriptor.getCachingPolicy() == ContentDescriptor.CACHING_READ_WRITE) {
storeContent(descriptor, data);
} else {
//#debug debug
- info("no storage due to caching policy");
+ System.out.println(this.id + " : " + "no storage due to caching policy");
}
return data;
}
@@ -225,6 +247,12 @@ public Object loadContent(ContentDescriptor descriptor)
return data;
}
+ /**
+ * Transforms content with a transformation
+ * @param descriptor the content descriptor containing the transformation
+ * @param data the data to transform
+ * @return
+ */
protected Object transformContent(ContentDescriptor descriptor, Object data) {
if (this.transformers.size() > 0
&& descriptor.getTransformID() != ContentDescriptor.TRANSFORM_NONE
@@ -234,12 +262,12 @@ protected Object transformContent(ContentDescriptor descriptor, Object data) {
if (transformer != null) {
try {
//#debug debug
- info("using transform : " + transformer
+ System.out.println(this.id + " : " + "using transform : " + transformer
+ " : for descriptor : " + descriptor);
data = transformer.transformContent(data);
} catch (IOException e) {
//#debug error
- System.out.println("error transforming " + descriptor + ":"
+ System.out.println(this.id + " : " + "error transforming " + descriptor + ":"
+ e);
}
@@ -250,19 +278,25 @@ protected Object transformContent(ContentDescriptor descriptor, Object data) {
return data;
}
+ /**
+ * Loads content data from this content source or from storage
+ * @param descriptor the descriptor to load the content data for
+ * @return the content data
+ * @throws ContentException
+ */
protected Object loadContentData(ContentDescriptor descriptor)
throws ContentException {
// if this source has a storage ...
if (hasStorage()) {
//#debug debug
- info("has storage");
+ System.out.println(this.id + " : " + "has storage");
// prepare the storage if it isn't
if (!this.storageIndex.isPrepared()) {
this.storageIndex.prepare();
//#debug debug
- info("storage index prepared");
+ System.out.println(this.id + " : " + "storage index prepared");
}
// get the StorageReference to a potentially stored content
@@ -272,7 +306,7 @@ protected Object loadContentData(ContentDescriptor descriptor)
// if the content is stored ...
if (reference != null) {
//#debug debug
- info("found reference : " + reference);
+ System.out.println(this.id + " : " + "found reference : " + reference);
// update its activity
reference.updateActivity();
@@ -324,12 +358,12 @@ protected Object loadContent(ContentDescriptor descriptor,
try {
if (reference != null) {
//#debug debug
- info("loading content from storage : " + reference);
+ System.out.println(this.id + " : " + "loading content from storage : " + reference);
return load(reference);
} else {
//#debug debug
- info("loading content from source : " + descriptor);
+ System.out.println(this.id + " : " + "loading content from source : " + descriptor);
return load(descriptor);
}
} catch (IOException e) {
@@ -345,7 +379,7 @@ protected Object loadContent(ContentDescriptor descriptor,
* @param data the data that needs to be stored
* @return an Object [], the first element is an Integer object containing the stored object's data size, the second element is a reference to the stored object
*/
- protected abstract Object[] storeContentAndGetDataSize(ContentDescriptor descriptor, Object data) throws IOException ;
+ protected abstract Object[] storeContentAndGetDataSize(ContentDescriptor descriptor, Object data) throws IOException, ContentException ;
protected void storeContent(ContentDescriptor descriptor, Object data)
throws ContentException {
@@ -354,7 +388,7 @@ protected void storeContent(ContentDescriptor descriptor, Object data)
// if this ContentSource has a storage ...
if (hasStorage()) {
//#debug debug
- info("storing content : " + data + " : for :" + descriptor);
+ System.out.println(this.id + " : " + "storing content : " + data + " : for :" + descriptor);
int size;
Object reference;
@@ -368,18 +402,23 @@ protected void storeContent(ContentDescriptor descriptor, Object data)
size = getSize(descriptor, data);
//#debug debug
- info("data size for : " + data + " : " + size);
+ System.out.println(this.id + " : " + "data size for : " + data + " : " + size);
// store the content
reference = store(descriptor, data);
}
- // add the reference to the StorageIndex
- this.storageIndex.addReference(new StorageReference(descriptor,
- size, reference));
+ // add the reference to the StorageIndex, if storage was successful
+ if ( reference != null ) {
+ this.storageIndex.addReference(new StorageReference(descriptor,
+ size, reference));
- //#debug debug
- info("content stored with reference : " + reference);
+ //#debug debug
+ System.out.println(this.id + " : " + "content stored with reference : " + reference);
+ } else {
+ //#debug debug
+ System.out.println(this.id + " : " + "content deliberately not stored");
+ }
}
} catch (IOException e) {
String message = "error storing content : " + e;
@@ -402,7 +441,7 @@ protected void destroyContent(ContentDescriptor descriptor)
// if this ContentSource has a storage ...
if (hasStorage()) {
//#debug debug
- info("destroying content : " + descriptor);
+ System.out.println(this.id + " : " + "destroying content : " + descriptor);
// get the reference to the content
StorageReference reference = this.storageIndex
@@ -422,18 +461,28 @@ protected void destroyContent(ContentDescriptor descriptor)
}
//#debug debug
- info("content destroyed : " + descriptor);
+ System.out.println(this.id + " : " + "content destroyed : " + descriptor);
}
}
-
+
/**
* If a clean is needed on the storage, the clean order is applied to the
* StorageIndex and contents are deleted until the cache size is below the
* thresholds
*/
public void clean() throws ContentException {
+ clean(0);
+ }
+
+ /**
+ * If a clean is needed on the storage in order to store an additional extraBytes number of bytes, the clean order is applied to the
+ * StorageIndex and contents are deleted until the cache size is below the
+ * thresholds
+ * @param extraBytes
+ */
+ public void clean(int extraBytes) throws ContentException {
if (hasStorage()) {
- if (!this.storageIndex.isCleanNeeded()) {
+ if (!this.storageIndex.isCleanNeeded(extraBytes)) {
return;
}
@@ -442,20 +491,29 @@ public void clean() throws ContentException {
}
//#debug debug
- info("clean : " + this.storageIndex);
+ System.out.println(this.id + " : " + "clean : " + this.storageIndex);
// apply the clean order
this.storageIndex.applyOrder();
+ boolean canDeleteFurther = true;
do {
+ // Assume that you cannot delete anything else
+ canDeleteFurther = false;
+
// get the index of the first disposable content
int index = this.storageIndex.getDisposableIndex();
// get the reference
StorageReference reference = this.storageIndex
.getReference(index);
- // destroy the content
- destroyContent(reference);
- } while ((this.storageIndex.isCleanNeeded()));
+ // destroy the content, if not critical
+ if ( reference.getPriority() != ContentDescriptor.PRIORITY_CRITICAL ) {
+ destroyContent(reference);
+
+ // Maybe we can delete other content too
+ canDeleteFurther = true;
+ }
+ } while ((this.storageIndex.isCleanNeeded(extraBytes)) && canDeleteFurther);
}
}
@@ -594,13 +652,4 @@ public String toString() {
"sources", this.sources).set("transformers", this.transformers)
.set("filter", this.filter).toString();
}
-
- /**
- * Prints an info
- *
- * @param info
- */
- public void info(String info) {
- System.out.println(this.id + " : " + info);
- }
}
View
10 enough-polish-j2me/source/src/de/enough/polish/content/source/impl/HttpContentSource.java
@@ -16,8 +16,15 @@
*/
public class HttpContentSource extends ContentSource{
+ /**
+ * The HTTP prefix
+ */
public final static String PREFIX = "http://";
+ /**
+ * Creates a new HttpContentSource
+ * @param id
+ */
public HttpContentSource(String id) {
super(id);
}
@@ -62,6 +69,9 @@ protected Object store(ContentDescriptor descriptor, Object data)
return null;
}
+ /* (non-Javadoc)
+ * @see de.enough.polish.content.source.ContentSource#storeContentAndGetDataSize(de.enough.polish.content.ContentDescriptor, java.lang.Object)
+ */
protected Object[] storeContentAndGetDataSize(ContentDescriptor descriptor,
Object data) throws IOException {
// Do nothing, this is a source
View
15 ...polish-j2me/source/src/de/enough/polish/content/source/impl/PersistentContentStorage.java
@@ -17,15 +17,27 @@
import de.enough.polish.io.Serializer;
/**
+ * Defines a content storage using the Persistent Record Store mechanism on Blackberry
* @author Andre Schmidt
*
*/
public class PersistentContentStorage extends ContentSource {
+ /**
+ * The record store ID for the persistent storage
+ */
static final String STORAGE = "RMSContentStorage";
+ /**
+ * The record store instance
+ */
PersistentRecordStore store;
+ /**
+ * Creates a new PersistentContentStorage instance
+ * @param id the ID for the storage
+ * @param index the storageindex to use
+ */
public PersistentContentStorage(String id, StorageIndex index) {
super(id, index);
@@ -38,6 +50,9 @@ public PersistentContentStorage(String id, StorageIndex index) {
}
}
+ /* (non-Javadoc)
+ * @see de.enough.polish.content.source.ContentSource#shutdown()
+ */
public synchronized void shutdown() {
// close the record store
try
View
26 ...h-polish-j2me/source/src/de/enough/polish/content/source/impl/PersistentStorageIndex.java
@@ -15,13 +15,36 @@
import de.enough.polish.io.Serializer;
import de.enough.polish.util.ArrayList;
+/**
+ * Defines a storage index using the Persistent Record Storage on Blackberry
+ * @author Ovidiu Iliescu
+ *
+ */
public class PersistentStorageIndex extends StorageIndex {
+ /**
+ * The record store index
+ */
static final String STORAGE = "RMSStorageIndex";
+
+ /**
+ * Indicates that the actaul record index is not known
+ */
static final int RECORD_UNKNOWN = Integer.MIN_VALUE;
+ /**
+ * The actual record store to use
+ */
PersistentRecordStore store;
+
+ /**
+ * The record ID
+ */
int recordId = RECORD_UNKNOWN;
+ /**
+ * Creates a new index, with the specified maximum size
+ * @param maxCacheSize the size of the index
+ */
public PersistentStorageIndex(int maxCacheSize) {
super(maxCacheSize);
@@ -109,6 +132,9 @@ protected void store(ArrayList index) {
}
}
+ /* (non-Javadoc)
+ * @see de.enough.polish.content.storage.StorageIndex#shutdown()
+ */
public void shutdown() {
super.shutdown();
View
10 ...gh-polish-j2me/source/src/de/enough/polish/content/source/impl/ResourceContentSource.java
@@ -16,8 +16,15 @@
*/
public class ResourceContentSource extends ContentSource{
+ /**
+ * The prefix for this kind of source
+ */
public final static String PREFIX = "resource://";
+ /**
+ * Creates a new resource content source
+ * @param id the unique ID of this source
+ */
public ResourceContentSource(String id) {
super(id);
}
@@ -63,6 +70,9 @@ protected Object store(ContentDescriptor descriptor, Object data)
return null;
}
+ /* (non-Javadoc)
+ * @see de.enough.polish.content.source.ContentSource#storeContentAndGetDataSize(de.enough.polish.content.ContentDescriptor, java.lang.Object)
+ */
protected Object[] storeContentAndGetDataSize(ContentDescriptor descriptor,
Object data) throws IOException {
// Do nothing, this is a source
View
127 enough-polish-j2me/source/src/de/enough/polish/content/source/impl/RmsContentStorage.java
@@ -8,35 +8,94 @@
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
+import javax.microedition.rms.RecordStoreNotOpenException;
import de.enough.polish.content.ContentDescriptor;
+import de.enough.polish.content.ContentException;
import de.enough.polish.content.source.ContentSource;
import de.enough.polish.content.storage.StorageIndex;
import de.enough.polish.content.storage.StorageReference;
import de.enough.polish.io.Serializer;
/**
+ * Defines a content storage using the RMS
* @author Andre Schmidt
*
*/
public class RmsContentStorage extends ContentSource {
- static final String STORAGE = "RMSContentStorage";
+ /**
+ * The default RMS store name
+ */
+ public static final String STORAGE = "RMSContentStorage";
+ /**
+ * The RecordStore instance to use
+ */
protected RecordStore store;
-
+
+ /**
+ * Returns the maximum total size of the store
+ * @return the maximum total size of the store
+ */
+ public static int getMaximumTotalSize() {
+ int maxSize = 0;
+ int currentSize = 0;
+ RecordStore rs = null;
+ try {
+ rs = RecordStore.openRecordStore(STORAGE, true);
+ currentSize = rs.getSize();
+ maxSize = currentSize + rs.getSizeAvailable();
+ } catch (Exception ex) {
+ // Do nothing
+ } finally {
+ try {
+ // Close record store
+ if (rs != null) {
+ rs.closeRecordStore();
+ }
+
+ // If the store is empty, delete it as well
+ if ( currentSize == 0 ) {
+ RecordStore.deleteRecordStore(STORAGE);
+ }
+ } catch (Exception ex) {
+ // Do nothing
+ }
+ }
+ return maxSize;
+ }
+
+ /**
+ * Creates a new RmsContentStor
+ * @param id
+ * @param index
+ */
public RmsContentStorage(String id, StorageIndex index) {
+ this(id, STORAGE, index);
+ }
+
+ /**
+ * Creates a new RmsContentStorage instance
+ * @param id the unique ID of this instance
+ * @param recordStoreName the name of the record store to use
+ * @param index the index to use with this content storage
+ */
+ public RmsContentStorage(String id, String recordStoreName, StorageIndex index) {
super(id, index);
// open the record store
try {
- store = RecordStore.openRecordStore(STORAGE, true);
+ store = RecordStore.openRecordStore(recordStoreName, true);
} catch (RecordStoreException e) {
//#debug error
System.out.println("unable to open record store " + e);
}
}
+ /* (non-Javadoc)
+ * @see de.enough.polish.content.source.ContentSource#shutdown()
+ */
public synchronized void shutdown() {
// close the record store
try
@@ -51,12 +110,15 @@ public synchronized void shutdown() {
}
+ /* (non-Javadoc)
+ * @see de.enough.polish.content.source.ContentSource#destroy(de.enough.polish.content.storage.StorageReference)
+ */
protected synchronized void destroy(final StorageReference reference) throws IOException {
try {
// get the record id
int recordId = ((Integer)reference.getReference()).intValue();
- // add the record
+ // delete the record
store.deleteRecord(recordId);
} catch (RecordStoreException e) {
@@ -67,35 +129,62 @@ protected synchronized void destroy(final StorageReference reference) throws IO
/* (non-Javadoc)
* @see de.enough.polish.content.source.ContentSource#storeContentAndGetDataSize(de.enough.polish.content.ContentDescriptor, java.lang.Object)
*/
- protected Object[] storeContentAndGetDataSize(ContentDescriptor descriptor, Object data) throws IOException {
+ protected Object[] storeContentAndGetDataSize(ContentDescriptor descriptor, Object data) throws IOException, ContentException {
+
+ // serialize the data and convert it to a byte array
+ ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+ Serializer.serialize(data, new DataOutputStream(byteStream));
+
+ // get the bytes
+ byte[] bytes = byteStream.toByteArray();
+
+ // If the data we are trying to store is bigger than the cache itself, don't even bother
+ if ( bytes.length > getStorageIndex().getAvailableCacheSize() ) {
+ return new Object[] { new Integer(bytes.length), null };
+ }
+
+ // Try to do a clean first, in case it is needed.
+ clean(bytes.length);
+
+ // add the record, if possible
+ Integer recordId = null;
try {
- // serialize the data and convert it to a byte array
- ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
- Serializer.serialize(data, new DataOutputStream(byteStream));
-
- // get the bytes
- byte[] bytes = byteStream.toByteArray();
-
- // add the record
- int recordId = store.addRecord(bytes, 0, bytes.length);
-
- return new Object[] { new Integer(bytes.length), new Integer(recordId)};
- } catch (RecordStoreException e) {
- throw new IOException("unable to store data " + e);
- }
+ if ( !this.getStorageIndex().isCleanNeeded(bytes.length) ) {
+ recordId = new Integer(store.addRecord(bytes, 0, bytes.length));
+ //#debug debug
+ System.out.println("added record for " + descriptor.getUrl());
+ } else {
+ //#debug debug
+ System.out.println("not enough space to add record for " + descriptor.getUrl());
+ }
+ } catch (Exception e) {
+ //#debug debug
+ System.out.println("exception while storing " + descriptor.getUrl() + " : " + e.getClass().getName() + " " + e.getMessage());
+ }
+
+ return new Object[] { new Integer(bytes.length), recordId};
}
+ /* (non-Javadoc)
+ * @see de.enough.polish.content.source.ContentSource#store(de.enough.polish.content.ContentDescriptor, java.lang.Object)
+ */
protected synchronized Object store(ContentDescriptor descriptor, Object data) throws IOException {
// Do nothing here as the #storeContentAndGetDataSize method will be used. instead
return null;
}
+ /* (non-Javadoc)
+ * @see de.enough.polish.content.source.ContentSource#load(de.enough.polish.content.ContentDescriptor)
+ */
protected synchronized Object load(ContentDescriptor descriptor)
throws IOException {
// do nothing here as it is a storage
return null;
}
+ /* (non-Javadoc)
+ * @see de.enough.polish.content.source.ContentSource#load(de.enough.polish.content.storage.StorageReference)
+ */
protected synchronized Object load(StorageReference reference) throws IOException {
try {
// get the record id
View
102 enough-polish-j2me/source/src/de/enough/polish/content/source/impl/RmsStorageIndex.java
@@ -19,32 +19,99 @@
import de.enough.polish.io.Serializer;
import de.enough.polish.util.ArrayList;
+/**
+ * Defines a Storage Index using the RMS for persistence
+ * @author Ovidiu Iliescu
+ */
public class RmsStorageIndex extends StorageIndex {
+
+ /**
+ * The default record store name to use
+ */
static final String STORAGE = "RMSStorageIndex";
+
+ /**
+ * Indicates that the index of the actual record containing the StorageIndex is not known
+ */
static final int RECORD_UNKNOWN = Integer.MIN_VALUE;
+ /**
+ * The record store holding the index
+ */
RecordStore store;
+
+ /**
+ * The actual recordID of the record holding the index
+ */
int recordId = RECORD_UNKNOWN;
- public RmsStorageIndex(int maxCacheSize) {
+ public RmsStorageIndex(long maxCacheSize) {
+ this(STORAGE,maxCacheSize);
+ }
+
+ /**
+ * Creates a new RmsStorageIndex instance
+ * @param recordStoreName the name of the record store to use for persisting the index
+ * @param maxCacheSize the maximum size of the index
+ */
+ public RmsStorageIndex(String recordStoreName, long maxCacheSize) {
super(maxCacheSize);
- try {
- // open the record store
- this.store = RecordStore.openRecordStore(STORAGE, true);
- RecordEnumeration recordEnumeration = this.store.enumerateRecords(
- null, null, false);
-
- if (recordEnumeration.hasNextElement()) {
- this.recordId = recordEnumeration.nextRecordId();
+ // When using a dedicated store, use fail-safe behavior
+ if ( STORAGE.equals(recordStoreName) ) {
+ try {
+ // open the record store
+ this.store = RecordStore.openRecordStore(recordStoreName, true);
+ RecordEnumeration recordEnumeration = this.store.enumerateRecords(
+ null, null, false);
+
+ if (recordEnumeration.hasNextElement()) {
+ this.recordId = recordEnumeration.nextRecordId();
+
+ //#debug debug
+ System.out.println("index record id : " + this.recordId);
+ }
- //#debug debug
- System.out.println("index record id : " + this.recordId);
+ } catch (RecordStoreException e) {
+ //#debug error
+ System.out.println("unable to open record store " + e);
}
+ } else {
+ // When using a custom store, make sure the index is always stored in the first record
+ this.recordId = 1;
- } catch (RecordStoreException e) {
- //#debug error
- System.out.println("unable to open record store " + e);
+ // Initialize the first record
+ try {
+ // open the record store
+ this.store = RecordStore.openRecordStore(recordStoreName, true);
+
+ // see if the first record exists. if it does, we're done
+ store.getRecord(1);
+ } catch (InvalidRecordIDException e) {
+ // If it doesn't exist, reserve a spot for it and serialize an empty index at that location
+ try {
+ this.store.addRecord(new byte[1], 0, 1);
+ store(this.index);
+ } catch (Exception e2) {
+ //#debug error
+ System.out.println("unable to initialize index " + e);
+ }
+ } catch (RecordStoreException e) {
+ //#debug error
+ System.out.println("unable to open record store " + e);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see de.enough.polish.content.storage.StorageIndex#getAvailableCacheSize()
+ */
+ public long getAvailableCacheSize() {
+ try {
+ long available = Math.min(this.maxCacheSize - getCacheSize(), store.getSizeAvailable() - getCacheSize());
+ return available;
+ } catch (RecordStoreNotOpenException e) {
+ return this.maxCacheSize;
}
}
@@ -100,8 +167,8 @@ protected void store(ArrayList index) {
store.setRecord(this.recordId, bytes, 0, bytes.length);
}
else
- {
- // add the record
+ {
+ // Create the record
this.recordId = store.addRecord(bytes,0,bytes.length);
}
} catch (IOException e) {
@@ -113,6 +180,9 @@ protected void store(ArrayList index) {
}
}
+ /* (non-Javadoc)
+ * @see de.enough.polish.content.storage.StorageIndex#shutdown()
+ */
public void shutdown() {
super.shutdown();
View
31 enough-polish-j2me/source/src/de/enough/polish/content/storage/StorageIndex.java
@@ -27,7 +27,7 @@
/**
* the maximum cache size
*/
- final long maxCacheSize;
+ protected final long maxCacheSize;
/**
* is the StorageIndex prepared ?
@@ -167,6 +167,15 @@ public int size() {
public long getCacheSize() {
return this.cacheSize;
}
+
+ /**
+ * Returns the maximum possible number of bytes that can be stored. This takes into consideration both user-specified limitations
+ * (e.g. maximum cache size) and platform-specific limitations (e.g. storage space).
+ * @return the maximum possible number of bytes that can be stored in the cache.
+ */
+ public long getAvailableCacheSize() {
+ return maxCacheSize - cacheSize;
+ }
/**
* Loads the ArrayList representing the index. It is encouraged to overwrite
@@ -207,7 +216,7 @@ public StorageReference getReference(ContentDescriptor descriptor) {
return null;
}
-
+
/**
* Returns true, if the current cache size is greater than the threshold,
* otherwise false
@@ -216,7 +225,21 @@ public StorageReference getReference(ContentDescriptor descriptor) {
* otherwise false
*/
public boolean isCleanNeeded() {
- return getCacheSize() > this.maxCacheSize;
+ return isCleanNeeded(0);
+ }
+
+ /**
+ * Returns true, if the current cache size is not enough to store an additional extraBytes bytes,
+ * otherwise false
+ *
+ * @param extraBytes the number of extra bytes to store
+ * @return true, if the current cache size is greater than the threshold,
+ * otherwise false
+ */
+ public boolean isCleanNeeded(int extraBytes) {
+ int OVERHEAD = 256;
+ long finalSize = extraBytes + OVERHEAD;
+ return finalSize > getAvailableCacheSize();
}
/*
@@ -252,7 +275,7 @@ public int compare(Object first, Object second) {
*/
public boolean isDisposableTo(StorageReference reference,
StorageReference master) {
- return reference.getPriority() <= master.getPriority() && reference.getCreationTime() < master.getCreationTime();
+ return reference.getPriority() <= master.getPriority() && reference.getLastActivityTime() < master.getLastActivityTime();
}
/**
Please sign in to comment.
Something went wrong with that request. Please try again.