Showing posts with label JODB. Show all posts
Showing posts with label JODB. Show all posts

Sunday, October 11, 2009

JODB (Java Objects Database) for Android (3) with reduced TestIndex benchmark

While creating and running the TestIndex for JODB I've discovered a few things.
  • Search operations are slow, and scale with the amount of records that is present in the database, so if it tok 2 seconds to get 10 distinct records with 100 records it will take 200 seconds with 10000, which are the number of records currently used in the TestIndex test. So large record-sets are not a good idea.
  • It seems to use a very little amount of memory, but when searching goes as it goes, that doesn't really help that much when things take as much time as it does.
  • As mentioned before it only supports primitives as indexes, so one really can't do a full TestIndex test.
As search operations was so costly I though I run a very reduced test with 100 records just to see how all of the other database management systems (DBMS).


As we see search operations are costly, my guess to why they are so costly is the way that JODB interacts with files on the system. I think that it do a lot of input/output (IO) operations when it does it's search operations. From what I gathered from looking in the source code it uses a FileChannel object to access its database files, which just reads or writes on a specific part of a file. So when doing a search operation it will read through the file until it finds the "part" (Record) that we are interested in. This would also explain why it use so little memory when it is running.



Perst
SQLite
DB4O
BerkeleyDB
JODB
Insert
106
586
278
354
2183
Search
48
889
989
334
31021
Iterate
14
36
238
192
718
Delete
115
498
415
465
1011

JODB (Java Objects Database) for Android (2)

After my previous post on JODB and after using it for a while I discovered a couple of things about JODB. JODB is picky of what it allows you to use as an Index. It will only allow you to use primitives as an index, so if you try to use something that is not a primitive, such as a string:

db.configureIndex(Record.class, "strKey", true); won't work.

You will get an exception looking something like this:
com.mobixess.jodb.core.JodbIOException: can't find description for primitive java.lang.String
com.mobixess.jodb.util.PrimitiveJavaTypesUtil.getEnumeratedType(PrimitiveJavaTypesUtil.java:141)
com.mobixess.jodb.core.index.JODBIndexingAgent.(JODBIndexingAgent.java:73)
com.mobixess.jodb.core.index.JODBIndexingRootAgent.addAgent(JODBIndexingRootAgent.java:148)
com.mobixess.jodb.core.index.JODBIndexingRootAgent.enableIndex(JODBIndexingRootAgent.java:72)
com.mobixess.jodb.core.JODBSessionContainer.configureIndex(JODBSessionContainer.java:130)
com.mobixess.jodb.core.JODBSessionContainer.configureIndex(JODBSessionContainer.java:102)

Another thing you must watch out for is when you are deleting your object from the database, you should(must at least when they contain other stuff than primitives) deactivate them, before, deleting them.
Record r = set.next();
db.deactivate(r, 1);
db.delete(r);
If you do not do this you will get an exception from deep within the Apache harmoney classes, in mmap method.
java.io.IOException
org.apache.harmony.luni.platform.OSMemory.mmap(OSMemory.java:617)
org.apache.harmony.luni.platform.PlatformAddressFactory.allocMapPlatformAddressFactory.java:107)
org.apache.harmony.nio.internal.FileChannelImpl.mapImpl(FileChannelImpl.java:201)
org.apache.harmony.nio.internal.ReadWriteFileChannel.map(ReadWriteFileChannel.java:53)
org.apache.harmony.nio.internal.FileChannelImpl.transferFrom(FileChannelImpl.java:422)
com.mobixess.jodb.core.io.buffers.RandomAccessFileTransactionBuffer.transferFrom(RandomAccessFileTransactionBuffer.java:156)
com.mobixess.jodb.core.io.JODBIOBase.applyTransaction0(JODBIOBase.java:501)
com.mobixess.jodb.core.io.JODBIOBase.applyTransaction0(JODBIOBase.java:433)
com.mobixess.jodb.core.io.JODBIOBase.applyTransaction(JODBIOBase.java:336)
com.mobixess.jodb.core.JODBSessionContainer.commit(JODBSessionContainer.java:202
com.mobixess.jodb.core.JODBSessionContainer.commit(JODBSessionContainer.java:191)

So now I got a working TestIndex for JODB, so soon I'll hopefully have some results on the emulator and on the ADP1. The biggest problem I found with using JODB is the lack of documentation, so if you're considering using it you should be aware that it's not that much help to get.

Thursday, October 8, 2009

JODB (Java Objects Database) for Android

JODB (Java Objects Database) is an open source object-oriented database that is somewhat similar to db4objects.

License
JODB is completely free for personal and commercial use.

JODB
The developer of JODB sais that JODB is created with performance, size and scalability in mind. It uses soft reference based caches to effectively use the available ram but at the same time reduce the memory footprint as much as possible when memory is pricey, like it is on Android.
The developer say that the queries are optimized to the minimal of objects instantiations during the search so that garbage collector will have more time to 'rest' which is especially important for busy server applications (GC as is expensive and this is unlikely to change in near future).


Things you should watch out for
The Android version of JODB does not have the Client/Server functionality and can thus only be used as an embedded database. This really doesn't matter that much to me, as I was going to use it as an embedded database anyway, but it is something to take not of. The current version of JODB mini doesn't support running of native queries. The developer(s) say this will be corrected in future versions, but that's a long time ago so I'm not really sure that it will happen  . And at last the big one you must use com.mobixess.jodb.core.JodbMini as the entry point instead of com.mobixess.jodb.core.JODB.

So opening a database would look something like this:  JodbMini.open(databaseName) ;

Problems related to android
JODB have had Android support for a long time ( since 2007 ), but Android has changed a bit since they released their JODB Mini. RandomAccessFileBufferFactory.createBuffer in JODB, uses File.createTempFile() which creates a new file in the directory that is defined by the java.io.tmpdir system property. Using this method not a recommended practice in Android, as it will fill up data in a folder that might not be cleaned up, making the application fill up a lot of space, that we won't get back until it cleanup. It seems that Android( at least in 1.6 )  have solved this problem by setting the java.io.tmpdir to the SDCARD. But still we don't want to pollute our SDCARD directory with lots of temporary files, and in this case we want the files to be written and read fast so the SDCARD is not a good option. An other thing is that Android as of 1.6  Applications need explicit permission to be allowed to write to the SDCARD through the android.permission.WRITE_EXTERNAL_STORAGE permission.
To fix this you can:
  1. Give the application write access to the SDCARD.
  2. Set the "java.io.tmpdir" property to somewhere on the phone where the application can write, like in it's own "home" directory.
The nice thing about setting the "java.io.tmpdir" property property to a directory within the applications own directory is that when you remove the application from the device, all of the related data will also be removed.

I here set the temp directory to a directory with the application directory so I can clean up the temp files by just deleting the contents of that directory.

File dir = this.getDir("TMP", 0);
String newTempDir = dir.getAbsolutePath();
System.setProperty("java.io.tmpdir", newTempDir);

Documentation
JODB help page and javadoc is the only documentation that I found on JODB. JODB mini can be fetched here.