NodePtr Node::concat_with(NodePtr other) { NodePtr result = concat(this, other); #ifdef SLOW_ASSERTS assert(result->as_string() == this->as_string()+other->as_string()); #endif return result; }
NodePtr concat(NodePtr left, NodePtr right) { if (//left->is_leaf() && right->is_leaf() && left->length() + right->length() <= CONCAT_THRESHOLD) return new Leaf(left->as_string()+right->as_string()); int new_key = rand()%MAX_HEAP_KEY; return merge(new_key, left, right); //return new InnerNode(std::min(left->heap_key, right->heap_key), left, right); // unbalanced implementation }
bool check_node(NodePtr node) { std::string s = node->as_string(); assert(s.length() == node->length()); Iterator iter = Iterator(node); for (std::string::iterator i = s.begin(); i != s.end(); i++, iter.advance(1)) assert(iter.current() == *i); assert(!iter.valid); return true; }
NodePtr merge(int new_key, NodePtr left, NodePtr right) { if (left->length()+right->length() <= CONCAT_THRESHOLD) return new Leaf(left->as_string()+right->as_string()); if (new_key <= left->heap_key && new_key <= right->heap_key) return new InnerNode(new_key, left, right); if (left->heap_key < right->heap_key || left->heap_key == right->heap_key && (rand()%2)) { assert(!left->is_leaf()); return new InnerNode( left->heap_key, ((InnerNode*)left)->left, merge(new_key, ((InnerNode*)left)->right, right) ); } else { assert(!right->is_leaf()); return new InnerNode( right->heap_key, merge(new_key, left, ((InnerNode*)right)->left), ((InnerNode*)right)->right); } }
void test() { NodePtr hello = new Leaf("hello"); NodePtr world = new Leaf("world"); //check_node(hello); NodePtr hw = hello->concat_with(world); //hw->debug_print(); check_node(hw); //concatenation for (int i = 0; i<100; i++) { if (i%20 == 0) std::cout<<i<<std::endl; hw = hw->concat_with(hello); //hw->debug_print(); assert(check_node(hw)); } assert(check_node(hw)); hw->debug_print(); //random access for (int i = 0; i<100; i++) { Iterator iter = Iterator(hw); int pos = 0; std::string s = hw->as_string(); while (pos < hw->length()) { //std::cout<<pos<<" "; assert(s[pos] == iter.current()); int d = rand()%100; pos += d; iter.advance(d); } assert(!iter.valid); //std::cout<<std::endl; } //slices for (int i = 0; i<100; i++) { int begin = rand()%(hw->length()+1); int end = begin+rand()%(hw->length()-begin+1); NodePtr slice = hw->slice(begin, end); assert(check_node(slice)); std::cout<<begin<<" "<<end<<std::endl; } std::cout<<"hw depth "<<hw->depth()<<std::endl; }