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) {
if(newprefetchset.size() > 0) {
addFlatPrefetchNode(newprefetchset);
}
- //printMethod(fm);
}
}
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++) {
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);
}
}
}
- /** 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
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));
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;
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);
}
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()));
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()) {
}
/** 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) {
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();
}
/** 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) {
}
}
+ 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
}
}
-
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();
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);
}
}
}
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);
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;
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 */
return objcopy;
#endif
} else if (rc == ETIMEDOUT) {
-// printf("Wait timed out\n");
+ printf("Wait timed out\n");
pthread_mutex_unlock(&pflookup.lock);
break;
}
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;
}
}
}
}
-
-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;
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;
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);
}
}
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;
//not found
return -1;
}
-