Using Record Stores Instead of Heap Memory

An additional opportunity for saving heap space is to store application data in a record store instead of consuming heap memory. The space available for persistent storage is often significantly larger than the heap memory, so in situations where heap memory is really rare, it may make sense to shift some of the memory consumption from the heap to persistent storage. However, accessing persistent storage may be significantly slower than heap access. Thus, the price for having more heap may be a significant performance tradeoff.

In order to demonstrate how to store objects in a record store instead of a Vector, let's create a sample implementation of a StringVectorRms class that stores a list of Strings in a record store. In contrast to an ordinary Vector, only a small amount of heap is consumed. The StringVectorRms implementation provides the access methods listed in Table 8.2.

Table 8.2. Methods of the StringVectorRms Class
Method Description
StringVectorRms () Constructs an instance and creates the underlying record store if needed.
addString (String text) Adds a String to the end of the Vector.
String stringAt (int index) Returns the String at the given index.
removeStringAt (int index) Removes the String at the given index and shifts the entries starting at index+1 down in order to fill the resulting gap.
SetStringAt (String newText, int newIndex) Replaces the String at position index with the new String that is contained in the variable newText.
int size () Returns the number of Strings that are currently stored.

Listing 8.1 shows the corresponding StringVectorRms implementation. It handles the conversation between Strings and the byte arrays stored in the record store. It also maps the Vector indices starting with 0 to RMS indices starting with 1 and maps all RmsExceptions to RuntimeExceptions. Finally, it takes care of shifting the remaining elements to their new index if an element is deleted.

Note

Especially for flash memory, write operations might take seconds. Thus, the removeStringAt() method should be used with special caution; all remaining items are moved to their new index position, requiring a lot of write operations.


Listing 8.1. StringVectorRMS.java—The StringVectorRMS Class for Storing Strings in a Record Store During Application Runtime
import javax.microedition.rms.*;

public class StringVectorRms {
    RecordStore store;
    String storeName;

    int size;

    static int openedStores = 0;


    public StringVectorRms () {
        storeName = "StringVectorRms"+(openedStores++);
        size = 0;
        try {
            store = RecordStore.openRecordStore (storeName, true);
            if (store.getNumRecords() > 0) {
            store.closeRecordStore ();
            RecordStore.deleteRecordStore (storeName);
            store = RecordStore.openRecordStore (storeName, true);
            }
        }
        catch (Exception e) {
            throw new RuntimeException (e.toString ());
        }
    }
    
    
    public void addString (String text) {
        try {
            byte[] data = text.getBytes ();
            if (size < store.getNumRecords ())
                store.setRecord (size+1, data, 0, data.length);
            else
                store.addRecord (data, 0, data.length);
            size++;
        }
        catch (Exception e) {
            throw new RuntimeException (e.toString ());
        }
    }


    public String stringAt (int index) {
        try {
            return new String (store.getRecord (index+1));
        }
        catch (Exception e) {
            throw new RuntimeException (e.toString ());
        }
    }


    public void removeStringAt (int index) {
        try {
            for (int i = index; i < size-1; i++) {
                byte[] data = store.getRecord (i+2);
                store.setRecord (i+1, data, 0, data.length);
            }
            size--;
        }
        catch (Exception e) {
            throw new RuntimeException (e.toString ());
        }
    }


    public void setStringAt (String newText, int newIndex) {
        try {
            byte[] newData = newText.getBytes ();
            store.setRecord (newIndex+1, newData, 0, newData.length);
        }
        catch (Exception e) {
            throw new RuntimeException (e.toString ());
        }
    }


    public int size () {
        return size;
    }


    public void close () {
        try {
            store.closeRecordStore ();
            RecordStore.deleteRecordStore (storeName);
        }
        catch (Exception e) {
            throw new RuntimeException (e.toString ());
        }
    }
}
				

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset