|
Summary: How to access space objects using their unique identifiers (UID).
OverviewGigaSpaces allows space Entries to be accessed using their unique identifiers (UID). This powerful option allows users to access space Entries very quickly without having to use the space matching subsystem.
The UID is a string based identifier and is composed of the following parts:
UID is supported by the Entry API and by the ExternalEntry API.
Defining Custom UIDBy default, GigaSpaces generates a unique ID automatically, and you can retrieve it through the lease after calling the write or from an Entry object as described in Using UID with Entry Objects. However, you also have the option of using your own unique name as an Entry UID. The ClientUIDHandler method allows you to supply your own unique name for an Entry and receive a formatted UID string generated from that name. This allows you to maintain your own object classification while ensuring the uniqueness of IDs. ClientUIDHandler also provides a method that converts UIDs into original names, so that you can identify objects received. The procedure below explains how to create an Entry with a user-defined UID. Following it is a code sample that illustrates the process. To create an Entry with a user-defined UID:
import net.jini.core.lease.Lease; import net.jini.space.JavaSpace; import com.j_spaces.core.IJSpace; import com.j_spaces.core.LeaseProxy; import com.j_spaces.core.client.EntryInfo; import com.j_spaces.core.client.SpaceFinder; import com.j_spaces.core.client.ClientUIDHandler ; public class MyEntry extends com.j_spaces.core.client.MetaDataEntry { public String myData; public MyEntry() { } public MyEntry(String data) { this.myData = data; } public String toString() {return myData;} public static void main(String[] args) { try { IJSpace space = (IJSpace) SpaceFinder.find(args[0]); // Setting Entry UID MyEntry myentry = new MyEntry("Data"); // make sure you provide unique name! String uid1 = ClientUIDHandler.createUIDFromName("MyEntryUID" ,MyEntry.class.getName() ); EntryInfo ei1 = new EntryInfo(uid1 , 0); myentry.__setEntryInfo(ei1); // Write entry to space Lease l = space.write(myentry, null, Lease.FOREVER); LeaseProxy lp =(LeaseProxy)l; System.out.println("Wrote Object with UID:" + lp.getUID()); // Reading Entry using its UID MyEntry template = new MyEntry(); String uid2 = ClientUIDHandler.createUIDFromName( "MyEntryUID" ,MyEntry.class.getName() ); EntryInfo ei2 = new EntryInfo(uid2 , 0); template.__setEntryInfo(ei2); MyEntry m = (MyEntry) space.read( template, null, JavaSpace.NO_WAIT); System.out.println("Read Object with UID:" + m.__getEntryInfo().m_UID + " Data:" +m.myData); } catch (Exception e) { e.printStackTrace(); } } } Using UID with Entry objectsYou can get the Entry's UID from the Entry lease object. See the example below: Message o = new Message ("A"); Lease lease = space.write(o, null, Lease.FOREVER); LeaseProxy lp = (LeaseProxy) lease; String uid = lp.getUID(); In situations where you do not have the Entry lease object (like when using the read operation), you need to get it from the Entry object. In order to access the Entry's UID from the Entry object, you need to add two methods to the class implementation, with the following signatures: public void __setEntryUID(String inUid) public String __getEntryUID() The example below describes how these methods should be implemented. package helloworld; import net.jini.core.entry.entry; public class Message implements entry { public String content; transient public String mUID; public Message() {} public void __setEntryUID(String inUid) { this.mUID = inUid; } public String __getEntryUID() { return mUID; } public Message(String content) { this.content = content; } } The Entry class should have an attribute that will store the UID. transient public String mUID; This attribute's data should not be stored as part of the Entry's attributes in the space, so it should be a transient type. The __setEntryUID method is called internally by the GigaSpaces when the Entry is materialized at the client side injecting the Entry UID value into the relevant field. You can access the injected UID using the __getEntryUID method: Message myobj =(Message) space.read(template, null, JavaSpace.NO_WAIT); String uid = myobj.__getEntryUID(); The example below reads the Entry using its UID: Message templateUID = new Message (); templateUID.__setEntryUID(uid); //Reading entry using its ID Message m = (Message) space.read(templateUID,null,JavaSpace.NO_WAIT);
Reading or Taking Multiple Entries using UIDsYou can read or take multiple Entries from the space using their UIDs, in one space operation. You should construct an ExternalEntry template that includes only an array of the Entry's UID, and use this template with the readMultiple operation. See the example below: The Entry Class: public class MyEntry extends MetaDataEntry{ public MyEntry (){} public MyEntry (int num) { this.attr1 = "attr1 " + num; this.attr2 = "attr2 " + num; } public String attr1; public String attr2; public String toString() { return "UID:" + __getEntryInfo().m_UID + " attr1:" + attr1 + " attr2:"+ attr2; } } The Application code: IJSpace space = (IJSpace )SpaceFinder.find("/./mySpace"); String uid[] = new String[10]; for (int i=0; i<10 ;i++ ) { uid[i] = ClientUIDHandler.createUIDFromName(i , MyEntry.class.getName()); MyEntry entry = new MyEntry(i); entry.__setEntryInfo(new EntryInfo(uid[i],0)); space.write(entry , null ,Lease.FOREVER ); } ExternalEntry multiUIDtemplate = new ExternalEntry(uid); Entry[] result = space.readMultiple(multiUIDtemplate , null , Integer.MAX_VALUE); for (int i=0; i<result.length ;i++ ) { ExternalEntry ee = (ExternalEntry)result[i]; System.out.println(ee.getEntry(space)); } Lazy LoadingBy using the ExternalEntry, you can query the space and get only the UIDs of the matching Entries. In a later phase you may retrieve the relevant Entries by reading the Entries using their UIDs. The example below illustrates lazy loading using ExternalEntry. This example creates a template Entry based on ExternalEntry where the matching Entries are all Message class instances and Message subclasses instances.
The readMultiple method returns an Array where its first (and only element) m_MultipleUIDs attribute holds all relevant Entries' UIDs. The Entries themselves can be read using the read API by creating a template Entry that contains only its UID. This is done by calling the __setEntryUID method that internally signals to the GigaSpaces Platform to locate and read this object using its UID and not by its matching attribute values. String classname = Message.class.getName(); ExternalEntry ex = new ExternalEntry (classname, null, null); ex.setReturnOnlyUids(true); Entry[] result = space.readMultiple(ex, null, Integer.MAX_VALUE); // Getting the first ExternalEntry from the readMultiple returned array // The first entry - resultUIDs.m_MultipleUIDs - holds matching UIDs ExternalEntry resUIDs = (ExternalEntry )result[0]; int max = resultUIDs.m_MultipleUIDs.length; for (int i=0;i<max;i++ ) { Message temp = new Message (); temp.__setEntryUID(resultUIDs.m_MultipleUIDs[i]); //Reading entry using its ID Message m = (Message) space.read(temp, null, JavaSpace.NO_WAIT); System.out.println(m); } Parent-ChildIn some cases, you might want to store Entries that include refereces to other space Entries in the space – i.e. an object graph. The example code below demonstrates usage of UID operations. The example writes 10 parent-child graphs into the space. Two types of graphs exist in the example:
This eventually returns the 5 first graphs. Full example source code can be downloaded here. Child class: Child package com.j_spaces.examples.parentchild; import com.j_spaces.core.client.ClientUIDHandler; import com.j_spaces.core.client.EntryInfo; import com.j_spaces.core.client.MetaDataEntry; public class Child extends MetaDataEntry{ public Child(){} public Child(String id, String parentUID) { String uid =ClientUIDHandler.createUIDFromName(id, this.getClass().getName()); __setEntryInfo(new EntryInfo(uid,0)); this.parentUID = parentUID; this.id = id; } public String parentUID; public Long field; public String id; public static String[] __getSpaceIndexedFields() { String[] indexedFields = { "parentUID", "field" }; return indexedFields; } public String toString() { return "UID:" + __getEntryInfo().m_UID + " id:" + id + " value:" + field; } } Parent class: Parent package com.j_spaces.examples.parentchild; import java.rmi.RemoteException; import net.jini.core.entry.Entry; import net.jini.core.entry.UnusableEntryException; import net.jini.core.transaction.TransactionException; import com.j_spaces.core.IJSpace; import com.j_spaces.core.client.ClientUIDHandler; import com.j_spaces.core.client.EntryInfo; import com.j_spaces.core.client.ExternalEntry; import com.j_spaces.core.client.MetaDataEntry; public class Parent extends MetaDataEntry { public Parent() { } public Parent(int id) { String uid = ClientUIDHandler.createUIDFromName(id, this.getClass() .getName()); __setEntryInfo(new EntryInfo(uid, 0)); } public String childs_uid[]; transient Child childs[]; public Long field; public String getChildsDetails(IJSpace space) throws RemoteException, TransactionException, UnusableEntryException { String ret=""; Child[] childs = getChilds(space); for (int i=0;i<childs.length ; i++) { ret = ret + childs[i].toString() + "\n"; } return ret; } public Child[] getChilds(IJSpace space) throws RemoteException, TransactionException, UnusableEntryException { if (childs == null) { ExternalEntry templateUIDs = new ExternalEntry (childs_uid); Entry results[] = space.readMultiple(templateUIDs , null , Integer.MAX_VALUE); childs = new Child[results.length]; for (int i=0;i<results.length ; i++) { childs [i] =(Child) ((ExternalEntry) results[i]).getEntry(space); } } return childs; } public String getChildUID() { String res =""; for (int i=0 ; i< childs_uid.length; i++) { res =res +childs_uid[i] + "\n"; } return res; } public static String[] __getSpaceIndexedFields() { String[] indexedFields = { "field"}; return indexedFields; } } Application: Application package com.j_spaces.examples.parentchild; import java.rmi.RemoteException; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import net.jini.core.entry.Entry; import net.jini.core.entry.UnusableEntryException; import net.jini.core.lease.Lease; import net.jini.core.transaction.TransactionException; import com.j_spaces.core.IJSpace; import com.j_spaces.core.client.ExternalEntry; import com.j_spaces.core.client.SpaceFinder; public class ParentChildMain { static IJSpace space; public static void main(String[] args) { try { space = (IJSpace) SpaceFinder.find("/./myCache?schema=cache"); System.out.println("Write 10 parent/child graphs.\nWe will have 2 types of graphs:" + "\n5 graphs having the following values for the child objects: 0,1,2,3,4,5,6,7,8,9" + "\nand another 5 graphs with the following values for the child objects:0,10,20,30,40,50,60,70,80,90"); for (int i = 0; i < 10; i++) { Parent parent = new Parent(i); Child childs[] = new Child[10]; parent.childs_uid = new String[10]; for (int j = 0; j < 10; j++) { childs[j] = new Child(i + "_" + j, parent.__getEntryInfo().m_UID); if (i% 2 ==0) childs[j].field = new Long(j); else childs[j].field = new Long(j * 10); parent.childs_uid[j] = childs[j].__getEntryInfo().m_UID; } space.write(parent, null, Lease.FOREVER); space.writeMultiple(childs, null, Lease.FOREVER); } System.out.println("Lets find all the parent object having 2 child object with values 1 and 2 - effectively join"); System.out.println("We need to make sure that both child objects have the same parent"); Entry childs_results1[] = getChildsbyValue(new Long(1)); Set set1 = getParentUIDsSet(childs_results1); Entry childs_results2[] = getChildsbyValue(new Long(2)); Set set2 = getParentUIDsSet(childs_results2); Set resultSet = AND(set1 , set2); Parent parents[] = getParentsfromUIDs(resultSet); System.out.println("Found " + parents.length +" matching Parent objects" ); for (int i = 0; i < parents.length; i++) { System.out.println("Found Parent Object:" + parents[i] + " - UID:" + parents[i].__getEntryInfo().m_UID + " His childs are:\n" + parents[i].getChildsDetails(space)); } } catch (Exception e) { e.printStackTrace(); } } static public Entry[] getChildsbyValue(Long value) throws RemoteException, TransactionException, UnusableEntryException { Child child_template = new Child(); child_template.field = value; return space.readMultiple(child_template, null,Integer.MAX_VALUE); } static public Set getParentUIDsSet(Entry entries[]) { HashSet result = new HashSet(); for (int i = 0; i < entries.length; i++) { result.add(((Child) entries[i]).parentUID); } return result; } static public Parent[] getParentsfromUIDs(Set uids) throws UnusableEntryException, RemoteException, TransactionException { Parent[] ret = null; String uids_str[] = new String [uids.size()]; System.arraycopy(uids.toArray(),0,uids_str,0,uids_str.length); ExternalEntry child_uids_template = new ExternalEntry(uids_str); Entry childs_result[] = space.readMultiple(child_uids_template,null, Integer.MAX_VALUE); ret = new Parent[childs_result.length]; for (int i=0;i<childs_result.length ; i++) { ret[i] = (Parent) ((ExternalEntry)childs_result[i]).getEntry(space); } return ret; } // find intersection between 2 sets with UIDs static public Set AND(Set set1, Set set2) { HashSet result = new HashSet(); Iterator keys = set1.iterator(); while (keys.hasNext()) { String key = (String) keys.next(); if (set2.contains(key)) { result.add(key); } } return result; } } Expected output: Write 10 parent/child graphs. We will have 2 types of graphs: 5 graphs having the following values for the child objects:0,1,2,3,4,5,6,7,8,9 and another 5 graphs with the following values for the child objects:0,10,20,30,40,50,60,70,80,90 Lets find all the parent object having 2 child object with values 1 and 2 - effectively join We need to make sure that both child objects have the same parent Found 5 matching Parent objects Found Parent Object:com.j_spaces.examples.parentchild.Parent@c954e - UID:-395274420^40^0^0^0 His childs are: UID:-578745798^39^0_0^0^0 id:0_0 value:0 UID:-578745798^39^0_1^0^0 id:0_1 value:1 UID:-578745798^39^0_2^0^0 id:0_2 value:2 UID:-578745798^39^0_3^0^0 id:0_3 value:3 UID:-578745798^39^0_4^0^0 id:0_4 value:4 UID:-578745798^39^0_5^0^0 id:0_5 value:5 UID:-578745798^39^0_6^0^0 id:0_6 value:6 UID:-578745798^39^0_7^0^0 id:0_7 value:7 UID:-578745798^39^0_8^0^0 id:0_8 value:8 UID:-578745798^39^0_9^0^0 id:0_9 value:9 Found Parent Object:com.j_spaces.examples.parentchild.Parent@39452f - UID:-395274420^40^8^0^0 His childs are: UID:-578745798^39^8_0^0^0 id:8_0 value:0 UID:-578745798^39^8_1^0^0 id:8_1 value:1 UID:-578745798^39^8_2^0^0 id:8_2 value:2 UID:-578745798^39^8_3^0^0 id:8_3 value:3 UID:-578745798^39^8_4^0^0 id:8_4 value:4 UID:-578745798^39^8_5^0^0 id:8_5 value:5 UID:-578745798^39^8_6^0^0 id:8_6 value:6 UID:-578745798^39^8_7^0^0 id:8_7 value:7 UID:-578745798^39^8_8^0^0 id:8_8 value:8 UID:-578745798^39^8_9^0^0 id:8_9 value:9 Found Parent Object:com.j_spaces.examples.parentchild.Parent@1ed13da - UID:-395274420^40^4^0^0 His childs are: UID:-578745798^39^4_0^0^0 id:4_0 value:0 UID:-578745798^39^4_1^0^0 id:4_1 value:1 UID:-578745798^39^4_2^0^0 id:4_2 value:2 UID:-578745798^39^4_3^0^0 id:4_3 value:3 UID:-578745798^39^4_4^0^0 id:4_4 value:4 UID:-578745798^39^4_5^0^0 id:4_5 value:5 UID:-578745798^39^4_6^0^0 id:4_6 value:6 UID:-578745798^39^4_7^0^0 id:4_7 value:7 UID:-578745798^39^4_8^0^0 id:4_8 value:8 UID:-578745798^39^4_9^0^0 id:4_9 value:9 Found Parent Object:com.j_spaces.examples.parentchild.Parent@1b25a82 - UID:-395274420^40^2^0^0 His childs are: UID:-578745798^39^2_0^0^0 id:2_0 value:0 UID:-578745798^39^2_1^0^0 id:2_1 value:1 UID:-578745798^39^2_2^0^0 id:2_2 value:2 UID:-578745798^39^2_3^0^0 id:2_3 value:3 UID:-578745798^39^2_4^0^0 id:2_4 value:4 UID:-578745798^39^2_5^0^0 id:2_5 value:5 UID:-578745798^39^2_6^0^0 id:2_6 value:6 UID:-578745798^39^2_7^0^0 id:2_7 value:7 UID:-578745798^39^2_8^0^0 id:2_8 value:8 UID:-578745798^39^2_9^0^0 id:2_9 value:9 Found Parent Object:com.j_spaces.examples.parentchild.Parent@541b02 - UID:-395274420^40^6^0^0 His childs are: UID:-578745798^39^6_0^0^0 id:6_0 value:0 UID:-578745798^39^6_1^0^0 id:6_1 value:1 UID:-578745798^39^6_2^0^0 id:6_2 value:2 UID:-578745798^39^6_3^0^0 id:6_3 value:3 UID:-578745798^39^6_4^0^0 id:6_4 value:4 UID:-578745798^39^6_5^0^0 id:6_5 value:5 UID:-578745798^39^6_6^0^0 id:6_6 value:6 UID:-578745798^39^6_7^0^0 id:6_7 value:7 UID:-578745798^39^6_8^0^0 id:6_8 value:8 UID:-578745798^39^6_9^0^0 id:6_9 value:9 |
Wiki Content Tree
Your Feedback Needed!
We need your help to improve this wiki site. If you have any suggestions or corrections, write to us at techw@gigaspaces.com. Please provide a link to the wiki page you are referring to.
Add Comment