When an object is inserted or removed from the list, only the list object needs to be updated, the objects in the list are not going to be changed. That means that for the object from the previous topic we will need to set update depth = 1.
Let's fill up the database with 2 long lists of objects:
01private static void FillUpDb() 02
{ 03
int listCount = 2; 04
int dataCount = 50000; 05
Stopwatch sw = new Stopwatch(); 06
File.Delete(DbFile); 07
IObjectContainer db = Db4oFactory.OpenFile(DbFile); 08
try 09
{ 10
sw.Start(); 11
12
for (int i = 0; i < listCount; i++) 13
{ 14
ListObject lo = new ListObject(); 15
lo.Name = "list" + i.ToString("00"); 16
for (int j = 0; j < dataCount; j++) 17
{ 18
DataObject dataObject = new DataObject(); 19
dataObject.Name = "data" + j.ToString("00000"); 20
dataObject.Data = DateTime.Now.ToString() + " ---- Data Object " + j.ToString("00000"); 21
lo.Data.Add(dataObject); 22
} 23
db.Set(lo); 24
} 25
sw.Stop(); 26
} 27
finally 28
{ 29
db.Close(); 30
} 31
Console.WriteLine("Completed {0} lists of {1} objects each.", listCount, dataCount); 32
Console.WriteLine("Elapsed time: {0}", sw.Elapsed.ToString()); 33
}
01Private Shared Sub FillUpDb() 02
Dim listCount As Integer = 2 03
Dim dataCount As Integer = 50000 04
Dim sw As Stopwatch = New Stopwatch 05
File.Delete(DbFile) 06
Dim db As IObjectContainer = Db4oFactory.OpenFile(DbFile) 07
Try 08
sw.Start() 09
Dim i As Integer = 0 10
While i < listCount 11
Dim lo As ListObject = New ListObject 12
lo.Name = "list" + i.ToString("00") 13
Dim j As Integer = 0 14
While j < dataCount 15
Dim dataObject As DataObject = New DataObject 16
dataObject.Name = "data" + j.ToString("00000") 17
dataObject.Data = DateTime.Now.ToString + " ---- Data Object " + j.ToString("00000") 18
lo.Data.Add(dataObject) 19
System.Math.Min(System.Threading.Interlocked.Increment(j), j - 1) 20
End While 21
db.Set(lo) 22
System.Math.Min(System.Threading.Interlocked.Increment(i), i - 1) 23
End While 24
sw.Stop() 25
Finally 26
db.Close() 27
End Try 28
Console.WriteLine("Completed {0} lists of {1} objects each.", listCount, dataCount) 29
Console.WriteLine("Elapsed time: {0}", sw.Elapsed.ToString) 30
End Sub
We will remove an object from one list and insert it into another:
01private static void RemoveInsert() 02
{ 03
Stopwatch sw = new Stopwatch(); 04
05
IObjectContainer db = Db4oFactory.OpenFile(DbFile); 06
try 07
{ 08
// set activation depth to 1 for the quickest execution 09
db.Ext().Configure().UpdateDepth(1); 10
IList<ListObject> result = db.Query<ListObject>(); 11
if (result.Count == 2) 12
{ 13
// retrieve 2 ListObjects 14
ListObject lo1 = result[0]; 15
ListObject lo2 = result[1]; 16
DataObject dataObject = lo1.Data[0]; 17
// move the first object from the first 18
// ListObject to the second ListObject 19
lo1.Data.Remove(dataObject); 20
lo2.Data.Add(dataObject); 21
22
Console.WriteLine("Removed from the first list, count is {0}, setting data...", lo1.Data.Count); 23
Console.WriteLine("Added to the second list, count is {0}, setting data...", lo2.Data.Count); 24
sw.Start(); 25
db.Set(lo1); 26
db.Set(lo2); 27
db.Commit(); 28
sw.Stop(); 29
} 30
} 31
finally 32
{ 33
db.Close(); 34
} 35
Console.WriteLine("Storing took {0}", sw.Elapsed.ToString()); 36
}
01Private Shared Sub RemoveInsert() 02
Dim sw As Stopwatch = New Stopwatch 03
Dim db As IObjectContainer = Db4oFactory.OpenFile(DbFile) 04
Try 05
' set activation depth to 1 for the quickest execution 06
db.Ext.Configure.UpdateDepth(1) 07
Dim result As IList(Of ListObject) = db.Query(Of ListObject)() 08
If result.Count = 2 Then 09
' retrieve 2 ListObjects 10
Dim lo1 As ListObject = result(0) 11
Dim lo2 As ListObject = result(1) 12
Dim dataObject As DataObject = lo1.Data(0) 13
' move the first object from the first 14
' ListObject to the second ListObject 15
lo1.Data.Remove(dataObject) 16
lo2.Data.Add(dataObject) 17
Console.WriteLine("Removed from the first list, count is {0}, setting data...", lo1.Data.Count) 18
Console.WriteLine("Added to the second list, count is {0}, setting data...", lo2.Data.Count) 19
sw.Start() 20
db.Set(lo1) 21
db.Set(lo2) 22
db.Commit() 23
sw.Stop() 24
End If 25
Finally 26
db.Close() 27
End Try 28
Console.WriteLine("Storing took {0}", sw.Elapsed.ToString) 29
End Sub
Remember, if an object is removed from the list and is not going to be used any more, it should be deleted manually:
db.Delete(dataObject)
Let's check if the results are correct:
01private static void CheckResults() 02
{ 03
Stopwatch sw = new Stopwatch(); 04
IObjectContainer db = Db4oFactory.OpenFile(DbFile); 05
try 06
{ 07
IList<ListObject> result = db.Query<ListObject>(); 08
if (result.Count > 0) 09
{ 10
// activation depth should be enough to activate 11
// ListObject, DataObject and its list members 12
int activationDepth = 3; 13
db.Ext().Configure().ActivationDepth(activationDepth); 14
Console.WriteLine("Result count was {0}, looping with activation depth {1}", result.Count, activationDepth); 15
sw.Start(); 16
foreach (ListObject lo in result) 17
{ 18
Console.WriteLine("ListObj {0} has {1} objects", lo.Name, 19
((lo.Data == null) ? "<null>" : lo.Data.Count.ToString())); 20
Console.WriteLine(" --- {0} at index 0", 21
((lo.Data != null && lo.Data.Count > 0) ? lo.Data[0].ToString() : "<null>")); 22
} 23
sw.Stop(); 24
} 25
} 26
finally 27
{ 28
db.Close(); 29
} 30
Console.WriteLine("Activation took {0}", sw.Elapsed.ToString()); 31
}
01Private Shared Sub CheckResults() 02
Dim sw As Stopwatch = New Stopwatch 03
Dim db As IObjectContainer = Db4oFactory.OpenFile(DbFile) 04
Try 05
Dim result As IList(Of ListObject) = db.Query(Of ListObject)() 06
If result.Count > 0 Then 07
' activation depth should be enough to activate 08
' ListObject, DataObject and its list members 09
Dim activationDepth As Integer = 3 10
db.Ext.Configure.ActivationDepth(activationDepth) 11
Console.WriteLine("Result count was {0}, looping with activation depth {1}", result.Count, activationDepth) 12
sw.Start() 13
For Each lo As ListObject In result 14
Console.WriteLine("ListObj {0} has {1} objects", lo.Name, (Microsoft.VisualBasic.IIf((lo.Data Is Nothing), "<null>", lo.Data.Count.ToString))) 15
Console.WriteLine(" --- {0} at index 0", (Microsoft.VisualBasic.IIf((Not (lo.Data Is Nothing) AndAlso lo.Data.Count > 0), lo.Data(0).ToString, "<null>"))) 16
Next 17
sw.Stop() 18
End If 19
Finally 20
db.Close() 21
End Try 22
Console.WriteLine("Activation took {0}", sw.Elapsed.ToString) 23
End Sub
You will see that insert/remove operation takes much less time with the correct update depth setting.