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
c#: MemoryIoAdapter#GrowBy(length)
VB: 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.
c#: MemoryIoAdapter#Put(filename, byte[])
VB: MemoryIoAdapter#Put(String, byte())
This method allows you to put the contents of the stored database file (byte[]) into the memory database.
The opposite method:
c#: MemoryIoAdapter#Get(filename)
VB: 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:
VB: Db4o.Configure().Io(MemoryIoAdapter)
01private static void SetObjects() 02
{ 03
File.Delete(Db4oFileName); 04
IObjectContainer db = Db4oFactory.OpenFile(Db4oFileName); 05
try 06
{ 07
Pilot pilot = new Pilot("Rubens Barrichello"); 08
db.Set(pilot); 09
} 10
finally 11
{ 12
db.Close(); 13
} 14
}
01Private Shared Sub SetObjects() 02
File.Delete(Db4oFileName) 03
Dim db As IObjectContainer = Db4oFactory.OpenFile(Db4oFileName) 04
Try 05
Dim pilot As Pilot = New Pilot("Rubens Barrichello") 06
db.Set(pilot) 07
Finally 08
db.Close() 09
End Try 10
End Sub
Now we can read the database into the memory file and work in the memory using MemoryIoAdapter:
01private static void GetObjectsInMem() 02
{ 03
System.Console.WriteLine("Setting up in-memory database"); 04
MemoryIoAdapter adapter = new MemoryIoAdapter(); 05
try 06
{ 07
Sharpen.IO.RandomAccessFile raf = new Sharpen.IO.RandomAccessFile(Db4oFileName,"r"); 08
adapter.GrowBy(100); 09
10
int len = (int)raf.Length(); 11
byte[] b = new byte[len]; 12
raf.Read(b,0,len); 13
adapter.Put(Db4oFileName, b); 14
raf.Close(); 15
} 16
catch (Exception ex) 17
{ 18
System.Console.WriteLine("Exception: " + ex.Message); 19
} 20
IConfiguration configuration = Db4oFactory.NewConfiguration(); 21
configuration.Io(adapter); 22
IObjectContainer db = Db4oFactory.OpenFile(configuration, Db4oFileName); 23
try 24
{ 25
IObjectSet result=db.Get(typeof(Pilot)); 26
System.Console.WriteLine("Read stored results through memory file"); 27
ListResult(result); 28
Pilot pilotNew = new Pilot("Michael Schumacher"); 29
db.Set(pilotNew); 30
System.Console.WriteLine("New pilot added"); 31
} 32
finally 33
{ 34
db.Close(); 35
} 36
System.Console.WriteLine("Writing the database back to disc"); 37
byte[] dbstream = adapter.Get(Db4oFileName); 38
try 39
{ 40
Sharpen.IO.RandomAccessFile file = new Sharpen.IO.RandomAccessFile(Db4oFileName, "rw"); 41
file.Write(dbstream); 42
file.Close(); 43
} 44
catch (IOException ioex) 45
{ 46
System.Console.WriteLine("Exception: " + ioex.Message); 47
} 48
}
01Private Shared Sub GetObjectsInMem() 02
System.Console.WriteLine("Setting up in-memory database") 03
Dim adapter As MemoryIoAdapter = New MemoryIoAdapter() 04
Try 05
Dim raf As Sharpen.IO.RandomAccessFile = New Sharpen.IO.RandomAccessFile(Db4oFileName, "r") 06
adapter.GrowBy(100) 07
08
Dim len As Integer = CType(raf.Length(), Integer) 09
Dim b() As Byte = New Byte(len) {} 10
raf.Read(b, 0, len) 11
adapter.Put(Db4oFileName, b) 12
raf.Close() 13
Catch ex As Exception 14
System.Console.WriteLine("Exception: " + ex.Message) 15
End Try 16
17
Dim configuration As IConfiguration = Db4oFactory.NewConfiguration() 18
configuration.Io(adapter) 19
Dim db As IObjectContainer = Db4oFactory.OpenFile(configuration, Db4oFileName) 20
Try 21
Dim result As IObjectSet = db.Get(GetType(Pilot)) 22
System.Console.WriteLine("Read stored results through memory file") 23
ListResult(result) 24
Dim pilotNew As Pilot = New Pilot("Michael Schumacher") 25
db.Set(pilotNew) 26
System.Console.WriteLine("New pilot added") 27
Finally 28
db.Close() 29
End Try 30
System.Console.WriteLine("Writing the database back to disc") 31
Dim dbstream() As Byte = adapter.Get(Db4oFileName) 32
Try 33
Dim file As Sharpen.IO.RandomAccessFile = New Sharpen.IO.RandomAccessFile(Db4oFileName, "rw") 34
file.Write(dbstream) 35
file.Close() 36
Catch ioex As IOException 37
System.Console.WriteLine("Exception: " + ioex.Message) 38
End Try 39
End Sub
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
{ 03
IConfiguration configuration = Db4oFactory.NewConfiguration(); 04
configuration.Io(new RandomAccessFileAdapter()); 05
IObjectContainer db = Db4oFactory.OpenFile(configuration, Db4oFileName); 06
try 07
{ 08
IObjectSet result=db.Get(typeof(Pilot)); 09
System.Console.WriteLine("Read stored results through disc file"); 10
ListResult(result); 11
} 12
finally 13
{ 14
db.Close(); 15
} 16
}
01Private Shared Sub GetObjects() 02
Dim configuration As IConfiguration = Db4oFactory.NewConfiguration() 03
configuration.Io(New RandomAccessFileAdapter()) 04
Dim db As IObjectContainer = Db4oFactory.OpenFile(configuration, Db4oFileName) 05
Try 06
Dim result As IObjectSet = db.Get(GetType(Pilot)) 07
System.Console.WriteLine("Read stored results through disc file") 08
ListResult(result) 09
Finally 10
db.Close() 11
End Try 12
End Sub
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.