The following example helps to see the effect of cache by modifying the cache size. Note, that this example is not a good illustration of the LRU cache algorithm, and only shows the effect of simple caching of the most recent data.
For the test we will use the following 2 classes: Item and ItemStore, holding a collection of items:
CachingStorageExample.cs: Item
private class Item {
int id;
String name;
public Item(int id, String name) {
this.id = id;
this.name = name;
}
public override string ToString() {
return String.Format("{0} [{1}]", name, id);
}
}
CachingStorageExample.cs: ItemStore
private class ItemStore {
List<Item> items;
public ItemStore() {
this.items = new List<Item>();
}
public void AddItem(Item item) {
this.items.Add(item);
}
}
CachingStorageExample.vb: Item
Private Class Item
Private id As Integer
Private name As [String]
Public Sub New(ByVal id As Integer, ByVal name As [String])
Me.id = id
Me.name = name
End Sub
Public Overloads Overrides Function ToString() As String
Return [String].Format("{0} [{1}]", name, id)
End Function
End Class
CachingStorageExample.vb: ItemStore
Private Class ItemStore
Private items As List(Of Item)
Public Sub New()
Me.items = New List(Of Item)()
End Sub
Public Sub AddItem(ByVal item As Item)
Me.items.Add(item)
End Sub
End Class
The following methods will be used to fill in and query the database:
CachingStorageExample.cs: CreateDatabase
private static void CreateDatabase(IEmbeddedConfiguration config) {
File.Delete(Db4oFileName);
long startTime = DateTime.Now.Ticks;
IObjectContainer container = Db4oEmbedded.OpenFile(config, Db4oFileName);
try {
ItemStore itemStore = new ItemStore();
for (int i = 0; i < ObjectCount; i++) {
itemStore.AddItem(new Item(i, "title" + i));
}
container.Store(itemStore);
Item item = (Item) container.QueryByExample(
new Item(1, "title1"))[0];
System.Console.WriteLine(item);
} finally {
container.Close();
}
System.Console.WriteLine(String.Format("Time to create a database: {0} ms",
(DateTime.Now.Ticks - startTime)/TimeSpan.TicksPerMillisecond));
}
CachingStorageExample.cs: QueryDatabase
private static void QueryDatabase(IEmbeddedConfiguration config) {
IObjectContainer container = Db4oEmbedded
.OpenFile(config, Db4oFileName);
try {
List<Item> temp = new List<Item>();
long startTime = DateTime.Now.Ticks;
IQuery q = container.Query();
q.Constrain(typeof(Item));
q.Descend("id").Constrain(1).Greater();
IObjectSet result = q.Execute();
foreach (Item i in result) {
temp.Add(i);
}
System.Console.WriteLine(String.Format("Time to get an objects first time: {0} ms",
(DateTime.Now.Ticks - startTime)/TimeSpan.TicksPerMillisecond));
//
temp = new List<Item>();
startTime = DateTime.Now.Ticks;
foreach (Item i in result) {
temp.Add(i);
}
System.Console.WriteLine(String.Format("Time to get an objects second time: {0} ms",
(DateTime.Now.Ticks - startTime)/TimeSpan.TicksPerMillisecond));
} finally {
container.Close();
}
}
CachingStorageExample.vb: CreateDatabase
Private Shared Sub CreateDatabase(ByVal config As IEmbeddedConfiguration)
File.Delete(Db4oFileName)
Dim startTime As Long = DateTime.Now.Ticks
Dim container As IObjectContainer = _
Db4oEmbedded.OpenFile(config, Db4oFileName)
Try
Dim itemStore As New ItemStore()
For i As Integer = 0 To ObjectCount - 1
itemStore.AddItem(New Item(i, "title" & i))
Next
container.Store(itemStore)
Dim item As Item = _
DirectCast(container.QueryByExample(New Item(1, "title1"))(0), Item)
System.Console.WriteLine(item)
Finally
container.Close()
End Try
System.Console.WriteLine([String].Format("Time to create a database: {0} ms", _
(DateTime.Now.Ticks - startTime) / TimeSpan.TicksPerMillisecond))
End Sub
CachingStorageExample.vb: QueryDatabase
Private Shared Sub QueryDatabase(ByVal config As IEmbeddedConfiguration)
Dim container As IObjectContainer = _
Db4oEmbedded.OpenFile(config, Db4oFileName)
Try
Dim temp As New List(Of Item)()
Dim startTime As Long = DateTime.Now.Ticks
Dim q As IQuery = container.Query()
q.Constrain(GetType(Item))
q.Descend("id").Constrain(1).Greater()
Dim result As IObjectSet = q.Execute()
For Each i As Item In result
temp.Add(i)
Next
System.Console.WriteLine([String].Format( _
"Time to get an objects first time: {0} ms", _
(DateTime.Now.Ticks - startTime) / TimeSpan.TicksPerMillisecond))
'
temp = New List(Of Item)()
startTime = DateTime.Now.Ticks
For Each i As Item In result
temp.Add(i)
Next
System.Console.WriteLine([String].Format(_
"Time to get an objects second time: {0} ms", _
(DateTime.Now.Ticks - startTime) / TimeSpan.TicksPerMillisecond))
Finally
container.Close()
End Try
End Sub
In general you should see the benefits of using cache with the majority of db4o operations. However, the effect is most obvious when a large amount of database information should be accessed fast (query) and this information is not loaded in the applications hash memory. We are trying to reproduce this situation in the second method querying database. If the amount of items in the ItemStore collection is 10000, the database size will be around 900 KB. With the default cache size, i.e. page count multiplied by page size (64 * 1024), this will mean that the whole collection won't fit into the cache (It can still fit into your hash memory, so you may want to decrease the available hash memory or increase the size of the collection to see the effect.).
We will use the following configuration methods to compare the default cache allocation and the custom one:
CachingStorageExample.cs: GetConfig
private static IEmbeddedConfiguration GetConfig() {
IEmbeddedConfiguration config = Db4oEmbedded.NewConfiguration();
config.File.Storage
= new CachingStorage(new FileStorage(), PageCount, PageSize);
return config;
}
CachingStorageExample.cs: GetDefaultConfig
private static IEmbeddedConfiguration GetDefaultConfig() {
IEmbeddedConfiguration config = Db4oEmbedded.NewConfiguration();
return config;
}
CachingStorageExample.vb: GetConfig
Private Shared Function GetConfig() As IEmbeddedConfiguration
Dim config As IEmbeddedConfiguration = _
Db4oEmbedded.NewConfiguration()
config.File.Storage = New _
CachingStorage(New FileStorage(), PageCount, PageSize)
Return config
End Function
CachingStorageExample.vb: GetDefaultConfig
Private Shared Function GetDefaultConfig() As IEmbeddedConfiguration
Dim config As IEmbeddedConfiguration = _
Db4oEmbedded.NewConfiguration()
Return config
End Function
Using custom page count = 1024 will make the cache size enough to fit the whole collection, and you should see some performance improvement browsing the retrieved collection second time (Unless it all fits into your hash memory in any case). Please, also try decreasing page size and count to see the opposite effect.
Download example code: