// Deletes an entry from the B+ tree. node * delete_entry( node * root, node * n, int key, void * pointer ) { int min_keys; node * neighbor; int neighbor_index; int k_prime_index, k_prime; int capacity; // Remove key and pointer from node. n = remove_entry_from_node(n, key, pointer); /* Case: deletion from the root. */ if (n == root) return adjust_root(root); // Case: deletion from a node below the root. // Determine minimum allowable size of node, to be preserved after deletion. min_keys = n->is_leaf ? cut(order - 1) : cut(order) - 1; // Case: node stays at or above minimum. if (n->num_keys >= min_keys) return root; /* Find the appropriate neighbor node with which * to merge. * Also find the key (k_prime) in the parent * between the pointer to node n and the pointer * to the neighbor. */ neighbor_index = get_neighbor_index( n ); k_prime_index = neighbor_index == -1 ? 0 : neighbor_index; k_prime = n->parent->keys[k_prime_index]; neighbor = neighbor_index == -1 ? n->parent->pointers[1] : n->parent->pointers[neighbor_index]; capacity = n->is_leaf ? order : order - 1; /* mergence. */ if (neighbor->num_keys + n->num_keys < capacity) return merge_nodes(root, n, neighbor, neighbor_index, k_prime); /* Redistribution. */ else return redistribute_nodes(root, n, neighbor, neighbor_index, k_prime_index, k_prime); }
static off_t merge_nodes(brtr_t *b, off_t left, off_t right) { off_t id = 0; struct brtr_node *l; if ((l = brtr_node(b, left)) != NULL) { struct brtr_node *r; if ((r = brtr_node(b, right)) != NULL) { if (l->c > r->c) id = set_right(b, left, merge_nodes(b, l->right, right)); else id = set_left(b, right, merge_nodes(b, left, r->left)); } else id = left; } else id = right; return id; }
/*void merge_nodes(QNode *ag, QNode *it) { if ((ag->children != 0) && (it->children !=0)) { for (int i=0; i<Globals::pow2dim; i++) { merge_nodes(ag->children[0] + i, it->children[0] + i); } } else if ((ag->children == 0) && (it->children !=0)) { if (ag->representatives != 0) { ag->remove_representatives(); } ag->bear_children(); for (int i=0; i<Globals::pow2dim; i++) { merge_nodes(ag->children[0] + i, it->children[0] + i); } } else if ((ag->children==0) && (it->children==0)) { myset union_reprs; if (ag->representatives!=0) { for (myset::iterator i = ag->representatives[0].begin(); i != ag->representatives[0].end(); i++) { union_reprs.insert(*i); } } if (it->representatives!=0) { for (myset::iterator i = it->representatives[0].begin(); i != it->representatives[0].end(); i++) { union_reprs.insert(*i); } } if (Globals::sets[0].count(union_reprs) == 0) { ag->representatives = new myset(union_reprs); Globals::sets[0][union_reprs] = ag->representatives; } else { ag->representatives = Globals::sets[0][union_reprs]; } //std::cout << union_reprs.size() << " " << ag->representatives[0].size() << std::endl; } }*/ void merge_nodes(QNode *ag, QNode *it) { if ((ag->depth != 0) && (it->depth != 0)) { ag->depth = std::max(ag->depth,it->depth); } else if ((ag->depth == 0) && (it->depth != 0)) { if (ag->children != 0) { std::cout << "error merging?" <<std::endl; } ag->depth = it->depth; //MERGE with previous } else if ((ag->children==0) && (it->children==0)) { for (int i=0; i<Globals::pow2dim; i++) { merge_nodes(ag->children[0]+i,it->children[0]+i); } } }
int find_min_cut(int **adj_list, int *lengths, int adj_list_len) { int nodes_num = adj_list_len; while(nodes_num > 2) { int node_1, node_2; do { node_1 = get_rand_int(adj_list_len); } while(lengths[node_1] == 0); node_2 = adj_list[node_1][ get_rand_int(lengths[node_1]) ]; merge_nodes(adj_list, lengths, adj_list_len, node_1, node_2); --nodes_num; } /* find cut */ int i; for(i = 0; lengths[i] == 0; ++i) ; return lengths[i]; }
// delete the specified key from the Btree RC deleteKey(BTreeHandle *tree, Value *key) { Btree* leaf = NULL; // get the desired leaf leaf = find_leaf(tree, key); // get the left node Btree* childLeft = NULL; childLeft = leaf->prev; // get the tree stastistics data Btree_stat *info = NULL; info = tree->mgmtData; if (leaf != NULL) { if (childLeft == NULL) { // no child // delete the entry and adjust the tree if needed delete_entry(tree, leaf, key); // done return RC_OK; } if (key->v.intV == leaf->keys[0]) { // the key exists in this leaf node // delete it delete_entry(tree, leaf, key); // check if there is underflow in the node capacity if (leaf->num_keys == 0) { // merge with the left sibling childLeft->next = leaf->next; // check if we need to propagate this change up the tree delete_parent_nodes_inital(info, leaf, key); // done return RC_OK; } // update the prent node updateFirst(leaf, key); return RC_OK; } else { delete_entry(tree, leaf, key); if (leaf) { // see of there is underflow if (checkUnderflow(info, leaf)) { // if yes, merge with left sibling if (childLeft) { // check the number of keys even after splitting if (childLeft->num_keys > splitNode(info->order) && childLeft->num_keys != info->order) { // we need to redistribute the keys // to balance out redistribute(info, childLeft, leaf); } else { // just merge merge_nodes(info, childLeft, leaf); } } } } return RC_OK; } } // all ok return RC_OK; }
int _tmain(int argc, _TCHAR* argv[]) { #ifdef WIN32 _fmode = _O_BINARY; #endif printf("This is QSplatMake version %s.\n", QSPLATMAKE_VERSION); // Parse command-line params //strncasecmp(char*s1,char*s2,size_t n):compare first n chars of s1 and s2 //ignore case and return 0 if equal else if s1>s2 return >0 else if s1<s2 return <0; if ((argc < 4) || !strncasecmp(argv[1], "-h", 2) || !strncasecmp(argv[1], "--h", 3)) usage(argv[0]); bool is_pointfile = false; int i = strncasecmp(argv[1], "point" , 5); if(!strncasecmp(argv[1], "point" , 5)) is_pointfile = true; const char *infilename = argv[2]; const char *outfilename = argv[3]; float threshold = 0; printf("argv2:%s\n",infilename); printf("argv3:%s\n",outfilename); if (argc >= 5 && !strncasecmp(argv[1], "-m", 2)) { threshold = atof(argv[2]); infilename = argv[3]; outfilename = argv[4]; } // Read the .ply file int numleaves, numfaces; face *faces; bool havecolor; QTree_Node *leaves; std::string comments; if (!read_ply(infilename, numleaves, leaves, numfaces, faces, havecolor, comments)) { fprintf(stderr, "Couldn't read input file %s\n", infilename); exit(1); } if (numleaves < 4) { fprintf(stderr, "Ummm... That's an awfully small mesh you've got there...\n"); exit(1); } if(!is_pointfile) if (numfaces < 4) { fprintf(stderr, "Ummm... I need a *mesh* as input. That means triangles 'n stuff...\n"); exit(1); } // Compute per-vertex normals if(!is_pointfile) { find_normals(numleaves, leaves, numfaces, faces); // Merge nodes merge_nodes(numleaves, leaves, numfaces, faces, havecolor, threshold); // Compute initial splat sizes find_splat_sizes(numleaves, leaves, numfaces, faces); } else { compute_splat_sizes(numleaves, leaves); } // Don't need face data any more delete [] faces; // Initialize the tree QTree qt(numleaves, leaves, havecolor); // Build the tree... qt.BuildTree(); // ... and write it out qt.Write(outfilename, comments); system("PAUSE"); return 0; }
int tree_chop(struct btree *btree, struct delete_info *info, millisecond_t deadline) { int depth = btree->root.depth, level = depth - 1, suspend = 0; struct cursor *cursor; struct buffer_head *leafbuf, **prev, *leafprev = NULL; struct btree_ops *ops = btree->ops; struct sb *sb = btree->sb; int ret; cursor = alloc_cursor(btree, 0); prev = malloc(sizeof(*prev) * depth); memset(prev, 0, sizeof(*prev) * depth); down_write(&btree->lock); probe(btree, info->resume, cursor); leafbuf = level_pop(cursor); /* leaf walk */ while (1) { ret = (ops->leaf_chop)(btree, info->key, bufdata(leafbuf)); if (ret) { mark_buffer_dirty(leafbuf); if (ret < 0) goto error_leaf_chop; } /* try to merge this leaf with prev */ if (leafprev) { struct vleaf *this = bufdata(leafbuf); struct vleaf *that = bufdata(leafprev); /* try to merge leaf with prev */ if ((ops->leaf_need)(btree, this) <= (ops->leaf_free)(btree, that)) { trace(">>> can merge leaf %p into leaf %p", leafbuf, leafprev); (ops->leaf_merge)(btree, that, this); remove_index(cursor, level); mark_buffer_dirty(leafprev); brelse_free(btree, leafbuf); //dirty_buffer_count_check(sb); goto keep_prev_leaf; } brelse(leafprev); } leafprev = leafbuf; keep_prev_leaf: //nanosleep(&(struct timespec){ 0, 50 * 1000000 }, NULL); //printf("time remaining: %Lx\n", deadline - gettime()); // if (deadline && gettime() > deadline) // suspend = -1; if (info->blocks && info->freed >= info->blocks) suspend = -1; /* pop and try to merge finished nodes */ while (suspend || level_finished(cursor, level)) { /* try to merge node with prev */ if (prev[level]) { assert(level); /* node has no prev */ struct bnode *this = cursor_node(cursor, level); struct bnode *that = bufdata(prev[level]); trace_off("check node %p against %p", this, that); trace_off("this count = %i prev count = %i", bcount(this), bcount(that)); /* try to merge with node to left */ if (bcount(this) <= sb->entries_per_node - bcount(that)) { trace(">>> can merge node %p into node %p", this, that); merge_nodes(that, this); remove_index(cursor, level - 1); mark_buffer_dirty(prev[level]); brelse_free(btree, level_pop(cursor)); //dirty_buffer_count_check(sb); goto keep_prev_node; } brelse(prev[level]); } prev[level] = level_pop(cursor); keep_prev_node: /* deepest key in the cursor is the resume address */ if (suspend == -1 && !level_finished(cursor, level)) { suspend = 1; /* only set resume once */ info->resume = from_be_u64((cursor->path[level].next)->key); } if (!level) { /* remove depth if possible */ while (depth > 1 && bcount(bufdata(prev[0])) == 1) { trace("drop btree level"); btree->root.block = bufindex(prev[1]); mark_btree_dirty(btree); brelse_free(btree, prev[0]); //dirty_buffer_count_check(sb); depth = --btree->root.depth; vecmove(prev, prev + 1, depth); //set_sb_dirty(sb); } //sb->snapmask &= ~snapmask; delete_snapshot_from_disk(); //set_sb_dirty(sb); //save_sb(sb); ret = suspend; goto out; } level--; trace_off(printf("pop to level %i, block %Lx, %i of %i nodes\n", level, bufindex(cursor->path[level].buffer), cursor->path[level].next - cursor_node(cursor, level)->entries, bcount(cursor_node(cursor, level)));); } /* push back down to leaf level */ while (level < depth - 1) { struct buffer_head *buffer = sb_bread(vfs_sb(sb), from_be_u64(cursor->path[level++].next++->block)); if (!buffer) { ret = -EIO; goto out; } level_push(cursor, buffer, ((struct bnode *)bufdata(buffer))->entries); trace_off(printf("push to level %i, block %Lx, %i nodes\n", level, bufindex(buffer), bcount(cursor_node(cursor, level)));); }
void overlap() { Globals::qbs = new QNode*[Globals::threads_num]; Globals::sets = new std::map<myset,myset*>[Globals::threads_num]; for (int i = 0; i<Globals::threads_num; i++) { Globals::qbs[i] = new QNode(); } denominator = Globals::c2 * Globals::gamma; denominator /= Globals::side_multiplier; boost::thread* thr[Globals::threads_num]; for (int i = 0; i < Globals::threads_num; ++i) thr[i] = new boost::thread(Worker(i)); for (int i = 0; i < Globals::threads_num; ++i) { thr[i]->join(); delete thr[i]; } // for (int i=0; i<Globals::threads_num; i++) { // rec_count(Globals::qbs[i], 1.0); // std::cout << Globals::ov_nodes << " " << Globals::ov_leaves << std::endl; // Globals::ov_nodes=1; // Globals::ov_leaves=0; // } double merging_timer = GetTimeMs(); for (int i=1; i<Globals::threads_num; i++) { std::cout << "Merging " << i << std::endl; merge_nodes(Globals::qbs[0],Globals::qbs[i]); delete Globals::qbs[i]; } Globals::qb = Globals::qbs[0]; //depth_all_reprs(Globals::qb); make_it_deeper(Globals::qb); //TODO //std::cout << "start filling" << std::endl; // std::cout << "before fill vectors" << std::endl; // fill_vectors(Globals::qb, &Globals::hypercube_center, 1.0); /* for (int i=0; i<10; i++) { printPt(std::cout,*Globals::qt_centers[i]); std::cout<<std::endl; std::cout << Globals::qt_sides[i] << std::endl; }*/ Globals::ov_nodes=1; Globals::ov_leaves=0; rec_count(Globals::qb); //TODO ////std::cout << " ovnodes " << Globals::ov_nodes << " " << Globals::ov_leaves << std::endl; ////std::cout << "LEAF: " << couter << std::endl; dothereprs(); ANNmin_k* asdf = new ANNmin_k(1); // fill_in_reprs(Globals::qb, &Globals::hypercube_center, 1.0, Globals::kdtree, asdf); find_all_reprs(Globals::qbs[0], &Globals::hypercube_center, 1.0, Globals::kdtree, asdf,0); Globals::merging_time = GetTimeMs() - merging_timer; ANNidxArray nnIdx = new ANNidx[Globals::reprs_num]; ANNdistArray dists = new ANNdist[Globals::reprs_num]; //replace_reprs(Globals::qb, &Globals::hypercube_center, 1.0, nnIdx, dists); CHANGE delete[] nnIdx; delete[] dists; //TODO // std::cout << "done replacing" << std::endl; /*std::map<myset,myset*>::iterator it; for (int i=0; i<Globals::threads_num; i++) { for (it=Globals::sets[i].begin(); it!=Globals::sets[i].end(); it++) { delete (*it).second; } }*/ delete[] Globals::sets; //representatives(); }