In prefetch analysis:
authoradash <adash>
Sat, 15 Dec 2007 01:06:00 +0000 (01:06 +0000)
committeradash <adash>
Sat, 15 Dec 2007 01:06:00 +0000 (01:06 +0000)
 a) deleted the shorter subset prefetch pairs from the prefetch set for a given
 FlatNode
 b) deleted prefetch pairs generating NULL pointer in C code

 In Runtime:
  Added support for prefetching arrays

Robust/src/Analysis/Prefetch/IndexDescriptor.java
Robust/src/Analysis/Prefetch/PrefetchAnalysis.java
Robust/src/Runtime/DSTM/interface/dstm.h
Robust/src/Runtime/DSTM/interface/dstmserver.c
Robust/src/Runtime/DSTM/interface/trans.c

index 97a9158b393cc08da3b153478bc883b0759b93b7..78d3c316134b99489af1d6352f78c221bec251de 100644 (file)
@@ -91,7 +91,7 @@ public class IndexDescriptor extends Descriptor {
        public boolean equals(Object o) {
                if(o instanceof IndexDescriptor) {
                        IndexDescriptor idesc = (IndexDescriptor) o;
-                       if(!offset.equals(idesc.offset)) {
+                       if(!(offset.equals(idesc.offset))) {
                                return false;
                        }
                        if(tddesc == null && idesc.tddesc == null) {
index 94210be7076866e2b05046d692d854e124d48b2b..4b649a8e06552432b799326cda4c87d9626d1373 100644 (file)
@@ -115,7 +115,6 @@ public class PrefetchAnalysis {
                        if(newprefetchset.size() > 0) {
                                addFlatPrefetchNode(newprefetchset);
                        }
-                       //printMethod(fm);
                }
        }
 
@@ -508,7 +507,7 @@ public class PrefetchAnalysis {
                        childpp = (PrefetchPair) ecld.nextElement();
                        if(childpp.base == currfsfn.getDst()) {
                                int size = childpp.desc.size();
-                               if(size >=2) {
+                               if(size >=2) { /*e.g. x.f = g (with child prefetches x.f.g, x.f[0].j) */
                                        if((childpp.getDescAt(0) instanceof FieldDescriptor) && (childpp.getDescAt(0) == currfsfn.getField())) { 
                                                ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
                                                for(int i = 0;i<(childpp.desc.size()-1); i++) {
@@ -532,7 +531,7 @@ public class PrefetchAnalysis {
                                                        child_prefetch_set_copy.remove(newpp);
                                                }
                                        }
-                               } else if(size==1) {
+                               } else if(size==1) { /* e.g x.f = g (with child prefetch x.f) */
                                        if((childpp.getDescAt(0) instanceof FieldDescriptor) && (childpp.getDescAt(0) == currfsfn.getField())) {
                                                child_prefetch_set_copy.remove(childpp);
                                        }
@@ -569,7 +568,7 @@ public class PrefetchAnalysis {
                } 
        }
 
-       /** This function processes the prefetch set of a FlatSeElementNode
+       /** This function processes the prefetch set of a FlatSetElementNode
         * It generates a new prefetch set after comparision with its children
         * It compares the old prefetch set with this new prefetch set and enqueues the parents 
         * of the current node if change occurs and then updates the global flatnode hash table
@@ -589,8 +588,9 @@ public class PrefetchAnalysis {
                                int sizedesc = childpp.desc.size();
                                if((childpp.getDescAt(0) instanceof IndexDescriptor)) {
                                        int sizetempdesc = ((IndexDescriptor)(childpp.getDescAt(0))).tddesc.size();
-                                       if(sizetempdesc == 1) {
+                                       if(sizetempdesc == 1) { 
                                                if((((IndexDescriptor)childpp.getDescAt(0)).tddesc.get(0) == currfsen.getIndex()) && (sizedesc>=2)) {
+                                                       /* For e.g. a[i] = g with child prefetch set a[i].r or a[i].r.f */
                                                        ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
                                                        for(int i = 0;i<(childpp.desc.size()-1); i++) {
                                                                newdesc.add(i,childpp.desc.get(i+1));
@@ -612,6 +612,7 @@ public class PrefetchAnalysis {
                                                                child_prefetch_set_copy.remove(newpp);
                                                        }
                                                } else if((((IndexDescriptor)childpp.getDescAt(0)).tddesc.get(0) == currfsen.getIndex()) && (sizedesc==1)) 
+                                                       /* For e.g. a[i] = g with child prefetch set a[i] */
                                                        child_prefetch_set_copy.remove(childpp);
                                        } else {
                                                continue;
@@ -665,7 +666,7 @@ public class PrefetchAnalysis {
                                childpp = (PrefetchPair) ecld.nextElement();
                                PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
 
-                               /* For cases like x=y followed by childnode t=x[i].z or t=x.g*/
+                               /* For cases like x=y  with child prefetch set x[i].z,x.g*/
                                if(childpp.base == currfopn.getDest()) {
                                        ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
                                        newdesc.addAll(childpp.desc);
@@ -685,7 +686,7 @@ public class PrefetchAnalysis {
                                                }
                                                child_prefetch_set_copy.remove(newpp);
                                        }
-                                       /* For cases like x=y followed by t = r[i].x or t =r[x].p or t = r[p+x].q*/
+                                       /* For cases like x=y  with child prefetch set r[i].x, r[x].p, r[p+x].q*/
                                } else if(isTempDescFound(copyofchildpp, currfopn.getDest())) {
                                        ArrayList<Descriptor> newdesc = new ArrayList<Descriptor>();
                                        newdesc.addAll((ArrayList<Descriptor>)getNewDesc(copyofchildpp, currfopn.getDest(), currfopn.getLeft()));
@@ -709,7 +710,7 @@ public class PrefetchAnalysis {
                                        continue;
                                }
                        }
-                       //case i = i+z  followed by a[i].x
+                       //case i = i+z with child prefetch set a[i].x
                } else if(currfopn.getRight()!=null && (currfopn.getOp().getOp() == Operation.ADD)) {
                        ecld = child_prefetch_set_copy.keys();
                        while (ecld.hasMoreElements()) {
@@ -771,7 +772,7 @@ public class PrefetchAnalysis {
        }
 
        /** This function processes a FlatLiteralNode where cases such as
-        * for cases like i = 0 followed by t = a[i].r or t = a[j+i].r or t = a[j].b[i].r
+        * for e.g. i = 0 with child prefetch sets a[i].r, a[j+i].r or a[j].b[i].r
         * are handled */
        private void processFlatLiteralNode(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
                        Hashtable<FlatNode, PairMap> parentpmap) {
@@ -787,7 +788,6 @@ public class PrefetchAnalysis {
                        while (ecld.hasMoreElements()) {
                                childpp = (PrefetchPair) ecld.nextElement();
                                PrefetchPair copyofchildpp = (PrefetchPair) childpp.clone();
-                               /* For cases like i = 0 followed by t = a[i].r or t = a[j+i].r or t = a[j].b[i].r*/
                                if(isTempDescFound(copyofchildpp,currfln.getDst())) {
                                        ArrayList<Descriptor> copychilddesc = (ArrayList<Descriptor>) copyofchildpp.getDesc();
                                        int sizetempdesc = copychilddesc.size();
@@ -889,8 +889,8 @@ public class PrefetchAnalysis {
        }
 
        /** This Function processes the FlatCalls 
-        * It currently drops the propagation of those prefetchpairs that are passed as
-        * arguments in the FlatCall 
+        * It currently drops the propagation of those prefetchpairs whose base is
+        * same as the destination of the FlatCall 
         */
        private void processFlatCall(FlatNode curr, Hashtable<PrefetchPair, Float> child_prefetch_set_copy,
                        Hashtable<FlatNode, PairMap> parentpmap) {
@@ -1226,13 +1226,83 @@ public class PrefetchAnalysis {
                        }
                }
 
+               delSubsetPPairs();
+       
+               /* Start with a top down sorted order of nodes */
                while(!newvisited.isEmpty()) {
                        applyPrefetchInsertRules((FlatNode) newvisited.getFirst());
                        newvisited.remove(0);
                }
        }
 
+       private void delSubsetPPairs() {
+               Enumeration e = prefetch_hash.keys();
+               while(e.hasMoreElements()) {
+                       FlatNode fn = (FlatNode) e.nextElement();
+                       Hashtable ppairs = prefetch_hash.get(fn);
+                       Enumeration epp = ((Hashtable)(prefetch_hash.get(fn))).keys();
+                       Vector<PrefetchPair> pplist = new Vector<PrefetchPair>();
+                       Vector pplength = new Vector();
+                       Vector ppisMod = new Vector();
+                       while(epp.hasMoreElements()) {
+                               PrefetchPair pp = (PrefetchPair) epp.nextElement();
+                               pplist.add(pp);
+                               int length = pp.desc.size()+ 1;
+                               pplength.add(length);
+                               ppisMod.add(0);
+                       }
+                       int numpp = ((Hashtable)(prefetch_hash.get(fn))).size();
+                       for (int i = 0; i < numpp; i++) {
+                               for (int j = i+1; j < numpp; j++) {
+                                       boolean ret;
+                                       int x = ((Integer) (pplength.get(i))).intValue();
+                                       if (((Integer) (pplength.get(i))).intValue() < ((Integer)( pplength.get(j))).intValue()) {
+                                               ret = isSubSet(pplist.get(i), pplist.get(j));
+                                               if (ret) {
+                                                       ppisMod.set(i, 1);
+                                               }
+                                       } else {
+                                               ret = isSubSet(pplist.get(j), pplist.get(i));
+                                               if (ret) {
+                                                       ppisMod.set(j, 1);
+                                               }
+                                       }
+                               }
+                       }
+                       for (int i = 0; i < numpp; i++) {
+                               if (((Integer)(ppisMod.get(i))).intValue() == 1) {
+                                       PrefetchPair pp = (PrefetchPair) pplist.get(i);
+                                       ppairs.remove(pp);
+                               }
+                       }
+               }
+       }
 
+       private boolean isSubSet(PrefetchPair shrt, PrefetchPair lng) {
+               if (shrt.base != lng.base) {
+                       return false;
+               }
+               for (int j = 0; j < shrt.desc.size(); j++) {
+                       if(shrt.getDescAt(j) instanceof IndexDescriptor) {
+                               IndexDescriptor shrtid = (IndexDescriptor) shrt.getDescAt(j);
+                               if(lng.getDescAt(j) instanceof IndexDescriptor){
+                                       IndexDescriptor lngid = (IndexDescriptor) lng.getDescAt(j);
+                                       if(shrtid.equals(lngid)) {
+                                               continue;
+                                       } else {
+                                               return false;
+                                       }
+                               } else {
+                                       return false;
+                               }
+                       } else  {
+                               if ((Descriptor)shrt.getDescAt(j) != (Descriptor)lng.getDescAt(j)){
+                                       return false;
+                               }
+                       }
+               }
+               return true;
+       }
 
        /**This function compares all the prefetch pairs in a Prefetch set hashtable and
         * returns: true if something has changed in the new Prefetch set else
@@ -1385,11 +1455,11 @@ public class PrefetchAnalysis {
                }
        }
 
-
        private void addFlatPrefetchNode(Hashtable<FlatNode, HashSet<PrefetchPair>> newprefetchset) {
                int i;
                Enumeration e = null;
                e = newprefetchset.keys();
+               boolean isFNPresent = false; /* Detects presence of FlatNew node */
                /* This modifies the graph */
                while(e.hasMoreElements()) {
                        FlatNode fn = (FlatNode) e.nextElement();
@@ -1397,21 +1467,31 @@ public class PrefetchAnalysis {
                        for(i = 0; i< newprefetchset.get(fn).size(); i++) {
                                fpn.insAllpp((HashSet)newprefetchset.get(fn));
                        }
-                       //System.out.println("The HashSet of prefetch pairs are "+ fpn.getPrefetchPairs());
                        if(fn.kind() == FKind.FlatMethod) {
                                FlatNode nn = fn.getNext(0);
                                fn.setNext(0, fpn);
                                fpn.addNext(nn);
                        } else {
-                               while(fn.numPrev() > 0) {
-                                       FlatNode nn = fn.getPrev(0);
-                                       for(int j = 0; j<nn.numNext(); j++) {
-                                               if(nn.getNext(j) == fn) {
-                                                       nn.setNext(j, fpn);
+                               /* Check if previous node of this FlatNode is a NEW node 
+                                * If yes, delete this flatnode and its prefetch set from hash table 
+                                * This eliminates prefetches for NULL ptrs*/
+                               for(i = 0; i< fn.numPrev(); i++) {
+                                       FlatNode nn = fn.getPrev(i);
+                                       if(nn.kind() == FKind.FlatNew) {
+                                               isFNPresent = true;
+                                       }
+                               }
+                               if(!isFNPresent) {
+                                       while(fn.numPrev() > 0) {
+                                               FlatNode nn = fn.getPrev(0);
+                                               for(int j = 0; j<nn.numNext(); j++) {
+                                                       if(nn.getNext(j) == fn) {
+                                                               nn.setNext(j, fpn);
+                                                       }
                                                }
                                        }
+                                       fpn.addNext(fn);
                                }
-                               fpn.addNext(fn);
                        }
                }
        }
index ede8fdda9e2da582707a46beda70dc8d9e168c93..99a21fbd347aa643363a901748cd7de8d1141b31 100644 (file)
@@ -240,7 +240,7 @@ void *mcqProcess(void *);
 void checkPrefetchTuples(prefetchqelem_t *);
 prefetchpile_t *foundLocal(prefetchqelem_t *);
 prefetchpile_t *makePreGroups(prefetchqelem_t *, int *);
-void checkPreCache(prefetchqelem_t *, int *, int, int, unsigned int, int, int, int);
+void checkPreCache(prefetchqelem_t *, int *, unsigned int, int);
 int transPrefetchProcess(transrecord_t *, int **, short);
 void sendPrefetchReq(prefetchpile_t*, int);
 void getPrefetchResponse(int, int);
index 00b54b0be5cd51f740d1b89102902eff30ab7e43..11d2507f4586c4b60c270dc694f0ad259834e7a0 100644 (file)
@@ -594,6 +594,7 @@ int transCommitProcess(void *modptr, unsigned int *oidmod, unsigned int *oidlock
 
 int prefetchReq(int acceptfd) {
   int i, length, sum, n, numbytes, numoffset, N, objnotfound = 0, size, count = 0;
+  int isArray = 0;
   unsigned int oid, index = 0;
   char *ptr, buffer[PRE_BUF_SIZE];
   void *mobj;
@@ -648,28 +649,38 @@ int prefetchReq(int acceptfd) {
       index += size;
       /* Calculate the oid corresponding to the offset value */
       for(i = 0 ; i< numoffset ; i++) {
-       objoid = *((int *)(((char *)header) + sizeof(objheader_t) + offset[i]));
-       if((header = mhashSearch(objoid)) == NULL) {
-         /* Obj not found, send oid */
-         *(buffer + index) = OBJECT_NOT_FOUND;
-         index += sizeof(char);
-         memcpy(buffer+index, &oid, sizeof(unsigned int));
-         index += sizeof(unsigned int);
-         break;
-       } else {/* Obj Found */
-         /* send the oid, it's size, it's header and data */
-         GETSIZE(size, header);
-         size+=sizeof(objheader_t);
-         *(buffer + index) = OBJECT_FOUND;
-         index += sizeof(char);
-         memcpy(buffer+index, &oid, sizeof(unsigned int));
-         index += sizeof(unsigned int);
-         memcpy(buffer+index, &size, sizeof(int));
-         index += sizeof(int);
-         memcpy(buffer + index, header, size);
-         index += size;
-         continue;
-       }
+             /* Check for arrays  */
+             if(TYPE(header) > NUMCLASSES) {
+                     isArray = 1;
+             }
+             if(isArray == 1) {
+                     int elementsize = classsize[TYPE(header)];
+                     objoid = *((unsigned int *)(((char *)header) + sizeof(objheader_t) + sizeof(struct ArrayObject) + (elementsize*offset[i])));
+             } else {
+                     objoid = *((unsigned int *)(((char *)header) + sizeof(objheader_t) + offset[i]));
+             }
+             if((header = mhashSearch(objoid)) == NULL) {
+                     /* Obj not found, send oid */
+                     *(buffer + index) = OBJECT_NOT_FOUND;
+                     index += sizeof(char);
+                     memcpy(buffer+index, &oid, sizeof(unsigned int));
+                     index += sizeof(unsigned int);
+                     break;
+             } else {/* Obj Found */
+                     /* send the oid, it's size, it's header and data */
+                     GETSIZE(size, header);
+                     size+=sizeof(objheader_t);
+                     *(buffer + index) = OBJECT_FOUND;
+                     index += sizeof(char);
+                     memcpy(buffer+index, &oid, sizeof(unsigned int));
+                     index += sizeof(unsigned int);
+                     memcpy(buffer+index, &size, sizeof(int));
+                     index += sizeof(int);
+                     memcpy(buffer+index, header, size);
+                     index += size;
+                     isArray = 0;
+                     continue;
+             }
       }
     }
     /* Check for overflow in the buffer */
index 65e48e527a19904a004a4e37d4a88f2a31d0d7fe..c65127f59eae94ed1459ad885d48717add9df7df 100644 (file)
@@ -315,7 +315,7 @@ objheader_t *transRead(transrecord_t *record, unsigned int oid) {
                                return objcopy;
 #endif
                        } else if (rc == ETIMEDOUT) {
-//                                     printf("Wait timed out\n");
+                                       printf("Wait timed out\n");
                                        pthread_mutex_unlock(&pflookup.lock);
                                        break;
                        }
@@ -1127,26 +1127,17 @@ void checkPrefetchTuples(prefetchqelem_t *node) {
 
                                if(i == 0) {
                                        k = 0;
-                                       index = endoffsets[j -1];
-                                       for(count = 0; count < slength; count ++) {
-                                               if (arryfields[k] != arryfields[index]) { 
-                                                       break;
-                                               }
-                                               index++;
-                                               k++;
-                                       }       
                                } else {
                                        k = endoffsets[i-1];
-                                       index = endoffsets[j-1];
-                                       for(count = 0; count < slength; count++) {
-                                               if(arryfields[k] != arryfields[index]) {
-                                                       break;
-                                               }
-                                               index++;
-                                               k++;
-                                       }
                                }
-
+                               index = endoffsets[j -1];
+                               for(count = 0; count < slength; count ++) {
+                                       if (arryfields[k] != arryfields[index]) { 
+                                               break;
+                                       }
+                                       index++;
+                                       k++;
+                               }       
                                if(slength == count) {
                                        oid[sindex] = 0;
                                }
@@ -1154,66 +1145,6 @@ void checkPrefetchTuples(prefetchqelem_t *node) {
                }
        }
 }
-
-void checkPreCache(prefetchqelem_t *node, int *numoffset, int counter, int loopcount, unsigned int objoid, int index, int iter, int oidnfound) {
-       char *ptr, *tmp;
-       int ntuples, i, k, flag;
-       unsigned int * oid;
-       short *endoffsets, *arryfields;
-       objheader_t *header;
-
-       ptr = (char *) node;
-       ntuples = *(GET_NTUPLES(ptr));
-       oid = GET_PTR_OID(ptr);
-       endoffsets = GET_PTR_EOFF(ptr, ntuples);
-       arryfields = GET_PTR_ARRYFLD(ptr, ntuples);
-
-       if(oidnfound == 1) {
-               if((header = (objheader_t *) prehashSearch(objoid)) == NULL) {
-                       return;
-               } else { //Found in Prefetch Cache
-                       //TODO Decide if object is too old, if old remove from cache
-                       tmp = (char *) header;
-                       /* Check if any of the offset oid is available in the Prefetch cache */
-                       for(i = counter; i < loopcount; i++) {
-                               objoid = *(tmp + sizeof(objheader_t) + arryfields[counter]);
-                               if((header = (objheader_t *)prehashSearch(objoid)) != NULL) {
-                                       flag = 0;
-                               } else {
-                                       flag = 1;
-                                       break;
-                               }
-                       }
-               }
-       } else {
-               for(i = counter; i<loopcount; i++) {
-                       if((header = (objheader_t *)prehashSearch(objoid)) != NULL) {
-                               tmp = (char *) header;
-                               objoid = *(tmp + sizeof(objheader_t) + arryfields[index]);
-                               flag = 0;
-                               index++;
-                       } else {
-                               flag = 1;
-                               break;
-                       }
-               }
-       }
-
-       /* If oid not found locally or in prefetch cache then 
-        * assign the latest oid found as the new oid 
-        * and copy left over offsets into the arrayoffsetfieldarray*/
-       oid[iter] = objoid;
-       numoffset[iter] = numoffset[iter] - (i+1);
-       for(k = 0; k < numoffset[iter] ; k++) {
-               arryfields[endoffsets[counter]+k] = arryfields[endoffsets[counter]+k+1];
-       }
-
-       if(flag == 0) {
-               oid[iter] = 0;
-               numoffset[iter] = 0;
-       }
-}
-
 /* This function makes machine piles to be added into the machine pile queue for each prefetch call */
 prefetchpile_t *makePreGroups(prefetchqelem_t *node, int *numoffset) {
        char *ptr, *tmp;
@@ -1246,14 +1177,11 @@ prefetchpile_t *makePreGroups(prefetchqelem_t *node, int *numoffset) {
        return head;
 }
 
-
-/* This function checks if the oids within the prefetch tuples are available locally.
- * If yes then makes the tuple invalid. If no then rearranges oid and offset values in 
- * the prefetchqelem_t node to represent a new prefetch tuple */
 prefetchpile_t *foundLocal(prefetchqelem_t *node) {
-       int ntuples,i, j, k, oidnfound = 0, index, flag;
+       int ntuples,i, j, k, oidnfound = 0, arryfieldindex,nextarryfieldindex, flag = 0, val;
        unsigned int *oid;
        unsigned int  objoid;
+       int isArray = 0;
        char *ptr, *tmp;
        objheader_t *objheader;
        short *endoffsets, *arryfields; 
@@ -1271,45 +1199,77 @@ prefetchpile_t *foundLocal(prefetchqelem_t *node) {
                numoffset[i] = endoffsets[i] - endoffsets[i-1];
        }
        for(i = 0; i < ntuples; i++) { 
-               if(oid[i] == 0)
+               if(oid[i] == 0){
+                       if(i == 0) {
+                               arryfieldindex = 0;
+                               nextarryfieldindex =  endoffsets[0];
+                       }else {
+                               arryfieldindex = endoffsets[i-1];
+                               nextarryfieldindex =  endoffsets[i];
+                       }
+                       numoffset[i] = 0;
+                       endoffsets[0] = val = numoffset[0];
+                       for(k = 1; k < ntuples; k++) {
+                               val = val + numoffset[k];
+                               endoffsets[k] = val; 
+                       }
+                       
+                       for(k = 0; k<endoffsets[ntuples-1]; k++) {
+                               arryfields[arryfieldindex+k] = arryfields[nextarryfieldindex+k];
+                       }
                        continue;
+               }
                /* If object found locally */
                if((objheader = (objheader_t*) mhashSearch(oid[i])) != NULL) { 
-                       oidnfound = 0;
                        tmp = (char *) objheader;
-                       /* Find the oid of its offset value */
-                       if(i == 0) 
-                               index = 0;
-                       else 
-                               index = endoffsets[i - 1];
-                       for(j = 0 ; j < numoffset[i] ; j++) {
-                               objoid = *(tmp + sizeof(objheader_t) + arryfields[index]);
-                               /*If oid found locally then 
-                                *assign the latest oid found as the new oid 
-                                *and copy left over offsets into the arrayoffsetfieldarray*/
+                       int orgnumoffset = numoffset[i];
+                       if(i == 0) {
+                               arryfieldindex = 0;
+                       }else {
+                               arryfieldindex = endoffsets[i-1];
+                       }
+
+                       for(j = 0; j<orgnumoffset; j++) {
+                               /* Check for arrays  */
+                               if(TYPE(objheader) > NUMCLASSES) {
+                                       isArray = 1;
+                               }
+                               if(isArray == 1) {
+                                       int elementsize = classsize[TYPE(objheader)];
+                                       struct ArrayObject *ao = (struct ArrayObject *) (tmp + sizeof(objheader_t));
+                                       objoid = *((unsigned int *)(tmp + sizeof(objheader_t) + sizeof(struct ArrayObject) + (elementsize*arryfields[arryfieldindex])));
+                               } else {
+                                       objoid = *(tmp + sizeof(objheader_t) + arryfields[arryfieldindex]);
+                               }
+                               //Update numoffset array
+                               numoffset[i] = numoffset[i] - 1;
+                               //Update oid array
                                oid[i] = objoid;
-                               numoffset[i] = numoffset[i] - (j+1);
-                               for(k = 0; k < numoffset[i]; k++)
-                                       arryfields[endoffsets[j]+ k] = arryfields[endoffsets[j]+k+1];
-                               index++;
-                               /*New offset oid not found */
-                               if((objheader = (objheader_t*) mhashSearch(objoid)) == NULL) {
+                               //Update endoffset array
+                               endoffsets[0] = val = numoffset[0];
+                               for(k = 1; k < ntuples; k++) {
+                                       val = val + numoffset[k];
+                                       endoffsets[k] = val; 
+                               }
+                               //Update arrayfields array
+                               for(k = 0; k < endoffsets[ntuples-1]; k++) {
+                                       arryfields[arryfieldindex+k] = arryfields[arryfieldindex+k+1];
+                               }
+                               if((objheader = (objheader_t*) mhashSearch(oid[i])) == NULL) {
                                        flag = 1;
-                                       checkPreCache(node, numoffset, j, numoffset[i], objoid, index, i, oidnfound); 
+                                       checkPreCache(node, numoffset, oid[i], i); 
                                        break;
-                               } else 
-                                       flag = 0;
+                               }  
+                               tmp = (char *) objheader;
+                               isArray = 0;
                        }
-
                        /*If all offset oids are found locally,make the prefetch tuple invalid */
                        if(flag == 0) {
                                oid[i] = 0;
-                               numoffset[i] = 0;
                        }
                } else {
-                       oidnfound = 1;
                        /* Look in Prefetch cache */
-                       checkPreCache(node, numoffset, 0, numoffset[i], oid[i], 0, i, oidnfound); 
+                       checkPreCache(node, numoffset, oid[i],i); 
                }
 
        }
@@ -1318,6 +1278,72 @@ prefetchpile_t *foundLocal(prefetchqelem_t *node) {
        return head;
 }
 
+void checkPreCache(prefetchqelem_t *node, int *numoffset, unsigned int objoid, int index) {
+       char *ptr, *tmp;
+       int ntuples, i, k, flag=0, isArray =0, arryfieldindex, val;
+       unsigned int * oid;
+       short *endoffsets, *arryfields;
+       objheader_t *header;
+
+       ptr = (char *) node;
+       ntuples = *(GET_NTUPLES(ptr));
+       oid = GET_PTR_OID(ptr);
+       endoffsets = GET_PTR_EOFF(ptr, ntuples);
+       arryfields = GET_PTR_ARRYFLD(ptr, ntuples);
+
+       if((header = (objheader_t *) prehashSearch(objoid)) == NULL) {
+               return;
+       } else { //Found in Prefetch Cache
+               //TODO Decide if object is too old, if old remove from cache
+               tmp = (char *) header;
+               int loopcount = numoffset[index];       
+               if(index == 0)
+                       arryfieldindex = 0;
+               else
+                       arryfieldindex = endoffsets[(index - 1)];
+               // Check if any of the offset oid is available in the Prefetch cache
+               for(i = 0; i < loopcount; i++) {
+                       /* Check for arrays  */
+                       if(TYPE(header) > NUMCLASSES) {
+                               isArray = 1;
+                       }
+                       if(isArray == 1) {
+                               int elementsize = classsize[TYPE(header)];
+                               objoid = *((unsigned int *)(tmp + sizeof(objheader_t) + sizeof(struct ArrayObject) + (elementsize*arryfields[arryfieldindex])));
+                       } else {
+                               objoid = *(tmp + sizeof(objheader_t) + arryfields[arryfieldindex]);
+                       }
+                       //Update numoffset array
+                       numoffset[index] = numoffset[index] - 1;
+                       //Update oid array
+                       oid[index] = objoid;
+                       //Update endoffset array
+                       endoffsets[0] = val = numoffset[0];
+                       for(k = 1; k < ntuples; k++) {
+                               val = val + numoffset[k];
+                               endoffsets[k] = val; 
+                       }
+                       //Update arrayfields array
+                       for(k = 0; k < endoffsets[ntuples-1]; k++) {
+                               arryfields[arryfieldindex+k] = arryfields[arryfieldindex+k+1];
+                       }
+                       if((header = (objheader_t *)prehashSearch(oid[index])) != NULL) {
+                               tmp = (char *) header;
+                               isArray = 0;
+                       } else {
+                               flag = 1;
+                               break;
+                       }
+               }
+       }
+       //Found in the prefetch cache
+       if(flag == 0 && (numoffset[index] == 0)) {
+               oid[index] = 0;
+       }
+}
+
+
+
 /* This function is called by the thread calling transPrefetch */
 void *transPrefetch(void *t) {
        prefetchqelem_t *qnode;
@@ -1748,4 +1774,3 @@ int findHost(unsigned int hostIp)
        //not found
        return -1;
 }
-