When a field in a Managed Object is accessed, transactional locking and logging occur. This is true for primitive types, arrays, and objects.
Arrays can also be copied into a local array variable to avoid transactional locking or logging. This copy occurs implicitly if an array is passed into a method for execution. Shared memory backing an array is only modified when elements in the array are modified using the object reference containing the array. These cases are shown in the snippet below.
Array copies are a useful performance optimization when a large number of elements in an array are being modified in a single transaction.
Example 5.29. Array copy-in/copy-out
// $Revision: 1.1.2.1 $ package com.kabira.snippets.managedobjects; import com.kabira.platform.Transaction; import com.kabira.platform.annotation.Managed; /** * Array copy-in/copy-out * <p> * <h2> Target Nodes</h2> * <ul> * <li> <b>domainnode</b> = A * </ul> */ public class Array extends Transaction { /** * A managed object */ @Managed public static class MyObject { int value; } /** * A managed object containing other managed objects */ @Managed public static class MyObjectContainer { /** * Create a new object */ public MyObjectContainer() { super(); sharedMemoryArray = new int[10]; int i; for (i = 0; i < 10; i++) { sharedMemoryArray[i] = i; } objectArray = new MyObject[2]; for (i = 0; i < 2; i++) { MyObject f2 = new MyObject(); f2.value = i; objectArray[i] = f2; } } int [] sharedMemoryArray; MyObject [] objectArray; } /** * Main entry point * @param args Not used */ public static void main(String [] args) { Array array = new Array(); array.execute(); } /** * Transaction run method * */ @Override protected void run() { MyObjectContainer f = new MyObjectContainer(); // // Read lock f and make of copy of sharedMemoryArray in localArray // int localArray[] = f.sharedMemoryArray; // // This does not modify shared memory // localArray[2] = 6; System.out.println("localArray: " + localArray[2] + " sharedMemoryArray: " + f.sharedMemoryArray[2]); // // This modifies shared memory and takes a write lock on f // f.sharedMemoryArray[2] = 7; System.out.println("localArray: " + localArray[2] + " sharedMemoryArray: " + f.sharedMemoryArray[2]); // // This does not change the value of sharedMemoryArray in // shared memory // modifyIntArray(localArray); System.out.println("localArray: " + localArray[0] + " sharedMemoryArray: " + f.sharedMemoryArray[0]); // // This does not modify the value of sharedMemoryArray in shared // memory. It takes a read lock on f. // modifyIntArray(f.sharedMemoryArray); System.out.println("localArray: " + localArray[0] + " sharedMemoryArray: " + f.sharedMemoryArray[0]); // // This copies the value of localArray into shared memory // and takes a write lock on f. // f.sharedMemoryArray = localArray; System.out.println("localArray: " + localArray[0] + " sharedMemoryArray: " + f.sharedMemoryArray[0]); // // This copies only the object references in objectArray to a local // array // MyObject localF2Array[] = f.objectArray; // // This updates shared memory through the object reference copied // into the local array // localF2Array[0].value = 8; System.out.println("f2.value: " + f.objectArray[0].value); } /** * Modify the array passed as a parameter * @param arg Array to modify */ public void modifyIntArray(int [] arg) { arg[0] = 5; } }
When Example 5.29, “Array copy-in/copy-out” is run it outputs (annotation added):
Example 5.30. Array copy-in/copy-out output
# # Modify local array with a value of 6 # [A] localArray: 6 sharedMemoryArray: 2 # # Modify shared memory with a value of 7 # [A] localArray: 6 sharedMemoryArray: 7 # # Modify local array with a value of 5 # [A] localArray: 5 sharedMemoryArray: 0 # # Modify shared memory array passed to a method with a value of 5 # [A] localArray: 5 sharedMemoryArray: 0 # # Copy local array into shared memory array # [A] localArray: 5 sharedMemoryArray: 5 # # Modify shared memory using an object reference in a local array # [A] f2.value: 8