Insert And Remove

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:

ListOperationsExample.java: fillUpDb
01private static void fillUpDb() 02 { 03 int listCount = 2; 04 int dataCount = 50000; 05 long elapsedTime = 0; 06 new File(DBFILE).delete(); 07 ObjectContainer db = Db4o.openFile(DBFILE); 08 try 09 { 10 long t1 = System.currentTimeMillis(); 11 12 for (int i = 0; i < listCount; i++) 13 { 14 ListObject lo = new ListObject(); 15 lo.setName("list" + String.format("%3d", i)); 16 for (int j = 0; j < dataCount; j++) 17 { 18 DataObject dataObject = new DataObject(); 19 dataObject.setName( "data" + String.format("%5d", j)); 20 dataObject.setData( System.currentTimeMillis() + " ---- Data Object " + String.format("%5d", j)); 21 lo.getData().add(dataObject); 22 } 23 db.set(lo); 24 } 25 long t2 = System.currentTimeMillis(); 26 elapsedTime = t2 - t1; 27 } 28 finally 29 { 30 db.close(); 31 } 32 System.out.println("Completed " + listCount + " lists of " + dataCount + " objects each."); 33 System.out.println("Elapsed time: " + elapsedTime + " ms."); 34 }

We will remove an object from one list and insert it into another:

ListOperationsExample.java: removeInsert
01private static void removeInsert() 02 { 03 ObjectContainer db = Db4o.openFile(DBFILE); 04 long timeElapsed = 0; 05 try 06 { 07 // set activation depth to 1 for the quickest execution 08 db.ext().configure().updateDepth(1); 09 List<ListObject> result = db.<ListObject>query(ListObject.class); 10 if (result.size() == 2) 11 { 12 // retrieve 2 ListObjects 13 ListObject lo1 = result.get(0); 14 ListObject lo2 = result.get(1); 15 DataObject dataObject = lo1.getData().get(0); 16 // move the first object from the first 17 // ListObject to the second ListObject 18 lo1.getData().remove(dataObject); 19 lo2.getData().add(dataObject); 20 21 System.out.println("Removed from the first list, count is " + lo1.getData().size()); 22 System.out.println("Added to the second list, count is " + lo2.getData().size()); 23 long t1 = System.currentTimeMillis(); 24 // save ListObjects. UpdateDepth = 1 will ensure that 25 // the DataObject list is saved as well 26 db.set(lo1); 27 db.set(lo2); 28 db.commit(); 29 long t2 = System.currentTimeMillis(); 30 timeElapsed = t2 - t1; 31 } 32 } 33 finally 34 { 35 db.close(); 36 } 37 System.out.println("Storing took: " + timeElapsed + " ms."); 38 }

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:

ListOperationsExample.java: checkResults
01private static void checkResults() 02 { 03 ObjectContainer db = Db4o.openFile(DBFILE); 04 try 05 { 06 List<ListObject> result = db.<ListObject>query(ListObject.class); 07 if (result.size() > 0) 08 { 09 // activation depth should be enough to activate 10 // ListObject, DataObject and its list members 11 int activationDepth = 3; 12 db.ext().configure().activationDepth(activationDepth); 13 System.out.println("Result count was " + result.size()+ " looping with activation depth" + activationDepth); 14 for (int i = 0; i < result.size(); i++){ 15 ListObject lo = (ListObject)result.get(i); 16 System.out.println("ListObj " + lo.getName() + " has " + ((lo.getData() == null) ? "<null>" : lo.getData().size()) +" objects"); 17 System.out.println((lo.getData() != null && lo.getData().size() > 0) ? lo.getData().get(0).toString() : "<null>" + " at index 0"); 18 System.out.println(); 19 } 20 } 21 } 22 finally 23 { 24 db.close(); 25 } 26 }

You will see that insert/remove operation takes much less time with the correct update depth setting.