1 #include "SimpleHash.h"
5 /* LINKED HASH NODE ****************************************************/
7 LinkedHashNode::LinkedHashNode(int key, int data, LinkedHashNode *next) {
15 LinkedHashNode::LinkedHashNode() {
23 /* SIMPLE LIST ****************************************************/
25 SimpleList::SimpleList() {
30 void SimpleList::reset() {
35 int SimpleList::hasMoreElements() {
37 return (ptr->next != 0);
40 int SimpleList::nextElement() {
44 //int data = ptr->data;
49 void SimpleList::add(int data) {
50 LinkedHashNode *cur = &head;
53 if (cur->data == data) {
54 return; // no duplicates
57 cur->next = new LinkedHashNode(0, data, 0);
61 int SimpleList::contains(int data) {
62 LinkedHashNode *cur = &head;
65 if (cur->data == data) {
72 /* WORK LIST ****************************************************/
74 WorkList::WorkList() {
75 head=(struct ListNode *) malloc(sizeof(struct ListNode));
82 void WorkList::reset() {
88 int WorkList::hasMoreElements() {
90 return ((head!=tail)||(headoffset!=tailoffset));
93 int WorkList::getid() {
94 return tail->data[tailoffset];
97 int WorkList::gettype() {
98 return tail->data[tailoffset+1];
101 int WorkList::getlvalue() {
102 return tail->data[tailoffset+2];
105 int WorkList::getrvalue() {
106 return tail->data[tailoffset+3];
109 WorkList::~WorkList() {
110 struct ListNode *ptr=tail;
112 struct ListNode *oldptr=ptr;
118 void WorkList::pop() {
119 int newoffset=tailoffset+4;
120 struct ListNode *ptr=tail;
121 if (newoffset>=WLISTSIZE) {
122 if (newoffset!=WLISTSIZE||head!=tail) {
123 newoffset-=WLISTSIZE;
124 struct ListNode *oldptr=ptr;
130 tailoffset=newoffset;
133 void WorkList::add(int id,int type, int lvalue, int rvalue) {
134 if (headoffset==WLISTSIZE) {
136 head->next=(struct ListNode *)malloc(sizeof(struct ListNode));
141 if (tailoffset==WLISTSIZE) { /* roll the tail over also */
146 head->data[headoffset++]=id;
147 head->data[headoffset++]=type;
148 head->data[headoffset++]=lvalue;
149 head->data[headoffset++]=rvalue;
152 /* SIMPLE HASH ********************************************************/
153 SimpleIterator* SimpleHash::iterator() {
154 return new SimpleIterator(listhead,listtail,tailindex/*,this*/);
157 void SimpleHash::iterator(SimpleIterator & it) {
161 it.tailindex=tailindex;
165 SimpleHash::SimpleHash(int size) {
167 throw SimpleHashException();
170 this->bucket = (struct SimpleNode **) calloc(sizeof(struct SimpleNode *)*size,1);
171 /* Set allocation blocks*/
172 this->listhead=(struct ArraySimple *) calloc(sizeof(struct ArraySimple),1);
173 this->listtail=this->listhead;
176 this->numparents = 0;
177 this->numchildren = 0;
178 this->numelements = 0;
181 SimpleHash::~SimpleHash() {
183 struct ArraySimple *ptr=listhead;
185 struct ArraySimple *next=ptr->nextarray;
191 int SimpleHash::firstkey() {
192 struct ArraySimple *ptr=listhead;
194 while((index==ARRAYSIZE)||!ptr->nodes[index].inuse) {
195 if (index==ARRAYSIZE) {
201 return ptr->nodes[index].key;
204 void SimpleHash::addParent(SimpleHash* parent) {
205 parents[numparents++] = parent;
206 parent->addChild(this);
209 void SimpleHash::addChild(SimpleHash *child) {
210 children[numchildren++]=child;
213 int SimpleHash::remove(int key, int data) {
214 unsigned int hashkey = (unsigned int)key % size;
216 struct SimpleNode **ptr = &bucket[hashkey];
218 for (int i = 0; i < numchildren; i++) {
219 children[i]->remove(key, data);
223 if ((*ptr)->key == key && (*ptr)->data == data) {
224 struct SimpleNode *toremove=*ptr;
227 toremove->inuse=0; /* Marked as unused */
232 ptr = &((*ptr)->next);
238 void SimpleHash::addAll(SimpleHash * set) {
241 while(it.hasNext()) {
248 int SimpleHash::add(int key, int data) {
250 if (numelements>=size) {
251 int newsize=2*size+1;
252 struct SimpleNode ** newbucket = (struct SimpleNode **) calloc(sizeof(struct SimpleNode *)*newsize,1);
253 for(int i=size-1;i>=0;i--) {
254 for(struct SimpleNode *ptr=bucket[i];ptr!=NULL;) {
255 struct SimpleNode * nextptr=ptr->next;
256 unsigned int newhashkey=(unsigned int)ptr->key % newsize;
257 ptr->next=newbucket[newhashkey];
258 newbucket[newhashkey]=ptr;
267 unsigned int hashkey = (unsigned int)key % size;
268 struct SimpleNode **ptr = &bucket[hashkey];
270 /* check that this key/object pair isn't already here */
271 /* TBD can be optimized for set v. relation */
274 if ((*ptr)->key == key && (*ptr)->data == data) {
277 ptr = &((*ptr)->next);
279 if (tailindex==ARRAYSIZE) {
280 listtail->nextarray=(struct ArraySimple *) calloc(sizeof(struct ArraySimple),1);
282 listtail=listtail->nextarray;
285 *ptr = &listtail->nodes[tailindex++];
292 for (int i = 0; i < numparents; i++) {
293 parents[i]->add(key, data);
298 bool SimpleHash::contains(int key) {
299 unsigned int hashkey = (unsigned int)key % size;
301 struct SimpleNode *ptr = bucket[hashkey];
303 if (ptr->key == key) {
304 // we already have this object
305 // stored in the hash so just return
313 bool SimpleHash::contains(int key, int data) {
314 unsigned int hashkey = (unsigned int)key % size;
316 struct SimpleNode *ptr = bucket[hashkey];
318 if (ptr->key == key && ptr->data == data) {
319 // we already have this object
320 // stored in the hash so just return
328 int SimpleHash::count(int key) {
329 unsigned int hashkey = (unsigned int)key % size;
332 struct SimpleNode *ptr = bucket[hashkey];
334 if (ptr->key == key) {
342 SimpleHash * SimpleHash::imageSet(int key) {
343 SimpleHash * newset=new SimpleHash(2*count(key)+4);
344 unsigned int hashkey = (unsigned int)key % size;
346 struct SimpleNode *ptr = bucket[hashkey];
348 if (ptr->key == key) {
349 newset->add(ptr->data,ptr->data);
356 int SimpleHash::get(int key, int&data) {
357 unsigned int hashkey = (unsigned int)key % size;
359 struct SimpleNode *ptr = bucket[hashkey];
361 if (ptr->key == key) {
371 int SimpleHash::countdata(int data) {
373 struct ArraySimple *ptr = listhead;
375 if (ptr->nextarray) {
376 for(int i=0;i<ARRAYSIZE;i++)
377 if (ptr->nodes[i].data == data
378 &&ptr->nodes[i].inuse) {
382 for(int i=0;i<tailindex;i++)
383 if (ptr->nodes[i].data == data
384 &&ptr->nodes[i].inuse) {
388 ptr = ptr->nextarray;
393 SimpleHashException::SimpleHashException() {}
394 // ************************************************************
397 RepairHashNode::RepairHashNode(int setrelation, int rule, int lvalue, int rvalue, int data, int data2, int ismodify){
398 this->setrelation = setrelation;
406 this->ismodify=ismodify;
409 // ************************************************************
411 RepairHash::RepairHash(int size) {
413 throw SimpleHashException();
416 this->bucket = new RepairHashNode* [size];
417 for (int i=0;i<size;i++)
420 this->numelements = 0;
423 #define REPAIRSIZE 100
424 RepairHash::RepairHash() {
425 this->size = REPAIRSIZE;
426 this->bucket = new RepairHashNode* [REPAIRSIZE];
427 for (int i=0;i<REPAIRSIZE;i++)
430 this->numelements = 0;
433 RepairHash::~RepairHash() {
434 delete [] this->bucket;
435 RepairHashNode *ptr=nodelist;
437 RepairHashNode *next=ptr->lnext;
443 #define SETFLAG (1<<31)
445 int RepairHash::addset(int setv, int rule, int value, int data) {
446 return addrelation(setv||SETFLAG, rule, value,0,data);
449 int RepairHash::addrelation(int relation, int rule, int lvalue, int rvalue, int data) {
450 unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % size;
452 RepairHashNode **ptr = &bucket[hashkey];
454 /* check that this key/object pair isn't already here */
455 // TBD can be optimized for set v. relation */
457 if ((*ptr)->setrelation == relation &&
458 (*ptr)->rule==rule &&
459 (*ptr)->lvalue==lvalue &&
460 (*ptr)->rvalue==rvalue &&
461 (*ptr)->data == data&&
462 (*ptr)->data2 == 0) {
465 ptr = &((*ptr)->next);
468 *ptr = new RepairHashNode(relation,rule,lvalue,rvalue, data,0,0);
469 (*ptr)->lnext=nodelist;
475 int RepairHash::addrelation(int relation, int rule, int lvalue, int rvalue, int data, int data2) {
476 unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % size;
478 RepairHashNode **ptr = &bucket[hashkey];
480 /* check that this key/object pair isn't already here */
481 // TBD can be optimized for set v. relation */
483 if ((*ptr)->setrelation == relation &&
484 (*ptr)->rule==rule &&
485 (*ptr)->lvalue==lvalue &&
486 (*ptr)->rvalue==rvalue &&
487 (*ptr)->data == data &&
488 (*ptr)->data2 == data2) {
491 ptr = &((*ptr)->next);
494 *ptr = new RepairHashNode(relation,rule,lvalue,rvalue, data,data2,1);
495 (*ptr)->lnext=nodelist;
501 bool RepairHash::containsset(int setv, int rule, int value) {
502 return containsrelation(setv||SETFLAG, rule, value,0);
505 bool RepairHash::containsrelation(int relation, int rule, int lvalue, int rvalue) {
506 unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % size;
508 RepairHashNode **ptr = &bucket[hashkey];
510 /* check that this key/object pair isn't already here */
511 // TBD can be optimized for set v. relation */
513 if ((*ptr)->setrelation == relation &&
514 (*ptr)->rule==rule &&
515 (*ptr)->lvalue==lvalue &&
516 (*ptr)->rvalue==rvalue) {
519 ptr = &((*ptr)->next);
524 int RepairHash::getset(int setv, int rule, int value) {
525 return getrelation(setv||SETFLAG, rule, value,0);
528 int RepairHash::ismodify(int relation, int rule, int lvalue,int rvalue) {
529 unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % size;
531 RepairHashNode **ptr = &bucket[hashkey];
533 /* check that this key/object pair isn't already here */
534 // TBD can be optimized for set v. relation */
536 if ((*ptr)->setrelation == relation &&
537 (*ptr)->rule==rule &&
538 (*ptr)->lvalue==lvalue &&
539 (*ptr)->rvalue==rvalue) {
540 return (*ptr)->ismodify;
542 ptr = &((*ptr)->next);
547 int RepairHash::getrelation2(int relation, int rule, int lvalue,int rvalue) {
548 unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % size;
550 RepairHashNode **ptr = &bucket[hashkey];
552 /* check that this key/object pair isn't already here */
553 // TBD can be optimized for set v. relation */
555 if ((*ptr)->setrelation == relation &&
556 (*ptr)->rule==rule &&
557 (*ptr)->lvalue==lvalue &&
558 (*ptr)->rvalue==rvalue) {
559 return (*ptr)->data2;
561 ptr = &((*ptr)->next);
566 int RepairHash::getrelation(int relation, int rule, int lvalue,int rvalue) {
567 unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % size;
569 RepairHashNode **ptr = &bucket[hashkey];
571 /* check that this key/object pair isn't already here */
572 // TBD can be optimized for set v. relation */
574 if ((*ptr)->setrelation == relation &&
575 (*ptr)->rule==rule &&
576 (*ptr)->lvalue==lvalue &&
577 (*ptr)->rvalue==rvalue) {
580 ptr = &((*ptr)->next);