bool ISTree::modify(int _key, const char* _str, unsigned _len) { if (_key < 0) { printf("error in ISTree-modify: empty string\n"); return false; } this->CopyToTransfer(_str, _len, 2); //not check value const Bstr* val = &(this->transfer[2]); this->request = 0; int store; ISNode* ret = this->find(_key, &store, true); if (ret == NULL || store == -1 || _key != ret->getKey(store)) //tree is empty or not found { cerr<<"tree is empty or not found"<<endl; return false; } //cout<<"ISTree::modify() - key is found, now to remove"<<endl; unsigned len = ret->getValue(store)->getLen(); ret->setValue(val, store, true); //cout<<"value reset"<<endl; //cout<<"newlen: "<<val->getLen()<<" oldlen: "<<len<<endl; //request += (val->getLen() - len); this->request = val->getLen(); this->request -= len; ret->setDirty(); //cout<<"to request"<<endl; this->TSM->request(request); //cout<<"memory requested"<<endl; return true; }
bool ISTree::search(unsigned _key, char*& _str, unsigned& _len) { //DEBUG //if (_key < 0) //{ //printf("error in ISTree-search: empty string\n"); //return false; //} this->request = 0; int store; ISNode* ret = this->find(_key, &store, false); //cout<<"to find the position: "<<store<<endl; if (ret == NULL || store == -1 || _key != ret->getKey(store)) //tree is empty or not found { return false; } const Bstr* val = ret->getValue(store); //this->CopyToTransfer(val->getStr(), val->getLen(), 0); //not sum to request //_str = this->transfer[0].getStr(); //_len = this->transfer[0].getLen(); _str = val->getStr(); _len = val->getLen(); char* debug = new char[_len]; memcpy(debug, _str, _len); // debug[_len] = '\0'; _str = debug; //if(_key==62) //{ //cout<<"check in search: "<<string(_str, _len)<<endl; //} this->TSM->request(request); //if(_key==62) //{ //cout<<"check in search: "<<string(_str, _len)<<endl; //} return true; }
bool ISTree::search(int _key, char*& _str, int& _len) { if (_key < 0) { //printf("error in ISTree-search: empty string\n"); return false; } this->request = 0; int store; ISNode* ret = this->find(_key, &store, false); if (ret == NULL || store == -1 || _key != ret->getKey(store)) //tree is empty or not found { return false; } const Bstr* val = ret->getValue(store); this->CopyToTransfer(val->getStr(), val->getLen(), 0); //not sum to request _str = this->transfer[0].getStr(); _len = this->transfer[0].getLen(); this->TSM->request(request); return true; }
bool //special case: not exist, one-edge-case ISTree::range_query(int _key1, int _key2) { //the range is: *_key1 <= x < *_key2 //if(_key1 <0 && _key2 <0) //return false; //ok to search one-edge, requiring only one be negative //find and write value int store1, store2; ISNode *p1, *p2; if (_key1 >= 0) { request = 0; p1 = this->find(_key1, &store1, false); if (p1 == NULL || store1 == -1) return false; //no element this->TSM->request(request); } else { p1 = this->leaves_head; store1 = 0; } if (_key2 >= 0) { //QUERY: another strategy is to getnext and compare every time to tell end request = 0; p2 = this->find(_key2, &store2, false); if (p2 == NULL) return false; else if (store2 == -1) store2 = p2->getNum(); else if (store2 == 0) { p2 = p2->getPrev(); if (p2 == NULL) return false; //no element store2 = p2->getNum(); } this->TSM->request(request); } else { p2 = this->leaves_tail; store2 = p2->getNum(); } ISNode* p = p1; unsigned i, l, r; //get the num of answers first, not need to prepare the node unsigned ansNum = 0; while (true) { //request = 0; //this->prepare(p); if (p == p1) l = store1; else l = 0; if (p == p2) r = store2; else r = p->getNum(); ansNum += (r - l); //this->TSM->request(request); if (p != p2) p = p->getNext(); else break; } if (this->stream != NULL) { delete this->stream; this->stream = NULL; } vector<int> keys; vector<bool> desc; this->stream = new Stream(keys, desc, ansNum, 1, false); p = p1; while (1) { request = 0; this->prepare(p); if (p == p1) l = store1; else l = 0; if (p == p2) r = store2; else r = p->getNum(); for (i = l; i < r; ++i) { //NOTICE:Bstr* in an array, used as Bstr[] this->stream->write(p->getValue(i)); } this->TSM->request(request); if (p != p2) p = p->getNext(); else break; } this->stream->setEnd(); return true; }
bool ISTree::remove(int _key) { if (_key < 0) { printf("error in ISTree-remove: empty string\n"); return false; } this->request = 0; ISNode* ret; if (this->root == NULL) //tree is empty return false; ISNode* p = this->root; ISNode* q; int i, j; while (!p->isLeaf()) { j = p->getNum(); //for(i = 0; i < j; ++i) //if(bstr < *(p->getKey(i))) //break; i = p->searchKey_less(_key); q = p->getChild(i); this->prepare(q); if (q->getNum() < ISNode::MIN_CHILD_NUM) //==MIN_KEY_NUM { if (i > 0) this->prepare(p->getChild(i - 1)); if (i < j) this->prepare(p->getChild(i + 1)); ret = q->coalesce(p, i); if (ret != NULL) this->TSM->updateHeap(ret, 0, true);//non-sense node this->TSM->updateHeap(q, q->getRank(), true); if (q->isLeaf()) { if (q->getPrev() == NULL) this->leaves_head = q; if (q->getNext() == NULL) this->leaves_tail = q; } if (p->getNum() == 0) //root shrinks { //this->leaves_head = q; this->root = q; this->TSM->updateHeap(p, 0, true); //instead of delete p this->height--; } } else p->setDirty(); this->TSM->updateHeap(p, p->getRank(), true); p = q; } bool flag = false; //j = p->getNum(); //LeafNode(maybe root) //for(i = 0; i < j; ++i) // if(bstr == *(p->getKey(i))) // { // request -= p->getKey(i)->getLen(); // request -= p->getValue(i)->getLen(); // p->subKey(i, true); //to release // p->subValue(i, true); //to release // p->subNum(); // if(p->getNum() == 0) //root leaf 0 key // { // this->root = NULL; // this->leaves_head = NULL; // this->leaves_tail = NULL; // this->height = 0; // this->TSM->updateHeap(p, 0, true); //instead of delete p // } // p->setDirty(); // flag = true; // break; // } i = p->searchKey_equal(_key); //WARN+NOTICE:here must check, because the key to remove maybe not exist if (i != (int)p->getNum()) { request -= p->getValue(i)->getLen(); p->subKey(i); //to release p->subValue(i, true); //to release p->subNum(); if (p->getNum() == 0) //root leaf 0 key { this->root = NULL; this->leaves_head = NULL; this->leaves_tail = NULL; this->height = 0; this->TSM->updateHeap(p, 0, true); //instead of delete p } p->setDirty(); flag = true; } this->TSM->request(request); return flag; //i == j, not found }