00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "ObjectTable.h"
00026 #include "Collections.h"
00027 #include "XMLParser.h"
00028 #include "JSemaphore.h"
00029
00030
00031 namespace cmlabs {
00032
00033
00034
00035
00036
00037 ObjectTable::ObjectTable()
00038 {
00039 hashTable = create_hashtable(1);
00040 accessMutex = new JMutex();
00041 sorting = SORTNONE;
00042 count = 0;
00043 currentPos = -1;
00044 current = NULL;
00045 first = NULL;
00046 last = NULL;
00047 deleteOnDestroy = true;
00048 type = "ObjectTable";
00049 }
00050
00051 ObjectTable::ObjectTable(const ObjectTable &Coll) {
00052 hashTable = create_hashtable(1);
00053 accessMutex = new JMutex();
00054 sorting = SORTNONE;
00055 count = 0;
00056 currentPos = -1;
00057 current = NULL;
00058 first = NULL;
00059 last = NULL;
00060 type = Coll.type;
00061 addAll(Coll.first);
00062 deleteOnDestroy = Coll.deleteOnDestroy;
00063 }
00064
00065 ObjectTable::ObjectTable(const JString& xml) {
00066 hashTable = create_hashtable(1);
00067 accessMutex = new JMutex();
00068 sorting = SORTNONE;
00069 count = 0;
00070 currentPos = -1;
00071 current = NULL;
00072 first = NULL;
00073 last = NULL;
00074 deleteOnDestroy = true;
00075 type = "ObjectTable";
00076
00077 if (xml.length() == 0)
00078 return;
00079
00080 fromXML(xml);
00081 }
00082
00083 ObjectTable::ObjectTable(XMLNode* node) {
00084 hashTable = create_hashtable(1);
00085 accessMutex = new JMutex();
00086 sorting = SORTNONE;
00087 count = 0;
00088 currentPos = -1;
00089 current = NULL;
00090 first = NULL;
00091 last = NULL;
00092 deleteOnDestroy = true;
00093 type = "ObjectTable";
00094
00095 fromXML(node);
00096 }
00097
00098
00099 ObjectTable::~ObjectTable()
00100 {
00101 removeAll();
00102 hashtable_destroy(hashTable);
00103 delete(accessMutex);
00104 }
00105
00106 bool ObjectTable::isCollection() {
00107 return true;
00108 }
00109
00110 const ObjectTable& ObjectTable::operator = (const ObjectTable& c) {
00111 removeAll();
00112 type = c.type;
00113 addAll(c.first);
00114 deleteOnDestroy = c.deleteOnDestroy;
00115 return *this;
00116 }
00117
00118
00119 bool ObjectTable::equals(const Object* o2) const {
00120 if (o2 == NULL) return false;
00121 if (!this->isSameClass(o2)) {
00122 return false;
00123 }
00124
00125 ObjectTable* t = (ObjectTable*) o2;
00126 if (!this->type.equalsIgnoreCase(t->type))
00127 return false;
00128
00129 if (this->getCount() != t->getCount())
00130 return false;
00131
00132 CollectionEntry* item1;
00133 CollectionEntry* item2;
00134
00135 if (accessMutex->EnterMutex(5000)) {
00136 for (int n=0; n<getCount(); n++) {
00137 item1 = getEntry(n);
00138 item2 = t->getEntry(n);
00139 if ((item1->key == NULL) || (item2->key == NULL)) {
00140 if (item1->key != item2->key) {
00141 accessMutex->LeaveMutex();
00142 return false;
00143 }
00144 }
00145 else if (!item1->key->equals(item2->key)) {
00146 accessMutex->LeaveMutex();
00147 return false;
00148 }
00149 if (!item1->value->equals(item2->value)) {
00150 accessMutex->LeaveMutex();
00151 return false;
00152 }
00153 }
00154 accessMutex->LeaveMutex();
00155 }
00156 else {
00157 printf("******* Access Denied 1 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
00158 }
00159
00160 return true;
00161 }
00162
00163 bool ObjectTable::operator ==(ObjectTable& c) {
00164 return this->equals(&c);
00165 }
00166
00167 bool ObjectTable::operator !=(ObjectTable& c) {
00168 return (!(*this == c));
00169 }
00170
00171 Object* ObjectTable::clone() const {
00172 ObjectTable* coll = new ObjectTable();
00173
00174 coll->copyAll(this);
00175 coll->type = type;
00176
00177
00178
00179
00180
00181 return (Object*) coll;
00182 }
00183
00184 bool ObjectTable::removeAll() {
00185 if (first == NULL) {
00186 count = 0;
00187 currentPos = -1;
00188 current = NULL;
00189 last = NULL;
00190 return true;
00191 }
00192
00193 if (accessMutex->EnterMutex(5000)) {
00194 CollectionEntry* item = first;
00195 while (first != NULL) {
00196 if (deleteOnDestroy) {
00197 delete(first->value);
00198 first->value = NULL;
00199 }
00200 item = (CollectionEntry*) first->next;
00201 delete(first->key);
00202 delete(first);
00203 first = item;
00204 }
00205 count = 0;
00206 current = NULL;
00207 last = NULL;
00208 currentPos = -1;
00209 hashtable_destroy(hashTable);
00210 hashTable = create_hashtable(1);
00211 accessMutex->LeaveMutex();
00212 }
00213 else {
00214 printf("******* Access Denied 3 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
00215 }
00216 return true;
00217 }
00218
00219
00220 void ObjectTable::noDelete() {
00221 deleteOnDestroy = false;
00222 }
00223
00224 void ObjectTable::doDelete() {
00225 deleteOnDestroy = true;
00226 }
00227
00228 bool ObjectTable::removeAllNoDelete() {
00229 bool prevVal = deleteOnDestroy;
00230 deleteOnDestroy = false;
00231 bool res = removeAll();
00232 deleteOnDestroy = prevVal;
00233 return res;
00234 }
00235
00236 bool ObjectTable::removeNoDelete(int pos) {
00237 bool prevVal = deleteOnDestroy;
00238 deleteOnDestroy = false;
00239 bool res = remove(pos);
00240 deleteOnDestroy = prevVal;
00241 return res;
00242 }
00243
00244 bool ObjectTable::removeNoDelete(const Object* key) {
00245 bool prevVal = deleteOnDestroy;
00246 deleteOnDestroy = false;
00247 bool res = remove(key);
00248 deleteOnDestroy = prevVal;
00249 return res;
00250 }
00251
00252 int ObjectTable::removeNoDelete(const Object* value, bool removeAll) {
00253 bool prevVal = deleteOnDestroy;
00254 deleteOnDestroy = false;
00255 int res = remove(value, removeAll);
00256 deleteOnDestroy = prevVal;
00257 return res;
00258 }
00259
00260
00261
00262 int ObjectTable::getCount() const {
00263 return count;
00264 }
00265
00266 bool ObjectTable::containsKey(const Object* key) const {
00267 return (this->getEntryKey(key) != NULL);
00268 }
00269
00270 bool ObjectTable::contains(const Object* value) const {
00271 return (this->getPos(value) >= 0);
00272 }
00273
00274 ObjectCollection* ObjectTable::getAllKeysCopy() {
00275 ObjectCollection* coll = new ObjectCollection();
00276 CollectionEntry* item = first;
00277 while (item != NULL) {
00278 if (item->key != NULL)
00279 coll->add(item->key->clone());
00280 item = (CollectionEntry*) item->next;
00281 }
00282 return coll;
00283 }
00284
00285
00286
00287
00288
00289
00290 int ObjectTable::getPos(const Object* obj) const {
00291
00292 if (first == NULL)
00293 return -1;
00294
00295 int n = 0;
00296
00297 if (accessMutex->EnterMutex(5000)) {
00298 CollectionEntry* entry = hashtable_search_value(hashTable, obj);
00299 if (entry == NULL) {
00300 accessMutex->LeaveMutex();
00301 return -1;
00302 }
00303
00304 n = getEntryPos(entry);
00305 accessMutex->LeaveMutex();
00306 return n;
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 }
00319 else {
00320 printf("******* Access Denied 4 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
00321 }
00322 return -1;
00323 }
00324
00325 int ObjectTable::getPosKey(const Object* key) const {
00326
00327 if (first == NULL)
00328 return -1;
00329
00330 int n = 0;
00331
00332 if (accessMutex->EnterMutex(5000)) {
00333 CollectionEntry* entry = hashtable_search_key(hashTable, key);
00334 if (entry == NULL) {
00335 accessMutex->LeaveMutex();
00336 return -1;
00337 }
00338
00339 n = getEntryPos(entry);
00340 accessMutex->LeaveMutex();
00341 return n;
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 }
00354 else {
00355 printf("******* Access Denied 4 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
00356 }
00357 return -1;
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 bool ObjectTable::add(Object* key, Object* value) {
00377
00378
00379 if (key != NULL) {
00380 CollectionEntry* entry = getEntryKey(key);
00381 if (entry != NULL) {
00382
00383 return replaceEntry(entry, key, value);
00384 }
00385 }
00386
00387 if ((this->count > 0) && (this->sorting != 0))
00388 return (addAndReturnPosition(key, value) >= 0);
00389
00390
00391 return addLast(key, value);
00392 }
00393
00394
00395
00396 bool ObjectTable::addLast(Object* key, Object* value) {
00397 if (count == 0)
00398 return addBetweenEntries(NULL, NULL, key, value);
00399 return addAfterEntry(last, key, value);
00400 }
00401
00402 bool ObjectTable::addFirst(Object* key, Object* value) {
00403 if (count == 0)
00404 return addBetweenEntries(NULL, NULL, key, value);
00405 return addBeforeEntry(first, key, value);
00406 }
00407
00408
00409
00410 bool ObjectTable::addAfter(const Object* obj, Object* key, Object* value) {
00411 return addAfterEntry(getEntryKey(obj), key, value);
00412 }
00413
00414
00415 bool ObjectTable::addBefore(const Object* obj, Object* key, Object* value) {
00416 return addBeforeEntry(getEntryKey(obj), key, value);
00417 }
00418
00419
00420
00421 bool ObjectTable::addBefore(int pos, Object* key, Object* value) {
00422 if (pos == 0)
00423 return addFirst(key, value);
00424 if (count == 0)
00425 return addBetweenEntries(NULL, NULL, key, value);
00426 CollectionEntry* nextItem = getEntry(pos);
00427 if (nextItem == NULL) return false;
00428 return addBetweenEntries((CollectionEntry*) nextItem->prev, nextItem, key, value);
00429 }
00430
00431 bool ObjectTable::addAfter(int pos, Object* key, Object* value) {
00432 if (count == 0)
00433 return addFirst(key, value);
00434 if (pos >= getCount())
00435 return addLast(key, value);
00436 CollectionEntry* prevItem = getEntry(pos);
00437 if (prevItem == NULL) return false;
00438 return addBetweenEntries(prevItem, (CollectionEntry*) prevItem->next, key, value);
00439 }
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 bool ObjectTable::addBeforeEntry(CollectionEntry* entry, Object* key, Object* value) {
00451 if (entry == NULL) return false;
00452 return addBetweenEntries((CollectionEntry*) entry->prev, entry, key, value);
00453 }
00454
00455 bool ObjectTable::addAfterEntry(CollectionEntry* entry, Object* key, Object* value) {
00456 if (entry == NULL) return false;
00457 return addBetweenEntries(entry, (CollectionEntry*) entry->next, key, value);
00458 }
00459
00460
00461
00462 bool ObjectTable::addBetweenEntries(CollectionEntry* prevItem, CollectionEntry* nextItem, Object* key, Object* value) {
00463 if (value == NULL)
00464 return false;
00465
00466 if (accessMutex->EnterMutex(5000)) {
00467 currentPos = -1;
00468 current = NULL;
00469
00470 CollectionEntry* item = new CollectionEntry(key, value);
00471
00472 item->prev = prevItem;
00473 item->next = nextItem;
00474
00475 if (prevItem != NULL)
00476 prevItem->next = item;
00477 else
00478 first = item;
00479
00480 if (nextItem != NULL)
00481 nextItem->prev = item;
00482 else
00483 last = item;
00484
00485 if (item->key != NULL)
00486 hashtable_insert_key(hashTable, item);
00487 hashtable_insert_value(hashTable, item);
00488 accessMutex->LeaveMutex();
00489 }
00490 else {
00491 printf("******* Access Denied 5 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
00492 }
00493
00494 count++;
00495 return true;
00496 }
00497
00498
00499
00500
00501
00502
00503 bool ObjectTable::replace(const Object* obj, Object* key, Object* value) {
00504 return replaceEntry(getEntryKey(obj), key, value);
00505 }
00506
00507 bool ObjectTable::replace(int pos, Object* key, Object* value) {
00508 return replaceEntry(getEntry(pos), key, value);
00509 }
00510
00511
00512
00513 bool ObjectTable::replaceEntry(CollectionEntry* entry, Object* key, Object* value) {
00514 if ((entry == NULL) || (value == NULL))
00515 return false;
00516
00517 if (accessMutex->EnterMutex(5000)) {
00518 if (this->deleteOnDestroy) {
00519
00520 delete(entry->value);
00521
00522 }
00523
00524 delete(entry->key);
00525
00526
00527 entry->key = key;
00528 entry->value = value;
00529 accessMutex->LeaveMutex();
00530 }
00531 else {
00532 printf("******* Access Denied 6 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
00533 }
00534 return true;
00535 }
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 bool ObjectTable::removeFirst() {
00547
00548 if (accessMutex->EnterMutex(5000)) {
00549 if (first == NULL) {
00550 accessMutex->LeaveMutex();
00551 return true;
00552 }
00553 CollectionEntry* second = first->next;
00554 if (second != NULL) {
00555 second->prev = NULL;
00556 }
00557
00558 hashtable_remove_key(hashTable, first);
00559 hashtable_remove_value(hashTable, first);
00560
00561 if (this->deleteOnDestroy) {
00562 delete(first->value);
00563 }
00564 first->value = NULL;
00565 delete(first->key);
00566 if (first == last)
00567 last = NULL;
00568 delete(first);
00569 first = second;
00570 count--;
00571 current = NULL;
00572 currentPos = -1;
00573 accessMutex->LeaveMutex();
00574 return true;
00575 }
00576 else {
00577 printf("******* Access Denied 100 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
00578 }
00579 return false;
00580 }
00581
00582 bool ObjectTable::removeLast() {
00583
00584 if (accessMutex->EnterMutex(5000)) {
00585 if (last == NULL) {
00586 accessMutex->LeaveMutex();
00587 return true;
00588 }
00589 CollectionEntry* second = last->prev;
00590 if (second != NULL) {
00591 second->next = NULL;
00592 }
00593
00594 hashtable_remove_key(hashTable, first);
00595 hashtable_remove_value(hashTable, first);
00596
00597 if (this->deleteOnDestroy) {
00598 delete(last->value);
00599 }
00600 last->value = NULL;
00601 delete(last->key);
00602 if (first == last)
00603 first = NULL;
00604 delete(last);
00605 last = second;
00606 count--;
00607 current = NULL;
00608 currentPos = -1;
00609 accessMutex->LeaveMutex();
00610 return true;
00611 }
00612 else {
00613 printf("******* Access Denied 101 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
00614 }
00615 return false;
00616 }
00617
00618 int ObjectTable::remove(const Object* value, bool removeAllMatches) {
00619
00620 int c = 0;
00621 if (accessMutex->EnterMutex(5000)) {
00622
00623 ObjectCollection* coll = hashtable_search_values(hashTable, value);
00624 if (coll == NULL) {
00625 accessMutex->LeaveMutex();
00626 return 0;
00627 }
00628 for (CollectionEntry* entry = (CollectionEntry*)coll->getFirst(); entry != NULL; entry = (CollectionEntry*)coll->getNext()) {
00629 removeEntry(entry);
00630 c++;
00631 if (!removeAllMatches) {
00632 accessMutex->LeaveMutex();
00633 delete(coll);
00634 return 1;
00635 }
00636 }
00637 accessMutex->LeaveMutex();
00638 delete(coll);
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670 }
00671 else {
00672 printf("******* Access Denied 7 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
00673 }
00674
00675 return c;
00676 }
00677
00678 bool ObjectTable::remove(const Object* key) {
00679 return removeEntry(getEntryKey(key));
00680 }
00681
00682 bool ObjectTable::remove(int pos) {
00683 return removeEntry(getEntry(pos));
00684 }
00685
00686
00687
00688 bool ObjectTable::removeEntry(CollectionEntry* entry) {
00689 if (entry == NULL)
00690 return false;
00691
00692 if (accessMutex->EnterMutex(5000)) {
00693 currentPos = -1;
00694 current = NULL;
00695
00696 hashtable_remove_key(hashTable, entry);
00697 hashtable_remove_value(hashTable, entry);
00698
00699 CollectionEntry* prevItem = (CollectionEntry*) entry->prev;
00700 CollectionEntry* nextItem = (CollectionEntry*) entry->next;
00701
00702 if (prevItem != NULL)
00703 prevItem->next = nextItem;
00704 else
00705 first = nextItem;
00706
00707 if (nextItem != NULL)
00708 nextItem->prev = prevItem;
00709 else
00710 last = prevItem;
00711
00712 if (this->deleteOnDestroy) {
00713 delete(entry->value);
00714 }
00715 entry->value = NULL;
00716 delete(entry->key);
00717 delete(entry);
00718
00719 count--;
00720 accessMutex->LeaveMutex();
00721 }
00722 else {
00723 printf("******* Access Denied 8 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
00724 }
00725
00726 return true;
00727 }
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741 Object* ObjectTable::get(const Object* key) const {
00742 CollectionEntry* entry = getEntryKey(key);
00743 if (entry != NULL)
00744 return entry->value;
00745 else
00746 return NULL;
00747 }
00748
00749 Object* ObjectTable::get(int pos) const {
00750 CollectionEntry* entry = getEntry(pos);
00751 if (entry != NULL)
00752 return entry->value;
00753 else
00754 return NULL;
00755 }
00756
00757 Object* ObjectTable::get(int pos) {
00758 CollectionEntry* entry = getEntry(pos);
00759 if (entry != NULL)
00760 return entry->value;
00761 else
00762 return NULL;
00763 }
00764
00765 Object* ObjectTable::take(const Object* key) {
00766 CollectionEntry* entry = getEntryKey(key);
00767 if (entry != NULL) {
00768 this->removeNoDelete(entry);
00769 return entry->value;
00770 }
00771 else
00772 return NULL;
00773 }
00774
00775 Object* ObjectTable::take(int pos) {
00776 CollectionEntry* entry = getEntry(pos);
00777 if (entry != NULL) {
00778 this->removeNoDelete(entry);
00779 return entry->value;
00780 }
00781 else
00782 return NULL;
00783 }
00784
00785 Object* ObjectTable::getNext() {
00786 CollectionEntry* entry = getNextEntry();
00787 if (entry != NULL)
00788 return entry->value;
00789 else
00790 return NULL;
00791 }
00792
00793 Object* ObjectTable::getPrevious() {
00794 CollectionEntry* entry = getPreviousEntry();
00795 if (entry != NULL)
00796 return entry->value;
00797 else
00798 return NULL;
00799 }
00800
00801 Object* ObjectTable::getFirst() {
00802 CollectionEntry* entry = getFirstEntry();
00803 if (entry != NULL)
00804 return entry->value;
00805 else
00806 return NULL;
00807 }
00808
00809 Object* ObjectTable::getLast() {
00810 CollectionEntry* entry = getLastEntry();
00811 if (entry != NULL)
00812 return entry->value;
00813 else
00814 return NULL;
00815 }
00816
00817
00818 CollectionEntry* ObjectTable::getEntryKey(const Object* key) const {
00819 if ((first == NULL) || (key == NULL))
00820 return NULL;
00821
00822 if (accessMutex->EnterMutex(5000)) {
00823 CollectionEntry* item = hashtable_search_key(hashTable, key);
00824 accessMutex->LeaveMutex();
00825 return item;
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836 }
00837 else {
00838 printf("******* Access Denied 9 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
00839 }
00840
00841 return NULL;
00842 }
00843
00844 CollectionEntry* ObjectTable::getEntryValue(const Object* value) const {
00845 if ((first == NULL) || (value == NULL))
00846 return NULL;
00847
00848 if (accessMutex->EnterMutex(5000)) {
00849 CollectionEntry* item = hashtable_search_value(hashTable, value);
00850 accessMutex->LeaveMutex();
00851 return item;
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862 }
00863 else {
00864 printf("******* Access Denied 9 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
00865 }
00866
00867 return NULL;
00868 }
00869
00870 CollectionEntry* ObjectTable::getEntry(int pos) const {
00871 if ((pos < 0) || (pos >= count)) return NULL;
00872 if (first == NULL) return NULL;
00873 if (pos >= count) return NULL;
00874
00875 int end = count-1;
00876 if (accessMutex->EnterMutex(5000)) {
00877 CollectionEntry* entry = first;
00878 int n;
00879 int distEnd = end-pos;
00880 int distCur = currentPos-pos;
00881
00882
00883 if ( (pos < distEnd) && (pos < abs(distCur)) ) {
00884
00885 for (n=0; n<pos; n++)
00886 entry = entry->next;
00887 }
00888 else if (distEnd < abs(distCur)) {
00889
00890 entry = last;
00891 for (n=0; n<distEnd; n++)
00892 entry = entry->prev;
00893 }
00894 else {
00895 if (distCur >= 0) {
00896
00897 entry = current;
00898 for (n=0; n<distCur; n++)
00899 entry = entry->prev;
00900 }
00901 else {
00902
00903 entry = current;
00904 distCur = 0-distCur;
00905 for (n=0; n<distCur; n++)
00906 entry = entry->next;
00907 }
00908 }
00909 accessMutex->LeaveMutex();
00910 return entry;
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925 }
00926 else {
00927 printf("******* Access Denied 10 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
00928 }
00929 return NULL;
00930 }
00931
00932 CollectionEntry* ObjectTable::getEntry(int pos) {
00933
00934 if (accessMutex->EnterMutex(5000)) {
00935 const ObjectTable* table = this;
00936 CollectionEntry* entry = table->getEntry(pos);
00937 if (entry == NULL) {
00938 accessMutex->LeaveMutex();
00939 return NULL;
00940 }
00941 currentPos = pos;
00942 current = entry;
00943 accessMutex->LeaveMutex();
00944 return entry;
00945 }
00946 else
00947 printf("******* Access Denied 11 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
00948 return NULL;
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050 }
01051
01052
01053
01054
01055 CollectionEntry* ObjectTable::getNextEntry() {
01056
01057 if (accessMutex->EnterMutex(5000)) {
01058 if ( (current != NULL) && (current->next != NULL) ) {
01059 currentPos++;
01060 current = (CollectionEntry*) current->next;
01061 accessMutex->LeaveMutex();
01062 return current;
01063 }
01064 accessMutex->LeaveMutex();
01065 }
01066 return NULL;
01067 }
01068
01069
01070 CollectionEntry* ObjectTable::getPreviousEntry() {
01071 if (accessMutex->EnterMutex(5000)) {
01072 if ( (current != NULL) && (current->prev != NULL) ) {
01073 currentPos--;
01074 current = (CollectionEntry*) current->prev;
01075 accessMutex->LeaveMutex();
01076 return current;
01077 }
01078 accessMutex->LeaveMutex();
01079 }
01080 return NULL;
01081 }
01082
01083
01084 CollectionEntry* ObjectTable::getFirstEntry() {
01085 CollectionEntry* item = NULL;
01086 if (accessMutex->EnterMutex(5000)) {
01087 currentPos = 0;
01088 current = first;
01089 item = first;
01090 accessMutex->LeaveMutex();
01091 }
01092 return item;
01093 }
01094
01095 CollectionEntry* ObjectTable::getLastEntry() {
01096 CollectionEntry* item = NULL;
01097 if (accessMutex->EnterMutex(5000)) {
01098 currentPos = count - 1;
01099 current = last;
01100 item = last;
01101 accessMutex->LeaveMutex();
01102 }
01103 return item;
01104 }
01105
01106 Object* ObjectTable::getKey(int pos) const {
01107 CollectionEntry* entry = getEntry(pos);
01108 if (entry == NULL)
01109 return NULL;
01110 return entry->key;
01111 }
01112
01113 Object* ObjectTable::getKey(int pos) {
01114 CollectionEntry* entry = getEntry(pos);
01115 if (entry == NULL)
01116 return NULL;
01117 return entry->key;
01118 }
01119
01120 Object* ObjectTable::getFirstKey() {
01121 CollectionEntry* entry = getFirstEntry();
01122 if (entry == NULL)
01123 return NULL;
01124 return entry->key;
01125 }
01126
01127 Object* ObjectTable::getLastKey() {
01128 CollectionEntry* entry = getLastEntry();
01129 if (entry == NULL)
01130 return NULL;
01131 return entry->key;
01132 }
01133
01134 Object* ObjectTable::getNextKey() {
01135 CollectionEntry* entry = getNextEntry();
01136 if (entry == NULL)
01137 return NULL;
01138 return entry->key;
01139 }
01140
01141 Object* ObjectTable::getPreviousKey() {
01142 CollectionEntry* entry = getPreviousEntry();
01143 if (entry == NULL)
01144 return NULL;
01145 return entry->key;
01146 }
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163 int ObjectTable::getEntryPos(CollectionEntry* entry) const {
01164 int c = 0;
01165 CollectionEntry* e = NULL;
01166 if (accessMutex->EnterMutex(5000)) {
01167 e = first;
01168 while ((e != NULL) && (e != entry)) {
01169 e = e->next;
01170 c++;
01171 }
01172 accessMutex->LeaveMutex();
01173 }
01174 else {
01175 printf("******* Access Denied 12 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
01176 }
01177 return ((e == NULL) ? -1 : c);
01178 }
01179
01180
01181 int ObjectTable::addAndReturnPosition(Object* key, Object* value) {
01182 CollectionEntry* entry;
01183
01184 if (sorting & SORTBYKEY) {
01185 if (sorting & SORTREVERSE) {
01186 if ( (entry = getLastEntryBeforeKey(key)) != NULL) {
01187 if (addAfterEntry(entry, key, value))
01188 return getEntryPos(entry)+1;
01189 else
01190 return -1;
01191 }
01192 else {
01193 addFirst(key, value);
01194 return 0;
01195 }
01196 }
01197 else {
01198 if ( (entry = getLastEntryBeforeKey(key)) != NULL) {
01199 if (addAfterEntry(entry, key, value))
01200 return getEntryPos(entry)+1;
01201 else
01202 return -1;
01203 }
01204 else {
01205 addFirst(key, value);
01206 return 0;
01207 }
01208 }
01209 }
01210 else if (sorting & SORTBYVALUE) {
01211 if (sorting & SORTREVERSE) {
01212
01213
01214
01215
01216
01217
01218
01219
01220 if ( (entry = getLastEntryBefore(value)) != NULL) {
01221 if (addAfterEntry(entry, key, value))
01222 return getEntryPos(entry)+1;
01223 else
01224 return -1;
01225 }
01226 else {
01227 addFirst(key, value);
01228 return 0;
01229 }
01230 }
01231 else {
01232
01233
01234
01235
01236
01237
01238
01239
01240 if ( (entry = getLastEntryBefore(value)) != NULL) {
01241 if (addAfterEntry(entry, key, value))
01242 return getEntryPos(entry)+1;
01243 else
01244 return -1;
01245 }
01246 else {
01247 addFirst(key, value);
01248 return 0;
01249 }
01250 }
01251 }
01252 else {
01253 if (!addLast(key, value))
01254 return -1;
01255 else
01256 return getCount()-1;
01257 }
01258 }
01259
01260
01261
01262
01263 ObjectCollection* ObjectTable::getAllBetweenKeys(const Object* key1, const Object* key2) {
01264 ObjectCollection* entries = getAllEntriesBetweenKeys(key1, key2);
01265 if (entries == NULL)
01266 return NULL;
01267 ObjectCollection* col = new ObjectCollection();
01268 col->noDelete();
01269 CollectionEntry* entry;
01270 for (int n=0; n<entries->getCount(); n++) {
01271 if ( (entry = (CollectionEntry*) entries->get(n)) != NULL )
01272 col->add(entry->value);
01273 }
01274 delete(entries);
01275 return col;
01276 }
01277
01278 ObjectCollection* ObjectTable::getAllBetween(const Object* value1, const Object* value2) {
01279 ObjectCollection* entries = getAllEntriesBetween(value1, value2);
01280 if (entries == NULL)
01281 return NULL;
01282 ObjectCollection* col = new ObjectCollection();
01283 col->noDelete();
01284 CollectionEntry* entry;
01285 for (int n=0; n<entries->getCount(); n++) {
01286 if ( (entry = (CollectionEntry*) entries->get(n)) != NULL )
01287 col->add(entry->value);
01288 }
01289 delete(entries);
01290 return col;
01291 }
01292
01293 Object* ObjectTable::getFirstAfterKey(const Object* key) {
01294 CollectionEntry* entry = getFirstEntryAfterKey(key);
01295 if (entry != NULL)
01296 return entry->value;
01297 else
01298 return NULL;
01299 }
01300
01301 Object* ObjectTable::getFirstAfter(const Object* value) {
01302 CollectionEntry* entry = getFirstEntryAfter(value);
01303 if (entry != NULL)
01304 return entry->value;
01305 else
01306 return NULL;
01307 }
01308
01309 Object* ObjectTable::getLastBeforeKey(const Object* key) {
01310 CollectionEntry* entry = getLastEntryBeforeKey(key);
01311 if (entry != NULL)
01312 return entry->value;
01313 else
01314 return NULL;
01315 }
01316
01317 Object* ObjectTable::getLastBefore(const Object* value) {
01318 CollectionEntry* entry = getLastEntryBefore(value);
01319 if (entry != NULL)
01320 return entry->value;
01321 else
01322 return NULL;
01323 }
01324
01325 int ObjectTable::removeAllBetweenKeys(const Object* key1, const Object* key2) {
01326 return removeAllEntriesBetweenKeys(key1, key2);
01327 }
01328
01329 int ObjectTable::removeAllBetween(const Object* value1, const Object* value2) {
01330 return removeAllEntriesBetween(value1, value2);
01331 }
01332
01333 int ObjectTable::removeAllBeforeKey(const Object* key) {
01334 if (first == NULL)
01335 return 0;
01336 return removeAllEntriesBetweenKeys(first->key, key);
01337 }
01338
01339 int ObjectTable::removeAllBefore(const Object* value) {
01340 if (first == NULL)
01341 return 0;
01342 return removeAllEntriesBetween(first->value, value);
01343 }
01344
01345 int ObjectTable::removeAllAfterKey(const Object* key) {
01346 if (first == NULL)
01347 return 0;
01348 return removeAllEntriesBetweenKeys(key, last->key);
01349 }
01350
01351 int ObjectTable::removeAllAfter(const Object* value) {
01352 if (first == NULL)
01353 return 0;
01354 return removeAllEntriesBetween(value, last->value);
01355 }
01356
01357
01358
01359
01360
01361
01362
01363 CollectionEntry** ObjectTable::findClosestKeys(const Object* key) const {
01364 CollectionEntry** triplet = new CollectionEntry*[3];
01365 memset(triplet, 0, sizeof(CollectionEntry*)*3);
01366
01367 CollectionEntry* entry = this->getEntryKey(key);
01368 if (entry != NULL) {
01369 triplet[0] = entry;
01370 triplet[1] = entry->prev;
01371 triplet[2] = entry->next;
01372 return triplet;
01373 }
01374
01375
01376
01377
01378 if ((!(sorting & SORTBYKEY)) || (first == NULL) || (first->key == NULL))
01379 return triplet;
01380
01381 int comp, comp2;
01382
01383 if (sorting & SORTREVERSE) {
01384
01385 comp = first->key->compare(key);
01386 if ( (comp < 0) ) {
01387 triplet[2] = first;
01388 return triplet;
01389 }
01390 else {
01391
01392 comp2 = last->key->compare(key);
01393 if ( (comp2 >= 0) ) {
01394 triplet[1] = last;
01395 return triplet;
01396 }
01397
01398 else if ( (comp == 0) && (comp2 == 0)) {
01399 triplet[1] = last;
01400 return triplet;
01401 }
01402 }
01403 }
01404 else {
01405
01406 comp = first->key->compare(key);
01407 if ( (comp > 0) ) {
01408 triplet[2] = first;
01409 return triplet;
01410 }
01411 else {
01412
01413 comp2 = last->key->compare(key);
01414 if ( (comp2 <= 0) ) {
01415 triplet[1] = last;
01416 return triplet;
01417 }
01418
01419 else if ( (comp == 0) && (comp2 == 0)) {
01420 triplet[1] = last;
01421 return triplet;
01422 }
01423 }
01424 }
01425
01426
01427 if (getCount() == 2) {
01428 triplet[1] = first;
01429 triplet[2] = last;
01430 return triplet;
01431 }
01432
01433 entry = first;
01434 bool growing = true;
01435 int n;
01436
01437
01438 for (int delta = (getCount() >> 1); delta >= 1; delta = (delta >> 1)) {
01439 if (growing)
01440 for (n=0; n<delta; n++) entry = entry->next;
01441 else
01442 for (n=0; n<delta; n++) entry = entry->prev;
01443 growing = ( (comp = entry->key->compare(key)) <= 0);
01444 if ((comp != 0) && (sorting & SORTREVERSE))
01445 growing = (!growing);
01446 }
01447
01448 if (sorting & SORTREVERSE) {
01449
01450
01451 if (growing) {
01452 do { entry = entry->next; }
01453 while ( (entry != NULL) && (entry->key->compare(key) >= 0) );
01454 if (entry == NULL)
01455 triplet[1] = last;
01456 else {
01457 triplet[1] = entry->prev;
01458 triplet[2] = entry;
01459 }
01460 }
01461
01462
01463 else {
01464 do { entry = entry->prev; }
01465 while (entry->key->compare(key) < 0);
01466 triplet[1] = entry;
01467 triplet[2] = entry->next;
01468 }
01469 }
01470 else {
01471
01472
01473 if (!growing) {
01474 do { entry = entry->prev; }
01475 while (entry->key->compare(key) > 0);
01476 triplet[1] = entry;
01477 triplet[2] = entry->next;
01478 }
01479
01480
01481 else {
01482 do { entry = entry->next; }
01483 while ( (entry != NULL) && (entry->key->compare(key) <= 0));
01484 if (entry == NULL)
01485 triplet[1] = last;
01486 else {
01487 triplet[1] = entry->prev;
01488 triplet[2] = entry;
01489 }
01490 }
01491 }
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518 return triplet;
01519 }
01520
01521 CollectionEntry** ObjectTable::findClosestValues(const Object* value) const {
01522 CollectionEntry** triplet = new CollectionEntry*[3];
01523 memset(triplet, 0, sizeof(CollectionEntry*)*3);
01524
01525 CollectionEntry* entry = this->getEntryValue(value);
01526 if (entry != NULL) {
01527 triplet[0] = entry;
01528 triplet[1] = entry->prev;
01529 triplet[2] = entry->next;
01530 return triplet;
01531 }
01532
01533
01534
01535
01536 if ((!(sorting & SORTBYVALUE)) || (first == NULL))
01537 return triplet;
01538
01539 int comp, comp2;
01540
01541 if (sorting & SORTREVERSE) {
01542
01543 comp = first->value->compare(value);
01544 if ( (comp < 0) ) {
01545 triplet[2] = first;
01546 return triplet;
01547 }
01548 else {
01549 comp2 = last->value->compare(value);
01550
01551 if ( (comp2 >= 0) ) {
01552 triplet[1] = last;
01553 return triplet;
01554 }
01555
01556 else if ( (comp == 0) && (comp2 == 0)) {
01557 triplet[1] = last;
01558 return triplet;
01559 }
01560 }
01561 }
01562 else {
01563
01564 comp = first->value->compare(value);
01565 if ( (comp > 0) ) {
01566 triplet[2] = first;
01567 return triplet;
01568 }
01569 else {
01570
01571 comp2 = last->value->compare(value);
01572 if ( (comp2 <= 0) ) {
01573 triplet[1] = last;
01574 return triplet;
01575 }
01576
01577 else if ( (comp == 0) && (comp2 == 0)) {
01578 triplet[1] = last;
01579 return triplet;
01580 }
01581 }
01582 }
01583
01584
01585 if (getCount() == 2) {
01586 triplet[1] = first;
01587 triplet[2] = last;
01588 return triplet;
01589 }
01590
01591 entry = first;
01592 bool growing = true;
01593 int n;
01594
01595
01596 for (int delta = (getCount() >> 1); delta >= 1; delta = (delta >> 1)) {
01597 if (growing)
01598 for (n=0; n<delta; n++) entry = entry->next;
01599 else
01600 for (n=0; n<delta; n++) entry = entry->prev;
01601 growing = ( (comp = entry->value->compare(value)) <= 0);
01602 if ( (comp != 0) && (sorting & SORTREVERSE))
01603 growing = (!growing);
01604 }
01605
01606 if (sorting & SORTREVERSE) {
01607
01608
01609 if (growing) {
01610 do { entry = entry->next; }
01611 while ( (entry != NULL) && (entry->value->compare(value) >= 0) );
01612 if (entry == NULL)
01613 triplet[1] = last;
01614 else {
01615 triplet[1] = entry->prev;
01616 triplet[2] = entry;
01617 }
01618 }
01619
01620
01621 else {
01622 do { entry = entry->prev; }
01623 while (entry->value->compare(value) < 0);
01624 triplet[1] = entry;
01625 triplet[2] = entry->next;
01626 }
01627 }
01628 else {
01629
01630
01631 if (!growing) {
01632 do { entry = entry->prev; }
01633 while (entry->value->compare(value) > 0);
01634 triplet[1] = entry;
01635 triplet[2] = entry->next;
01636 }
01637
01638
01639 else {
01640 do { entry = entry->next; }
01641 while ( (entry != NULL) && (entry->value->compare(value) <= 0) );
01642 if (entry == NULL)
01643 triplet[1] = last;
01644 else {
01645 triplet[1] = entry->prev;
01646 triplet[2] = entry;
01647 }
01648 }
01649 }
01650
01651 return triplet;
01652 }
01653
01654
01655
01656
01657
01658
01659
01660
01661 ObjectCollection* ObjectTable::getAllEntriesBetweenKeys(const Object* key1, const Object* key2) {
01662 if ( (key1 == NULL) || (key2 == NULL) )
01663 return NULL;
01664
01665 if ((!(sorting & SORTBYKEY)) || (first == NULL) || (first->key == NULL))
01666 return NULL;
01667
01668 ObjectCollection* col = new ObjectCollection();
01669 col->noDelete();
01670
01671 if (key1->equals(key2)) {
01672 col->add(getEntryKey(key1));
01673 return col;
01674 }
01675
01676 const Object* k1, *k2;
01677 if (key1->compare(key2) < 0) {
01678 k1 = key1;
01679 k2 = key2;
01680 }
01681 else {
01682 k2 = key1;
01683 k1 = key2;
01684 }
01685
01686 CollectionEntry* entry;
01687 if (sorting & SORTREVERSE) {
01688 entry = getEntryKey(k2);
01689 if (entry == NULL)
01690 entry = getFirstEntryAfterKey(k2);
01691 if (accessMutex->EnterMutex(5000)) {
01692 if ( (entry != NULL) && (entry->prev != NULL) && (k2->compare(entry->prev->key) == 0) )
01693 col->add(entry->prev);
01694 while ((entry != NULL) && (k1->compare(entry->key) <= 0)) {
01695 col->add(entry);
01696 entry = entry->next;
01697 }
01698 accessMutex->LeaveMutex();
01699 }
01700 }
01701 else {
01702 entry = getEntryKey(k1);
01703 if (entry == NULL)
01704 entry = getFirstEntryAfterKey(k1);
01705 if (accessMutex->EnterMutex(5000)) {
01706 if ( (entry != NULL) && (entry->prev != NULL) && (k1->compare(entry->prev->key) == 0) )
01707 col->add(entry->prev);
01708 while ((entry != NULL) && (k2->compare(entry->key) >= 0)) {
01709 col->add(entry);
01710 entry = entry->next;
01711 }
01712 accessMutex->LeaveMutex();
01713 }
01714 }
01715 return col;
01716 }
01717
01718
01719
01720
01721 ObjectCollection* ObjectTable::getAllEntriesBetween(const Object* value1, const Object* value2) {
01722 if ( (value1 == NULL) || (value2 == NULL) )
01723 return NULL;
01724
01725 if ((!(sorting & SORTBYVALUE)) || (first == NULL))
01726 return NULL;
01727
01728 ObjectCollection* col = new ObjectCollection();
01729 col->noDelete();
01730
01731 if (value1->equals(value2)) {
01732 col->add(getEntryValue(value1));
01733 return col;
01734 }
01735
01736 const Object* k1, *k2;
01737 if (value1->compare(value2) <= 0) {
01738 k1 = value1;
01739 k2 = value2;
01740 }
01741 else {
01742 k2 = value1;
01743 k1 = value2;
01744 }
01745
01746 CollectionEntry* entry;
01747 if (sorting & SORTREVERSE) {
01748 entry = getEntryValue(k2);
01749 if (entry != NULL) {
01750 while ((entry->prev != NULL) && (entry->value->compare(entry->prev->value) == 0))
01751 entry = entry->prev;
01752 }
01753 else
01754 entry = getFirstEntryAfter(k2);
01755 if (accessMutex->EnterMutex(5000)) {
01756 if (entry == NULL)
01757 entry = last;
01758 else if ( (entry != NULL) && (entry->prev != NULL) && (k2->compare(entry->prev->value) == 0) )
01759 col->add(entry->prev);
01760 while ((entry != NULL) && (k1->compare(entry->value) <= 0)) {
01761 col->add(entry);
01762 entry = entry->next;
01763 }
01764 }
01765 accessMutex->LeaveMutex();
01766 }
01767 else {
01768 entry = getEntryValue(k1);
01769 if (entry != NULL) {
01770 while ((entry->prev != NULL) && (entry->value->compare(entry->prev->value) == 0))
01771 entry = entry->prev;
01772 }
01773 else
01774 entry = getFirstEntryAfter(k1);
01775 if (accessMutex->EnterMutex(5000)) {
01776 if (entry == NULL)
01777 entry = first;
01778 if ( (entry != NULL) && (entry->prev != NULL) && (k1->compare(entry->prev->value) == 0) )
01779 col->add(entry->prev);
01780 while ((entry != NULL) && (k2->compare(entry->value) >= 0)) {
01781 col->add(entry);
01782 entry = entry->next;
01783 }
01784 }
01785 accessMutex->LeaveMutex();
01786 }
01787 return col;
01788 }
01789
01790 CollectionEntry* ObjectTable::getFirstEntryAfterKey(const Object* key) {
01791
01792 CollectionEntry** entries = findClosestKeys(key);
01793 CollectionEntry* entry = entries[2];
01794 delete [] entries;
01795 return entry;
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873 }
01874
01875 CollectionEntry* ObjectTable::getFirstEntryAfter(const Object* value) {
01876
01877 CollectionEntry** entries = findClosestValues(value);
01878 CollectionEntry* entry = entries[2];
01879 delete [] entries;
01880 return entry;
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958 }
01959
01960 CollectionEntry* ObjectTable::getLastEntryBeforeKey(const Object* key) {
01961
01962 CollectionEntry** entries = findClosestKeys(key);
01963 CollectionEntry* entry = entries[1];
01964 delete [] entries;
01965 return entry;
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043 }
02044
02045 CollectionEntry* ObjectTable::getLastEntryBefore(const Object* value) {
02046
02047 CollectionEntry** entries = findClosestValues(value);
02048 CollectionEntry* entry = entries[1];
02049 delete [] entries;
02050 return entry;
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130 }
02131
02132
02133 int ObjectTable::removeAllEntriesBetweenKeys(const Object* key1, const Object* key2) {
02134 int c = 0;
02135 if (accessMutex->EnterMutex(5000)) {
02136 ObjectCollection* col = getAllEntriesBetweenKeys(key1, key2);
02137 if (col != NULL) {
02138 for (CollectionEntry* entry = (CollectionEntry*) col->getFirst(); entry != NULL; entry = (CollectionEntry*) col->getNext()) {
02139 if (removeEntry(entry))
02140 c++;
02141 }
02142 }
02143 delete(col);
02144 accessMutex->LeaveMutex();
02145 }
02146 else {
02147 printf("******* Access Denied 19 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
02148 }
02149 return c;
02150 }
02151
02152 int ObjectTable::removeAllEntriesBetween(const Object* value1, const Object* value2) {
02153 int c = 0;
02154 if (accessMutex->EnterMutex(5000)) {
02155 ObjectCollection* col = getAllEntriesBetween(value1, value2);
02156 if (col != NULL) {
02157 for (CollectionEntry* entry = (CollectionEntry*) col->getFirst(); entry != NULL; entry = (CollectionEntry*) col->getNext()) {
02158 if (removeEntry(entry))
02159 c++;
02160 }
02161 }
02162 delete(col);
02163 accessMutex->LeaveMutex();
02164 }
02165 else {
02166 printf("******* Access Denied 20 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
02167 }
02168 return c;
02169 }
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184 JString ObjectTable::toHTML() {
02185 JString str = "<TABLE width=\"100%%\" class=\"DictionaryTable\">\n";
02186 if (accessMutex->EnterMutex(5000)) {
02187 CollectionEntry* entry = first;
02188 while (entry != NULL) {
02189 if (entry->key != NULL)
02190 str += JString::format("<TR>\n<TD class=\"DictionaryKey\" valign=\"top\" align=\"left\">%s</TD>\n", (char*) entry->key->toHTML());
02191 else
02192 str += JString("<TR>\n<TD></TD>\n");
02193 str += JString::format("<TD class=\"DictionaryValue\" valign=\"top\" align=\"left\">%s</TD>\n</TD>\n", (char*) entry->value->toHTML());
02194 entry = entry->next;
02195 }
02196 accessMutex->LeaveMutex();
02197 }
02198 else {
02199 printf("******* Access Denied 21 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
02200 }
02201 str += JString("</TABLE>\n");
02202 return str;
02203 }
02204
02205
02206 JString ObjectTable::toXML() {
02207 JString xml;
02208
02209
02210 int mytype = -1;
02211 if (type.equals("objectcollection"))
02212 mytype = 1;
02213 else if (type.equals("objectdictionary"))
02214 mytype = 2;
02215 else if (type.equals("dictionary"))
02216 mytype = 3;
02217 else if (type.equals("sortedcollection"))
02218 mytype = 0;
02219 else if (type.equals("sortedobjectcollection"))
02220 mytype = 1;
02221 else if (type.equals("sorteddictionary"))
02222 mytype = 3;
02223 else if (type.equals("sortedobjectdictionary"))
02224 mytype = 2;
02225 else if (type.equals("collection"))
02226 mytype = 0;
02227
02228 if (accessMutex->EnterMutex(5000)) {
02229 CollectionEntry* entry = first;
02230 while (entry != NULL) {
02231 switch(mytype) {
02232 case -1:
02233 if (entry->key != NULL) {
02234 xml += JString::format("<objectkey>\n%s</objectkey>\n", (char*) entry->key->toXML().indentXML());
02235 }
02236 xml += JString::format("<objectvalue>\n%s</objectvalue>\n", (char*) entry->value->toXML().indentXML());
02237 break;
02238 case 0:
02239 if (((JString*)entry->value)->startsOrEndsWithWhiteSpace())
02240 xml += JString::format("<entry value=\"%s\" />\n", (char*) ((JString*)entry->value)->xmlStringEncode());
02241 else
02242 xml += JString::format("<entry>%s</entry>\n", (char*) ((JString*)entry->value)->xmlStringEncode());
02243 break;
02244 case 1:
02245 xml += JString::format("<object>\n%s</object>\n", (char*) entry->value->toXML().indentXML());
02246 break;
02247 case 2:
02248 xml += JString::format("<object name=\"%s\">\n%s</object>\n", (char*) ((JString*)entry->key)->xmlStringEncode(), (char*) entry->value->toXML().indentXML());
02249 break;
02250 case 3:
02251 if (((JString*)entry->value)->startsOrEndsWithWhiteSpace())
02252 xml += JString::format("<entry name=\"%s\" value=\"%s\" />\n", (char*) ((JString*)entry->key)->xmlStringEncode(), (char*) ((JString*)entry->value)->xmlStringEncode());
02253 else
02254 xml += JString::format("<entry name=\"%s\">%s</entry>\n", (char*) ((JString*)entry->key)->xmlStringEncode(), (char*) ((JString*)entry->value)->xmlStringEncode());
02255 break;
02256 default:
02257 break;
02258 }
02259 entry = entry->next;
02260 }
02261 accessMutex->LeaveMutex();
02262 }
02263 else {
02264 printf("******* Access Denied 22 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
02265 }
02266
02267 if (xml.length() > 0)
02268 return (JString::format("<%s>\n%s</%s>", (char*) type, (char*) xml.indentXML(), (char*) type));
02269 else
02270 return (JString::format("<%s />", (char*) type));
02271
02272 }
02273
02274 bool ObjectTable::fromXML(const JString& xml) {
02275
02276 bool ret = false;
02277
02278 XMLParser* xmlParser = new XMLParser();
02279 xmlParser->parse(xml);
02280 ret = fromXML(xmlParser->getRootNode());
02281 delete(xmlParser);
02282 return ret;
02283 }
02284
02285 bool ObjectTable::fromXML(XMLNode* node) {
02286
02287 removeAll();
02288
02289 if (node == NULL)
02290 return false;
02291
02292 JString tag = node->getTag();
02293 JString subtag;
02294
02295 Object* object, *objectkey = NULL;
02296 XMLNode* xmlNode;
02297 ObjectCollection* col = node->getChildTags();
02298
02299 if (col != NULL) {
02300 for (int n=0; n<col->getCount(); n++) {
02301 if ( (xmlNode = (XMLNode*) col->get(n)) != NULL ) {
02302 subtag = xmlNode->getTag();
02303 if (subtag.equals("object")) {
02304 object = createObjectFromXML(xmlNode->getFirstChildNode());
02305 if (xmlNode->hasAttribute("name"))
02306 objectkey = xmlNode->getAttribute("name").clone();
02307 else
02308 objectkey = NULL;
02309 this->add(objectkey, object);
02310 objectkey = NULL;
02311 }
02312 else if (subtag.equals("entry")) {
02313 if (xmlNode->hasAttribute("value"))
02314 object = xmlNode->getAttribute("value").clone();
02315 else
02316 object = xmlNode->getTextContent().clone();
02317 if (xmlNode->hasAttribute("name"))
02318 objectkey = xmlNode->getAttribute("name").clone();
02319 else
02320 objectkey = NULL;
02321 this->add(objectkey, object);
02322 objectkey = NULL;
02323 }
02324 else if (subtag.equals("objectkey")) {
02325 objectkey = createObjectFromXML(xmlNode->getFirstChildNode());
02326 }
02327 else if ((objectkey != NULL) && (subtag.equals("objectvalue"))) {
02328 object = createObjectFromXML(xmlNode->getFirstChildNode());
02329 this->add(objectkey, object);
02330 objectkey = NULL;
02331 }
02332 }
02333 }
02334 }
02335 return true;
02336 }
02337
02338
02339
02340 JString ObjectTable::print() const {
02341 JString str;
02342 int n = 0;
02343
02344 str = "Number of entries: ";
02345 str += JString(count);
02346 str += "\n";
02347
02348 if (count == 0) return str;
02349
02350 str = "";
02351
02352 if (accessMutex->EnterMutex(5000)) {
02353 CollectionEntry* item = first;
02354 while (item != NULL) {
02355 str += JString(n);
02356 str += "\t";
02357 str += print(item);
02358 str += "\n";
02359 item = (CollectionEntry*) item->next;
02360 n++;
02361 }
02362 accessMutex->LeaveMutex();
02363 }
02364 else {
02365 printf("******* Access Denied 23 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
02366 }
02367
02368 return str;
02369 }
02370
02371 JString ObjectTable::printListLine(const JString& separator, const JString& equalsign, const JString& quotes) const {
02372 JString str;
02373 if (count == 0) return "";
02374
02375 int c = 0;
02376 if (accessMutex->EnterMutex(5000)) {
02377 CollectionEntry* item = first;
02378 while (item != NULL) {
02379 str += printEntry(item, equalsign, quotes);
02380 if (item->next != NULL)
02381 str += separator;
02382 item = (CollectionEntry*) item->next;
02383 c++;
02384 }
02385 accessMutex->LeaveMutex();
02386 }
02387 else {
02388 printf("******* Access Denied 24 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
02389 }
02390
02391 return str;
02392 }
02393
02394
02395 JString ObjectTable::print(const Object* key) const {
02396 const CollectionEntry* entry = getEntryKey(key);
02397 return(printEntry(entry));
02398 }
02399
02400 JString ObjectTable::printEntry(const CollectionEntry* item, const JString& separator, const JString& quotes) const {
02401 if (item == NULL) return "";
02402
02403 if (item->key != NULL)
02404 return JString::format("%s%s%s%s%s", (char*) item->key->print(), (char*) separator, (char*) quotes, (char*) item->value->print(), (char*) quotes);
02405 else
02406 return item->value->print();
02407 }
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419 bool ObjectTable::unitTest() {
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430 printf("\n Performance Tests:\n");
02431
02432 Dictionary dict;
02433 JString s;
02434 int n;
02435 JTime start;
02436
02437 for (n=0; n<100; n++) {
02438 dict.put(JString(n), JString(n));
02439 }
02440 dict.removeAll();
02441
02442 start = JTime();
02443 for (n=0; n<100; n++) {
02444 dict.put(JString(n), JString(n));
02445 }
02446 printf(" %s %s", (char*) JString("Creating Table .1k:", 20, 0), (char*) JString(JString::format("%.3fms", start.getMicroAge()/1000.0), 20, 1));
02447 printf("\n");
02448 dict.removeAll();
02449
02450 start = JTime();
02451 for (n=0; n<1000; n++) {
02452 dict.put(JString(n), JString(n));
02453 }
02454 printf(" %s %s", (char*) JString("Creating Table 1k:", 20, 0), (char*) JString(JString::format("%.3fms", start.getMicroAge()/1000.0), 20, 1));
02455 printf("\n");
02456 dict.removeAll();
02457
02458 start = JTime();
02459 for (n=0; n<10000; n++) {
02460 dict.put(JString(n), JString(n));
02461 }
02462 printf(" %s %s", (char*) JString("Creating Table 10k:", 20, 0), (char*) JString(JString::format("%.3fms", start.getMicroAge()/1000.0), 20, 1));
02463 printf("\n");
02464
02465 this->addUnitTestLog("Testing get by key...");
02466 start = JTime();
02467
02468 for (n=0; n<100; n++) {
02469 if (!dict.get("200").equals("200"))
02470 return false;
02471 if (!dict.get("500").equals("500"))
02472 return false;
02473 if (!dict.get("3200").equals("3200"))
02474 return false;
02475 if (!dict.get("3500").equals("3500"))
02476 return false;
02477 if (!dict.get("5200").equals("5200"))
02478 return false;
02479 if (!dict.get("5500").equals("5500"))
02480 return false;
02481 if (!dict.get("9200").equals("9200"))
02482 return false;
02483 if (!dict.get("9500").equals("9500"))
02484 return false;
02485 dict.get("11200");
02486 dict.get("11500");
02487 }
02488 printf(" %s %s", (char*) JString("Key Fetching:", 20, 0), (char*) JString(JString::format("%.3fms", start.getMicroAge()/1000.0), 20, 1));
02489 printf("\n");
02490
02491 this->addUnitTestLog("Testing get by pos...");
02492 start = JTime();
02493 for (n=0; n<100; n++) {
02494 dict.get(200);
02495 if (!dict.get(500).equals("500"))
02496 return false;
02497 if (!dict.get(3200).equals("3200"))
02498 return false;
02499 if (!dict.get(3500).equals("3500"))
02500 return false;
02501 if (!dict.get(5200).equals("5200"))
02502 return false;
02503 if (!dict.get(5500).equals("5500"))
02504 return false;
02505 if (!dict.get(9200).equals("9200"))
02506 return false;
02507 if (!dict.get(9500).equals("9500"))
02508 return false;
02509 dict.get(11200);
02510 dict.get(11500);
02511 }
02512 printf(" %s %s", (char*) JString("Pos Fetching:", 20, 0), (char*) JString(JString::format("%.3fms", start.getMicroAge()/1000.0), 20, 1));
02513 printf("\n");
02514
02515
02516
02517
02518
02519 ObjectTable table;
02520 table.sorting = SORTBYKEY | SORTREVERSE;
02521
02522 table.add(new JString("00"), new JString("00"));
02523 table.add(new JString("14"), new JString("14"));
02524 table.add(new JString("04"), new JString("04"));
02525 table.add(new JString("06"), new JString("06"));
02526 table.add(new JString("08"), new JString("08"));
02527 table.add(new JString("02"), new JString("02"));
02528 table.add(new JString("10"), new JString("10"));
02529 table.add(new JString("12"), new JString("12"));
02530 table.add(new JString("16"), new JString("16"));
02531 table.add(new JString("18"), new JString("18"));
02532 table.add(new JString("20"), new JString("20"));
02533
02534
02535 JString key = "09";
02536 CollectionEntry** entries = table.findClosestKeys(&key);
02537 if (entries[0] != NULL) {
02538 this->addUnitTestLog("Closest key failed by finding exact key...");
02539 return false;
02540 }
02541 if (entries[1] == NULL) {
02542 this->addUnitTestLog("Closest key failed by not finding lower key...");
02543 return false;
02544 }
02545 if (entries[2] == NULL) {
02546 this->addUnitTestLog("Closest key failed by not finding upper key...");
02547 return false;
02548 }
02549
02550
02551
02552
02553
02554
02555 delete [] entries;
02556
02557 JString k1 = JString(40);
02558 JString k2 = JString(15);
02559 ObjectCollection* coll = table.getAllBetweenKeys(&k1, &k2);
02560 if (coll == NULL) {
02561 this->addUnitTestLog("Found nothing between keys...");
02562 return false;
02563 }
02564 if (coll->getCount() != 3) {
02565 this->addUnitTestLog("Found wrong amount between keys...");
02566 return false;
02567 }
02568 delete(coll);
02569 coll = table.getAllBetween(&k1, &k2);
02570 if (coll != NULL) {
02571 this->addUnitTestLog("Found something between values...");
02572 return false;
02573 }
02574 delete(coll);
02575
02576 printf(" ");
02577
02578 return true;
02579 }
02580
02581 bool ObjectTable::addAll(const ObjectTable* c)
02582 {
02583
02584
02585 return addAll(c->first, false);
02586 }
02587
02588 bool ObjectTable::copyAll(const ObjectTable* c)
02589 {
02590
02591
02592 return addAll(c->first, true);
02593 }
02594
02595 bool ObjectTable::takeAll(ObjectTable* c)
02596 {
02597 if (!addAll(c->first, false))
02598 return false;
02599 c->removeAllNoDelete();
02600 return true;
02601 }
02602
02603 bool ObjectTable::addAll(const ObjectTable& c)
02604 {
02605
02606
02607 return addAll(c.first, false);
02608 }
02609
02610 bool ObjectTable::copyAll(const ObjectTable& c)
02611 {
02612
02613
02614 return addAll(c.first, true);
02615 }
02616
02617 bool ObjectTable::takeAll(ObjectTable& c)
02618 {
02619 if (!addAll(c.first, false))
02620 return false;
02621 c.removeAllNoDelete();
02622 return true;
02623 }
02624
02625 bool ObjectTable::addAll(const CollectionEntry* f, bool copy) {
02626 const CollectionEntry* e = f;
02627
02628 Object* keycopy;
02629
02630 if (accessMutex->EnterMutex(5000)) {
02631 while (e != NULL) {
02632 if (e->key == NULL)
02633 keycopy = NULL;
02634 else
02635 keycopy = e->key->clone();
02636
02637 if (copy)
02638 addBetweenEntries(last, NULL, keycopy, e->value->clone());
02639 else
02640 addBetweenEntries(last, NULL, keycopy, e->value);
02641 e = (CollectionEntry*) e->next;
02642 }
02643 accessMutex->LeaveMutex();
02644 }
02645 else {
02646 printf("******* Access Denied 25 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
02647 }
02648 return true;
02649 }
02650
02651
02652
02653
02654
02655
02656
02657
02658 unsigned long ObjectTable::getPayloadSize() const {
02659 long payloadSize = 0;
02660
02661 if (accessMutex->EnterMutex(5000)) {
02662 CollectionEntry* entry = first;
02663 while (entry != NULL) {
02664 if (entry->key != NULL )
02665 payloadSize += entry->key->getPayloadSize();
02666 if (entry->value != NULL )
02667 payloadSize += entry->value->getPayloadSize();
02668 entry = entry->next;
02669 }
02670 accessMutex->LeaveMutex();
02671 }
02672 else {
02673 printf("******* Access Denied 26a ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
02674 }
02675
02676 return payloadSize;
02677 }
02678
02679
02680 long ObjectTable::getBinarySize(int chunk) {
02681 int c;
02682 long pos = 0;
02683 if (accessMutex->EnterMutex(5000)) {
02684 CollectionEntry* entry = first;
02685 while (entry != NULL) {
02686 if (entry->value != NULL) {
02687 c = entry->value->getBinaryChunkCount();
02688 if ( (pos <= chunk) && (chunk < pos+c) ) {
02689 long binsize = entry->value->getBinarySize(chunk-pos);
02690 accessMutex->LeaveMutex();
02691 return binsize;
02692 }
02693 pos += c;
02694 }
02695 entry = entry->next;
02696 }
02697 accessMutex->LeaveMutex();
02698 }
02699 else
02700 printf("******* Access Denied 26.2 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
02701 return 0;
02702 }
02703
02704
02705 int ObjectTable::getBinaryChunkCount() {
02706 long c = 0;
02707 if (accessMutex->EnterMutex(5000)) {
02708 CollectionEntry* entry = first;
02709 while (entry != NULL) {
02710 if (entry->value != NULL)
02711 c += entry->value->getBinaryChunkCount();
02712 entry = entry->next;
02713 }
02714 accessMutex->LeaveMutex();
02715 }
02716 else
02717 printf("******* Access Denied 26.1 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
02718 return c;
02719 }
02720
02721
02722 long ObjectTable::toBinaryBuffer(int chunk, char* buffer, int maxlen) {
02723 int c;
02724 long pos = 0;
02725 if (accessMutex->EnterMutex(5000)) {
02726 CollectionEntry* entry = first;
02727 while (entry != NULL) {
02728 if (entry->value != NULL) {
02729 c = entry->value->getBinaryChunkCount();
02730 if ( (pos <= chunk) && (chunk < pos+c) ) {
02731 long binsize = entry->value->toBinaryBuffer(chunk-pos, buffer, maxlen);
02732 accessMutex->LeaveMutex();
02733 return binsize;
02734 }
02735 pos += c;
02736 }
02737 entry = entry->next;
02738 }
02739 accessMutex->LeaveMutex();
02740 }
02741 else
02742 printf("******* Access Denied 26.2 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
02743 return 0;
02744 }
02745
02746
02747 bool ObjectTable::fromBinaryBuffer(int chunk, char* buffer, long len) {
02748 int c;
02749 long pos = 0;
02750 if (accessMutex->EnterMutex(5000)) {
02751 CollectionEntry* entry = first;
02752 while (entry != NULL) {
02753 if (entry->value != NULL) {
02754 c = entry->value->getBinaryChunkCount();
02755 if ( (pos <= chunk) && (chunk < pos+c) ) {
02756 bool res = entry->value->fromBinaryBuffer(chunk-pos, buffer, len);
02757 accessMutex->LeaveMutex();
02758 return res;
02759 }
02760 pos += c;
02761 }
02762 entry = entry->next;
02763 }
02764 accessMutex->LeaveMutex();
02765 }
02766 else
02767 printf("******* Access Denied 26.2 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
02768 return 0;
02769 }
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796
02797 bool ObjectTable::sortKeysReverse() {
02798 if (count == 0)
02799 return true;
02800
02801 int j;
02802 CollectionEntry *temp1, *temp2;
02803 int st = -1;
02804 bool swapped;
02805
02806 if (accessMutex->EnterMutex(5000)) {
02807
02808 int limit = getCount();
02809
02810 while(st < limit) {
02811 swapped = false;
02812 st++;
02813 limit--;
02814
02815 for(j=st; j<limit; j++) {
02816 currentPos = -1;
02817 current = NULL;
02818 temp1 = ((ObjectTable*)this)->getEntry(j);
02819 temp2 = (CollectionEntry*) temp1->next;
02820 if(isKeyBigger(temp2, temp1)) {
02821 if (temp1->prev != NULL)
02822 temp1->prev->next = temp2;
02823 if (temp2->next != NULL)
02824 temp2->next->prev = temp1;
02825 temp2->prev = temp1->prev;
02826 temp1->next = temp2->next;
02827 temp2->next = temp1;
02828 temp1->prev = temp2;
02829 if (first == temp1)
02830 first = temp2;
02831 if (last == temp2)
02832 last = temp1;
02833 swapped = true;
02834 }
02835 }
02836
02837
02838 if(!swapped) {
02839 accessMutex->LeaveMutex();
02840 return true;
02841 }
02842 swapped = false;
02843
02844
02845 for(j=limit-1; j>=st; --j) {
02846 currentPos = -1;
02847 current = NULL;
02848 temp1 = ((ObjectTable*)this)->getEntry(j);
02849 temp2 = (CollectionEntry*) temp1->next;
02850 if(isKeyBigger(temp2, temp1)) {
02851 if (temp1->prev != NULL)
02852 temp1->prev->next = temp2;
02853 if (temp2->next != NULL)
02854 temp2->next->prev = temp1;
02855 temp2->prev = temp1->prev;
02856 temp1->next = temp2->next;
02857 temp2->next = temp1;
02858 temp1->prev = temp2;
02859 if (first == temp1)
02860 first = temp2;
02861 if (last == temp2)
02862 last = temp1;
02863 swapped = true;
02864 }
02865 }
02866
02867
02868 if(!swapped) {
02869 accessMutex->LeaveMutex();
02870 return true;
02871 }
02872 }
02873 accessMutex->LeaveMutex();
02874 }
02875 else {
02876 printf("******* Access Denied 27 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
02877 }
02878
02879 return true;
02880 }
02881
02882 bool ObjectTable::sortKeys() {
02883 if (count == 0)
02884 return true;
02885
02886 int j;
02887 CollectionEntry *temp1, *temp2;
02888 int st = -1;
02889 bool swapped;
02890
02891 if (accessMutex->EnterMutex(5000)) {
02892
02893 int limit = getCount();
02894
02895 while(st < limit) {
02896 swapped = false;
02897 st++;
02898 limit--;
02899
02900 for(j=st; j<limit; j++) {
02901 currentPos = -1;
02902 current = NULL;
02903 temp1 = ((ObjectTable*)this)->getEntry(j);
02904 temp2 = (CollectionEntry*) temp1->next;
02905 if(isKeyBigger(temp1, temp2)) {
02906 if (temp1->prev != NULL)
02907 temp1->prev->next = temp2;
02908 if (temp2->next != NULL)
02909 temp2->next->prev = temp1;
02910 temp2->prev = temp1->prev;
02911 temp1->next = temp2->next;
02912 temp2->next = temp1;
02913 temp1->prev = temp2;
02914 if (first == temp1)
02915 first = temp2;
02916 if (last == temp2)
02917 last = temp1;
02918 swapped = true;
02919 }
02920 }
02921
02922
02923 if(!swapped) {
02924 accessMutex->LeaveMutex();
02925 return true;
02926 }
02927 swapped = false;
02928
02929
02930 for(j=limit-1; j>=st; --j) {
02931 currentPos = -1;
02932 current = NULL;
02933 temp1 = ((ObjectTable*)this)->getEntry(j);
02934 temp2 = (CollectionEntry*) temp1->next;
02935 if(isKeyBigger(temp1, temp2)) {
02936 if (temp1->prev != NULL)
02937 temp1->prev->next = temp2;
02938 if (temp2->next != NULL)
02939 temp2->next->prev = temp1;
02940 temp2->prev = temp1->prev;
02941 temp1->next = temp2->next;
02942 temp2->next = temp1;
02943 temp1->prev = temp2;
02944 if (first == temp1)
02945 first = temp2;
02946 if (last == temp2)
02947 last = temp1;
02948 swapped = true;
02949 }
02950 }
02951
02952
02953 if(!swapped) {
02954 accessMutex->LeaveMutex();
02955 return true;
02956 }
02957 }
02958 accessMutex->LeaveMutex();
02959 }
02960 else {
02961 printf("******* Access Denied 28 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
02962 }
02963
02964 return true;
02965 }
02966
02967 bool ObjectTable::sortValues() {
02968 if (count == 0)
02969 return true;
02970
02971 int j;
02972 CollectionEntry *temp1, *temp2;
02973 int st = -1;
02974 bool swapped;
02975
02976 if (accessMutex->EnterMutex(5000)) {
02977 int limit = getCount();
02978 while(st < limit) {
02979 swapped = false;
02980 st++;
02981 limit--;
02982
02983 for(j=st; j<limit; j++) {
02984 currentPos = -1;
02985 current = NULL;
02986 temp1 = ((ObjectTable*)this)->getEntry(j);
02987 temp2 = (CollectionEntry*) temp1->next;
02988 if(isValueBigger(temp1, temp2)) {
02989 if (temp1->prev != NULL)
02990 ((CollectionEntry*)(temp1->prev))->next = temp2;
02991 if (temp2->next != NULL)
02992 ((CollectionEntry*)(temp2->next))->prev = temp1;
02993 temp2->prev = temp1->prev;
02994 temp1->next = temp2->next;
02995 temp2->next = temp1;
02996 temp1->prev = temp2;
02997 if (first == temp1)
02998 first = temp2;
02999 if (last == temp2)
03000 last = temp1;
03001 swapped = true;
03002 }
03003 }
03004
03005
03006 if(!swapped) {
03007 accessMutex->LeaveMutex();
03008 return true;
03009 }
03010 swapped = false;
03011
03012
03013 for(j=limit-1; j>=st; --j) {
03014 currentPos = -1;
03015 current = NULL;
03016 temp1 = ((ObjectTable*)this)->getEntry(j);
03017 temp2 = (CollectionEntry*) temp1->next;
03018 if(isValueBigger(temp1, temp2)) {
03019 if (temp1->prev != NULL)
03020 ((CollectionEntry*)(temp1->prev))->next = temp2;
03021 if (temp2->next != NULL)
03022 ((CollectionEntry*)(temp2->next))->prev = temp1;
03023 temp2->prev = temp1->prev;
03024 temp1->next = temp2->next;
03025 temp2->next = temp1;
03026 temp1->prev = temp2;
03027 if (first == temp1)
03028 first = temp2;
03029 if (last == temp2)
03030 last = temp1;
03031 swapped = true;
03032 }
03033 }
03034
03035
03036 if(!swapped) {
03037 accessMutex->LeaveMutex();
03038 return true;
03039 }
03040 }
03041 accessMutex->LeaveMutex();
03042 }
03043 else {
03044 printf("******* Access Denied 29 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
03045 }
03046
03047 return true;
03048 }
03049
03050 bool ObjectTable::sortValuesReverse() {
03051 if (count == 0)
03052 return true;
03053
03054 int j;
03055 CollectionEntry *temp1, *temp2;
03056 int st = -1;
03057 bool swapped;
03058
03059 if (accessMutex->EnterMutex(5000)) {
03060 int limit = getCount();
03061 while(st < limit) {
03062 swapped = false;
03063 st++;
03064 limit--;
03065
03066 for(j=st; j<limit; j++) {
03067 currentPos = -1;
03068 current = NULL;
03069 temp1 = ((ObjectTable*)this)->getEntry(j);
03070 temp2 = (CollectionEntry*) temp1->next;
03071 if(isValueBigger(temp2, temp1)) {
03072 if (temp1->prev != NULL)
03073 ((CollectionEntry*)(temp1->prev))->next = temp2;
03074 if (temp2->next != NULL)
03075 ((CollectionEntry*)(temp2->next))->prev = temp1;
03076 temp2->prev = temp1->prev;
03077 temp1->next = temp2->next;
03078 temp2->next = temp1;
03079 temp1->prev = temp2;
03080 if (first == temp1)
03081 first = temp2;
03082 if (last == temp2)
03083 last = temp1;
03084 swapped = true;
03085 }
03086 }
03087
03088
03089 if(!swapped) {
03090 accessMutex->LeaveMutex();
03091 return true;
03092 }
03093 swapped = false;
03094
03095
03096 for(j=limit-1; j>=st; --j) {
03097 currentPos = -1;
03098 current = NULL;
03099 temp1 = ((ObjectTable*)this)->getEntry(j);
03100 temp2 = (CollectionEntry*) temp1->next;
03101 if(isValueBigger(temp2, temp1)) {
03102 if (temp1->prev != NULL)
03103 ((CollectionEntry*)(temp1->prev))->next = temp2;
03104 if (temp2->next != NULL)
03105 ((CollectionEntry*)(temp2->next))->prev = temp1;
03106 temp2->prev = temp1->prev;
03107 temp1->next = temp2->next;
03108 temp2->next = temp1;
03109 temp1->prev = temp2;
03110 if (first == temp1)
03111 first = temp2;
03112 if (last == temp2)
03113 last = temp1;
03114 swapped = true;
03115 }
03116 }
03117
03118
03119 if(!swapped) {
03120 accessMutex->LeaveMutex();
03121 return true;
03122 }
03123 }
03124 accessMutex->LeaveMutex();
03125 }
03126 else {
03127 printf("******* Access Denied 30 ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
03128 }
03129
03130 return true;
03131 }
03132
03133 bool ObjectTable::sortRandomMix() {
03134 if (count == 0)
03135 return true;
03136
03137 int count, p;
03138 Object* value;
03139
03140 ObjectTable newTable;
03141 if (accessMutex->EnterMutex(5000)) {
03142 while ( (count = this->getCount()) > 0) {
03143 if (count == 2) break;
03144 p = (int)(Object::getRandomNumber() * count);
03145 if ( (value = this->get(p)) != NULL ) {
03146 newTable.addLast(this->getKey(p), value);
03147 this->removeNoDelete(p);
03148 }
03149 }
03150 if ( (value = this->get(1)) != NULL ) {
03151 newTable.addLast(this->getKey(1), value);
03152 this->removeNoDelete(1);
03153 }
03154 if ( (value = this->get(0)) != NULL ) {
03155 newTable.addLast(this->getKey(0), value);
03156 this->removeNoDelete(0);
03157 }
03158 this->removeAll();
03159 this->takeAll(newTable);
03160 accessMutex->LeaveMutex();
03161 }
03162 else {
03163 printf("******* Access Denied 29a ********\n%s\n\n", (char*) JThread::getProgramTrace().printListLine("\n"));
03164 }
03165
03166 return true;
03167 }
03168
03169
03170
03171
03172 bool ObjectTable::isKeyBigger(CollectionEntry* entry1, CollectionEntry* entry2) {
03173 if ( (entry1 == NULL) || (entry1->key == NULL) )
03174 return false;
03175 if ( (entry2 == NULL) || (entry2->key == NULL) )
03176 return true;
03177 if (entry1->key->compare(entry2->key) > 0)
03178 return true;
03179 else
03180 return false;
03181 }
03182
03183 bool ObjectTable::isValueBigger(CollectionEntry* entry1, CollectionEntry* entry2) {
03184 if (entry1->value->compare(entry2->value) > 0)
03185 return true;
03186 else
03187 return false;
03188 }
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209
03210
03211
03212
03213
03214
03215
03216
03217 static const unsigned int primenumbers[] = {
03218 53, 97, 193, 389, 769, 1543, 3079, 6151,
03219 12289, 24593, 49157, 98317, 196613, 393241,
03220 786433, 1572869, 3145739, 6291469, 12582917,
03221 25165843, 50331653, 100663319, 201326611,
03222 402653189, 805306457, 1610612741};
03223
03224 const double maximum_fill = 0.65;
03225 const unsigned int primelen = sizeof(primenumbers)/sizeof(primenumbers[0]);
03226
03227
03228 struct HashTable *create_hashtable(unsigned int minsize) {
03229 struct HashTable *h;
03230 unsigned int pindex, size = primenumbers[0];
03231
03232 if (minsize > (1u << 30)) return NULL;
03233
03234 for (pindex=0; pindex < primelen; pindex++) {
03235 if (primenumbers[pindex] > minsize) { size = primenumbers[pindex]; break; }
03236 }
03237 h = (struct HashTable *)malloc(sizeof(struct HashTable));
03238 if (NULL == h) return NULL;
03239 h->table = (struct HashEntry **)malloc(sizeof(struct HashEntry*) * size);
03240 if (NULL == h->table) { free(h); return NULL; }
03241 memset(h->table, 0, size * sizeof(struct HashEntry *));
03242 h->length = size;
03243 h->prime = pindex;
03244 h->count = 0;
03245 h->limit = (unsigned int) ceil(size * maximum_fill);
03246 return h;
03247 }
03248
03249
03250 unsigned long hash(unsigned long hashkey) {
03251 unsigned long i = hashkey;
03252 i += ~(i << 9);
03253 i ^= ((i >> 14) | (i << 18));
03254 i += (i << 4);
03255 i ^= ((i >> 10) | (i << 22));
03256 return i;
03257 }
03258
03259
03260 static int hashtable_expand(struct HashTable *h) {
03261
03262 struct HashEntry **newtable;
03263 struct HashEntry *e;
03264 struct HashEntry **pE;
03265 unsigned int newsize, i, index;
03266
03267 if (h->prime == (primelen - 1)) return 0;
03268 newsize = primenumbers[++(h->prime)];
03269
03270 newtable = (struct HashEntry **)malloc(sizeof(struct HashEntry*) * newsize);
03271 if (NULL != newtable)
03272 {
03273 memset(newtable, 0, newsize * sizeof(struct HashEntry *));
03274
03275
03276 for (i = 0; i < h->length; i++) {
03277 while (NULL != (e = h->table[i])) {
03278 h->table[i] = e->next;
03279 index = hash2index(newsize,e->hash);
03280 e->next = newtable[index];
03281 newtable[index] = e;
03282 }
03283 }
03284 free(h->table);
03285 h->table = newtable;
03286 }
03287
03288 else
03289 {
03290 newtable = (struct HashEntry **)
03291 realloc(h->table, newsize * sizeof(struct HashEntry *));
03292 if (NULL == newtable) { (h->prime)--; return 0; }
03293 h->table = newtable;
03294 memset(newtable[h->length], 0, newsize - h->length);
03295 for (i = 0; i < h->length; i++) {
03296 for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
03297 index = hash2index(newsize,e->hash);
03298 if (index == i)
03299 {
03300 pE = &(e->next);
03301 }
03302 else
03303 {
03304 *pE = e->next;
03305 e->next = newtable[index];
03306 newtable[index] = e;
03307 }
03308 }
03309 }
03310 }
03311 h->length = newsize;
03312 h->limit = (unsigned int) ceil(newsize * maximum_fill);
03313 return -1;
03314 }
03315
03316
03317 unsigned int hashtable_count(const struct HashTable *h) {
03318 return h->count;
03319 }
03320
03321
03322 bool hashtable_insert_key(struct HashTable *h, CollectionEntry* entry) {
03323 if ( (entry == NULL) || (entry->key == NULL)) return false;
03324
03325 unsigned int index;
03326 struct HashEntry *e;
03327 if (++(h->count) > h->limit) {
03328
03329
03330
03331
03332 hashtable_expand(h);
03333 }
03334 e = (struct HashEntry *)malloc(sizeof(struct HashEntry));
03335 if (NULL == e) { --(h->count); return false; }
03336 e->hash = hash(entry->key->getHash());
03337 index = hash2index(h->length,e->hash);
03338 e->entry = entry;
03339 e->next = h->table[index];
03340 h->table[index] = e;
03341 entry->keyhash = e->hash;
03342 return true;
03343 }
03344
03345 bool hashtable_insert_value(struct HashTable *h, CollectionEntry* entry) {
03346 if ( (entry == NULL) || (entry->value == NULL)) return false;
03347
03348 unsigned int index;
03349 struct HashEntry *e;
03350 if (++(h->count) > h->limit)
03351 {
03352
03353
03354
03355
03356 hashtable_expand(h);
03357 }
03358 e = (struct HashEntry *)malloc(sizeof(struct HashEntry));
03359 if (NULL == e) { --(h->count); return 0; }
03360 e->hash = hash(entry->value->getHash());
03361 index = hash2index(h->length,e->hash);
03362 e->entry = entry;
03363 e->next = h->table[index];
03364 h->table[index] = e;
03365 entry->valuehash = e->hash;
03366 return true;
03367 }
03368
03369
03370 CollectionEntry* hashtable_search_key(const struct HashTable *h, const Object* key) {
03371 if (key == NULL) return NULL;
03372 struct HashEntry *e;
03373 unsigned long hashvalue;
03374 unsigned int index;
03375 hashvalue = hash(key->getHash());
03376 index = hash2index(h->length,hashvalue);
03377 e = h->table[index];
03378 while (NULL != e)
03379 {
03380
03381 if ((hashvalue == e->hash) && (e->entry->key->equals(key)))
03382 return e->entry;
03383 e = e->next;
03384 }
03385 return NULL;
03386 }
03387
03388 CollectionEntry* hashtable_search_value(const struct HashTable *h, const Object* value) {
03389 if (value == NULL) return NULL;
03390 struct HashEntry *e;
03391 unsigned long hashvalue;
03392 unsigned int index;
03393 hashvalue = hash(value->getHash());
03394 index = hash2index(h->length,hashvalue);
03395 e = h->table[index];
03396 while (NULL != e)
03397 {
03398
03399 if ((hashvalue == e->hash) && (e->entry->value->equals(value))) {
03400 return e->entry;
03401 }
03402 e = e->next;
03403 }
03404 return NULL;
03405 }
03406
03407 ObjectCollection* hashtable_search_values(const struct HashTable *h, const Object* value) {
03408 if (value == NULL) return NULL;
03409 struct HashEntry *e;
03410 unsigned long hashvalue;
03411 unsigned int index;
03412 hashvalue = hash(value->getHash());
03413 index = hash2index(h->length,hashvalue);
03414 e = h->table[index];
03415 ObjectCollection* coll = new ObjectCollection();
03416 coll->noDelete();
03417 while (NULL != e)
03418 {
03419
03420 if ((hashvalue == e->hash) && (e->entry->value->equals(value))) {
03421 coll->add(e->entry);
03422 }
03423 e = e->next;
03424 }
03425 if (coll->getCount() == 0) {
03426 delete(coll); coll = NULL;
03427 }
03428 return coll;
03429 }
03430
03431
03432 bool hashtable_remove_key(struct HashTable *h, const CollectionEntry* entry) {
03433
03434
03435
03436 if (entry == NULL) return false;
03437 struct HashEntry *e;
03438 struct HashEntry **pE;
03439 unsigned int index;
03440
03441 index = hash2index(h->length,entry->keyhash);
03442 pE = &(h->table[index]);
03443 e = *pE;
03444 while (NULL != e)
03445 {
03446
03447 if ((entry->keyhash == e->hash) && (e->entry == entry))
03448 {
03449 *pE = e->next;
03450 h->count--;
03451 free(e);
03452 return true;
03453 }
03454 pE = &(e->next);
03455 e = e->next;
03456 }
03457 return false;
03458 }
03459
03460 bool hashtable_remove_value(struct HashTable *h, const CollectionEntry* entry) {
03461
03462
03463
03464 if (entry == NULL) return false;
03465 struct HashEntry *e;
03466 struct HashEntry **pE;
03467 unsigned int index;
03468
03469 index = hash2index(h->length,entry->valuehash);
03470 pE = &(h->table[index]);
03471 e = *pE;
03472 while (NULL != e)
03473 {
03474
03475 if ((entry->valuehash == e->hash) && (e->entry == entry))
03476 {
03477 *pE = e->next;
03478 h->count--;
03479 free(e);
03480 return true;
03481 }
03482 pE = &(e->next);
03483 e = e->next;
03484 }
03485 return false;
03486 }
03487
03488
03489
03490 void hashtable_destroy(struct HashTable *h) {
03491 unsigned int i;
03492 struct HashEntry *e, *f;
03493 struct HashEntry **table = h->table;
03494 for (i = 0; i < h->length; i++) {
03495 e = table[i];
03496 while (NULL != e) {
03497 f = e;
03498 e = e->next;
03499 free(f);
03500 }
03501 }
03502 free(h->table);
03503 free(h);
03504 }
03505
03506
03507 }