One of the built-in db4o IoAdapters is MemoryIoAdapter. This adapter keeps the whole database in RAM instead of a hard-drive. Obviously such in-memory database has both advantages and disadvantages:
Pros:
Cons:
You can achieve the best results combining the usage of MemoryIoAdapter with the normal file adapter. Let's look, how MemoryIoAdapter should be used in your application.
First of all MemoryIoAdapter should be configured. The API gives you control over memory consumption with
Java: MemoryIoAdapter#growBy(length)
method. Length defines the amount of bytes in memory that should be allocated, when no more free slots are found within the allocated file. Large value (100,000) will assure the best performance; small value (100) will keep the memory consumption at the lowest level. The default setting is 10,000.
MemoryIoAdaptor supplies methods to exchange data with the database from the filesystem.
Java: MemoryIoAdapter#put(filename, byte[])
This method allows you to put the contents of the stored database file (byte[]) into the memory database.
The opposite method:
Java: MemoryIoAdapter#get(filename)
returns the updated byte[] array of the database in memory, which can be saved to disc as a normal database file.
The filename can be used for all further access (#openFile, #openServer methods) like normal file name. Make sure that you close the database file on the disc after reading its contents into memory and writing it back.
The configured adapter should be assigned as db4o IO system:
Java: Db4o.configure().io(MemoryIoAdapter)
[/filter]
[filter=cs]
c#: Db4o.Configure().Io(MemoryIoAdapter)
01private static void setObjects(){ 02
new File(DB4O_FILE_NAME).delete(); 03
ObjectContainer container = Db4o.openFile(DB4O_FILE_NAME); 04
try { 05
Pilot pilot = new Pilot("Rubens Barrichello"); 06
container.set(pilot); 07
} finally { 08
container.close(); 09
} 10
}
Now we can read the database into the memory file and work in the memory using MemoryIoAdapter:
01private static void getObjectsInMem(){ 02
System.out.println("Setting up in-memory database"); 03
MemoryIoAdapter adapter = new MemoryIoAdapter(); 04
try { 05
RandomAccessFile raf = new RandomAccessFile(DB4O_FILE_NAME,"r"); 06
adapter.growBy(100); 07
08
int len = (int)raf.length(); 09
byte[] b = new byte[len]; 10
raf.read(b,0,len); 11
adapter.put(DB4O_FILE_NAME, b); 12
raf.close(); 13
} catch (Exception ex){ 14
System.out.println("Exception: " + ex.getMessage()); 15
} 16
17
Configuration configuration = Db4o.newConfiguration(); 18
configuration.io(adapter); 19
ObjectContainer container = Db4o.openFile(configuration, DB4O_FILE_NAME); 20
try { 21
ObjectSet result=container.get(Pilot.class); 22
System.out.println("Read stored results through memory file"); 23
listResult(result); 24
Pilot pilotNew = new Pilot("Michael Schumacher"); 25
container.set(pilotNew); 26
System.out.println("New pilot added"); 27
} finally { 28
container.close(); 29
} 30
System.out.println("Writing the database back to disc"); 31
byte[] dbstream = adapter.get(DB4O_FILE_NAME); 32
try { 33
RandomAccessFile file = new RandomAccessFile(DB4O_FILE_NAME,"rw"); 34
file.write(dbstream); 35
file.close(); 36
} catch (IOException ioex) { 37
System.out.println("Exception: " + ioex.getMessage()); 38
} 39
}
Well, the changes are made and written to the disc. Let's check, if all the data are in place. We will need to switch back to the normal RandomAccessFileAdapter:
01private static void getObjects(){ 02
Configuration configuration = Db4o.newConfiguration(); 03
configuration.io(new RandomAccessFileAdapter()); 04
ObjectContainer container = Db4o.openFile(configuration, DB4O_FILE_NAME); 05
try { 06
ObjectSet result=container.get(Pilot.class); 07
System.out.println("Read stored results through disc file"); 08
listResult(result); 09
} finally { 10
container.close(); 11
} 12
}
So, switching between disc and memory database is quite easy. It can be used to increase performance on certain operations. More flexibility can be reached writing your own IoAdapter implementation.