IndexAccessMethod* Heap1DatabaseCatalogEntry::getIndex( OperationContext* txn, const CollectionCatalogEntry* collection, IndexCatalogEntry* index ) { const Entry* entry = dynamic_cast<const Entry*>( collection ); Entry::Indexes::const_iterator i = entry->indexes.find( index->descriptor()->indexName() ); if ( i == entry->indexes.end() ) { // index doesn't exist return NULL; } const string& type = index->descriptor()->getAccessMethodName(); #if 1 // Toggle to use Btree on HeapRecordStore // Need the Head to be non-Null to avoid asserts. TODO remove the asserts. index->headManager()->setHead(txn, DiskLoc(0xDEAD, 0xBEAF)); // When is a btree not a Btree? When it is a Heap1BtreeImpl! std::auto_ptr<SortedDataInterface> btree(getHeap1BtreeImpl(index->ordering(), &i->second->data)); #else if (!i->second->rs) i->second->rs.reset(new HeapRecordStore( index->descriptor()->indexName() )); std::auto_ptr<SortedDataInterface> btree( SortedDataInterface::getInterface(index->headManager(), i->second->rs, index->ordering(), index->descriptor()->indexNamespace(), index->descriptor()->version(), &BtreeBasedAccessMethod::invalidateCursors)); #endif if ("" == type) return new BtreeAccessMethod( index, btree.release() ); if (IndexNames::HASHED == type) return new HashAccessMethod( index, btree.release() ); if (IndexNames::GEO_2DSPHERE == type) return new S2AccessMethod( index, btree.release() ); if (IndexNames::TEXT == type) return new FTSAccessMethod( index, btree.release() ); if (IndexNames::GEO_HAYSTACK == type) return new HaystackAccessMethod( index, btree.release() ); if (IndexNames::GEO_2D == type) return new TwoDAccessMethod( index, btree.release() ); log() << "Can't find index for keyPattern " << index->descriptor()->keyPattern(); fassertFailed(18518); }
/** * test put same keys into Btree,these keys have same content and same address */ TEST(KeyBtree_Put_Char_Test, put_06_sameaddresskey) { int32_t iRet = 0; int32_t iValue = 0; int32_t iSuccess = 0; int32_t iFail = 0; //int32_t iGet = -1; charBtree btree( MAX_SIZE ); get_next_random_value(iValue); char * key = (char *)malloc( TEST_SIZE ); sprintf( key, "%08x", iValue); for (int32_t iLoop = 0; iLoop < TEST_COUNT; iLoop ++) { /* Put the key-value pair */ iRet = btree.put( key, iLoop + 1 ); if (((iRet == ERROR_CODE_OK) && (iLoop == 0)) || (iRet == ERROR_CODE_KEY_REPEAT)) { iSuccess ++; } else { iFail ++; } } free(key); EXPECT_EQ( iFail, 0); EXPECT_EQ( iSuccess, TEST_COUNT ); EXPECT_EQ( 1, btree.get_object_count() ); btree.clear(); }
static void remake_tree(int win, double order, double rt, double ra, double rnd, int bgcolor_r, int bgcolor_g, int bgcolor_b) { Cdbl z2 = 0 + 0.9 * L / (1 - pow(rt, order + 1)) * I; Cdbl z1 = 0; int i; /* 背景色専用レイヤ */ layer(win, 0, 2); for (i = 0; i < L; i++) { newrgbcolor(win, bgcolor_r + 128.0 * i / L, bgcolor_g + 128.0 * i / L, bgcolor_b + 128.0 * i / L); drawline(win, -L / 2, i, L / 2 - 1, i); } /* treeのマスク専用レイヤ */ layer(win, 0, 4); gsetbgcolor(win, "#ffffff"); gclr(win); newcolor(win, "#000000"); btree(win, z1, z2, order, rt, ra, rnd); /* treeの専用レイヤ */ layer(win, 0, 3); gsetbgcolor(win, "#003300"); gclr(win); newgcfunction(win, GXandInverted); gputarea(win, -L / 2, 0, win, 4, -L / 2, 0, L / 2 - 1, L - 1); newgcfunction(win, GXcopy); newcolor(win, "white"); drawstr(win, L / 2 - 180, 4, 14, 0, "Background Color: " "#%02x%02x%02x", bgcolor_r, bgcolor_g, bgcolor_b); }
DbCursor::DbCursor(DbTransaction& tx, DbTable& table) : Path(4) { Path.resize(0); DbTransaction::CTables::iterator it = tx.Tables.find(table.Name); if (it != tx.Tables.end()) Tree = &it->second; else { BTree btree(tx); btree.Name = table.Name; if (&table == &DbTable::Main) btree.Root = tx.MainTableRoot; else { DbCursor cMain(tx, DbTable::Main); ConstBuf k(table.Name.c_str(), strlen(table.Name.c_str())); if (!cMain.SeekToKey(k)) Throw(E_FAIL); TableData& td = *(TableData*)cMain.get_Data().P; btree.SetKeySize(td.KeySize); if (UInt32 pgno = letoh(td.RootPgNo)) btree.Root = tx.OpenPage(pgno); else if (tx.ReadOnly) { // TRC(0, "No root for " << table.Name); } } Tree = &tx.Tables.insert(make_pair(table.Name, btree)).first->second; } Tree->Cursors.push_back(_self); }
TEST(KeyBtreeTest, search) { StringBtree btree(TEST_KEY_MAX_SIZE); { TestKey key; int32_t j; int32_t *ids = (int32_t*)malloc(TEST_COUNT * sizeof(int32_t)); for(int32_t i = 0; i < TEST_COUNT; i++) { if (get_next_id(j)) break; ids[i] = j; key.set_value(j); btree.put(key, j + 1); } // search int32_t value = 0; int32_t success = 0; for(int32_t i = 0; i < TEST_COUNT; i++) { key.set_value(ids[i]); btree.get(key, value); if (value == ids[i] + 1) success ++; } free(ids); EXPECT_EQ(success, TEST_COUNT); } btree.clear(); }
/** *test put long keys into Btree */ TEST(KeyBtree_Put_Char_Test, put_07_longkey) { set_up(); int32_t iRet = 0; int32_t iValue = 0; int32_t iSuccess = 0; int32_t iFail = 0; charBtree btree(sizeof(char*)); for (int32_t iLoop = 0; iLoop < TEST_COUNT; iLoop ++) { /* malloc */ pstrKey[ iLoop ] = (char *)malloc( TEST_SIZE ); /* Set the flag for free */ iFlag = 1; /* Create the key */ get_next_random_value( iValue ); sprintf( pstrKey[ iLoop ], "%08x", iValue ); /* Put the key-value pair */ iRet = btree.put( pstrKey[ iLoop ], iLoop + 1 ); if (iRet == ERROR_CODE_OK) { iSuccess ++; } else { iFail ++; } } EXPECT_EQ( iFail, 0 ); EXPECT_EQ( iSuccess, btree.get_object_count() ); tear_down(); btree.clear(); }
TEST(KeyBtreeTest, put) { StringBtree btree(TEST_KEY_MAX_SIZE); { TestKey key; int32_t ret, j; int32_t success = 0; int32_t value = 0; for(int32_t i = 0; i < TEST_COUNT; i++) { if (get_next_id(j)) break; key.set_value(j); ret = btree.put(key, i + 1); if (ret == ERROR_CODE_OK) { success ++; } } EXPECT_EQ(success, btree.get_object_count()); ret = btree.put(key, 1); EXPECT_EQ(ret, ERROR_CODE_KEY_REPEAT); ret = btree.put(key, 20, true); EXPECT_EQ(ret, ERROR_CODE_OK); EXPECT_EQ(btree.get(key, value), ERROR_CODE_OK); EXPECT_TRUE(value == 20); EXPECT_EQ(success, btree.get_object_count()); } btree.clear(); }
IndexAccessMethod* MMAPV1DatabaseCatalogEntry::getIndex( OperationContext* txn, const CollectionCatalogEntry* collection, IndexCatalogEntry* entry ) { const string& type = entry->descriptor()->getAccessMethodName(); string ns = collection->ns().ns(); if ( IndexNames::TEXT == type || entry->descriptor()->getInfoElement("expireAfterSeconds").isNumber() ) { NamespaceDetailsRSV1MetaData md( ns, _namespaceIndex.details( ns ), _getNamespaceRecordStore() ); md.setUserFlag( txn, NamespaceDetails::Flag_UsePowerOf2Sizes ); } RecordStore* rs = NULL; { boost::mutex::scoped_lock lk( _collectionsLock ); string ns = entry->descriptor()->indexNamespace(); Entry*& entry = _collections[ns]; if ( !entry ) { entry = new Entry(); _fillInEntry_inlock( txn, ns, entry ); } rs = entry->recordStore.get(); } std::auto_ptr<BtreeInterface> btree( BtreeInterface::getInterface(entry->headManager(), rs, entry->ordering(), entry->descriptor()->indexNamespace(), entry->descriptor()->version(), &BtreeBasedAccessMethod::invalidateCursors)); if (IndexNames::HASHED == type) return new HashAccessMethod( entry, btree.release() ); if (IndexNames::GEO_2DSPHERE == type) return new S2AccessMethod( entry, btree.release() ); if (IndexNames::TEXT == type) return new FTSAccessMethod( entry, btree.release() ); if (IndexNames::GEO_HAYSTACK == type) return new HaystackAccessMethod( entry, btree.release() ); if ("" == type) return new BtreeAccessMethod( entry, btree.release() ); if (IndexNames::GEO_2D == type) return new TwoDAccessMethod( entry, btree.release() ); log() << "Can't find index for keyPattern " << entry->descriptor()->keyPattern(); fassertFailed(17489); }
static void btree(int win, Cdbl z1, Cdbl z2, int dim, float rt, double ra, double rnd) { Cdbl z3, z4, z5; if (dim == -1) return; z3 = z1 * rt + z2 * (1 - rt); z4 = z3 + rt * (z2 - z1) * cexp(I * ra / 180 * M_PI * (rnd * drand48() + (1 - rnd / 2))); z5 = z3 + rt * (z2 - z1) * cexp(-I * ra / 180 * M_PI * (rnd * drand48() + (1 - rnd / 2))); moveto(win, creal(z1), cimag(z1)); newlinewidth(win, dim); lineto(win, creal(z3), cimag(z3)); btree(win, z3, z5, dim - 1, rt, ra, rnd); btree(win, z3, z4, dim - 1, rt, ra, rnd); }
TEST(KeyBtreeTest, read_write_mthread) { StringBtree btree(TEST_KEY_MAX_SIZE); btree.set_write_lock_enable(1); TestKey key; int32_t new_value = 0; int32_t success = 0; for(int32_t i = 0; i < TEST_COUNT; i++) { new_value = (i * 11); key.set_value(new_value); if (btree.put(key, i + 1) == ERROR_CODE_OK) { success ++; } } EXPECT_EQ(success, TEST_COUNT); int cnt = 0; int rtc1 = 1; int rtc2 = 1; int wtc = 1; int dtc = 1; pthread_t tids[rtc1+rtc2+wtc+dtc]; stop_ = 0; while(cnt < rtc1) { pthread_create(&tids[cnt], NULL, mthread_read_1, &btree); cnt ++; } while(cnt < rtc1 + rtc2) { pthread_create(&tids[cnt], NULL, mthread_read_2, &btree); cnt ++; } while(cnt < rtc1 + rtc2 + wtc) { pthread_create(&tids[cnt], NULL, mthread_write, &btree); cnt ++; } while(cnt < rtc1 + rtc2 + wtc + dtc) { pthread_create(&tids[cnt], NULL, mthread_remove, &btree); cnt ++; } for(int i = 0; i < cnt; i++) { pthread_join(tids[i], NULL); } btree.clear(); }
int main() { int t,ans; scanf("%d",&t); while(t--) { scanf("%s",tree); i=0; // initialising i to 0 ans=btree(); printf("%d\n",ans); } return 0; }
TEST(KeyBtreeTest, range_search) { StringBtree btree(TEST_KEY_MAX_SIZE); { BtreeReadHandle handle; TestKey key; int32_t j; int32_t *ids = (int32_t*)malloc(TEST_COUNT * sizeof(int32_t)); int insert_total = 0; for(int32_t i = 0; i < TEST_COUNT; i++) { if (get_next_id(j)) break; ids[i] = j; key.set_value(j); if (ERROR_CODE_OK == btree.put(key, i + 1)) { insert_total ++; } } // range search int32_t value = 0; int32_t success = 0; int32_t ret = btree.get_read_handle(handle); ASSERT_TRUE(ERROR_CODE_OK == ret); btree.set_key_range(handle, btree.get_min_key(), 0, btree.get_max_key(), 0); while(ERROR_CODE_OK == btree.get_next(handle, value)) { success ++; } EXPECT_EQ(success, insert_total); success = 0; BtreeReadHandle handle1; btree.get_read_handle(handle1); btree.set_key_range(handle1, btree.get_max_key(), 1, btree.get_min_key(), 1); if (ERROR_CODE_OK == btree.get_next(handle1, key, value)) { success ++; } while(ERROR_CODE_OK == btree.get_next(handle1, value)) { success ++; } EXPECT_EQ(success, insert_total); free(ids); } btree.clear(); }
int btree() { if(tree[i]=='l') // (shifting from left to right subtree)if the subtree/tree has only leaf then return 0 { return 0; } else { i++; int l=btree(); // calculate height of left subtree i++; int r=btree(); // calculate height of right subtree //return (max(l,r))+1;// +1 since we are not calculating in case of last leaf if(l>r) { return l+1; } else { return r+1; } } }
TEST(KeyBtreeTest, small_key) { KeyBtree<char*, int32_t> btree(sizeof(char*)); char *base = (char*)0x1000; int success = 0; for(int32_t i = 0; i < TEST_COUNT; i++) { if (btree.put(base + i, i + 1) == ERROR_CODE_OK) success ++; } ASSERT_TRUE(success == TEST_COUNT); int value = 0; btree.get(base, value); ASSERT_TRUE(value == 1); btree.clear(); }
TEST(KeyBtreeTest, insert_batch) { StringBtree btree(TEST_KEY_MAX_SIZE); { BtreeWriteHandle handle; TestKey key; int32_t ret, j; int32_t success = 0; int32_t value = 0; ret = btree.get_write_handle(handle); ASSERT_TRUE(ERROR_CODE_OK == ret); for(int32_t i = 0; i < TEST_COUNT; i++) { if (get_next_id(j)) break; key.set_value(j); ret = btree.put(handle, key, i + 1); if (ret == ERROR_CODE_OK) { success ++; } } handle.end(); EXPECT_EQ(success, btree.get_object_count()); { BtreeWriteHandle handle1; btree.get_write_handle(handle1); for(int32_t i = 0; i < TEST_COUNT; i++) { if (get_next_id(j)) break; key.set_value(j); btree.put(handle1, key, i + 1); } key.set_value(1000); btree.put(handle1, key, 1000); btree.get(handle1, key, value); EXPECT_EQ(1000, value); handle1.rollback(); } EXPECT_EQ(success, btree.get_object_count()); } btree.clear(); }
TEST_F(BinaryTreeTest, BuildTreeFromInOrderPostOrder) { binary_tree::BinaryTree<int> btree( std::begin(inOrderTraversal), std::end(inOrderTraversal), binary_tree::POST_ORDER, std::begin(postOrderTraversal), std::end(postOrderTraversal) ); auto inOrderIt = btree.InOrderBegin(); for (auto value : inOrderTraversal) { EXPECT_EQ(value, *inOrderIt); ++inOrderIt; } auto postOrderIt = btree.PostOrderBegin(); for (auto value: postOrderTraversal) { EXPECT_EQ(value, *postOrderIt); ++postOrderIt; } }
TEST(KeyBtreeTest, remove) { StringBtree btree(TEST_KEY_MAX_SIZE); { TestKey key; int32_t ret, j; int32_t *ids = (int32_t*)malloc(TEST_COUNT * sizeof(int32_t)); int32_t success = 0; int value; for(int32_t i = 0; i < TEST_COUNT; i++) { if (get_next_id(j)) break; ids[i] = j; key.set_value(j); if (btree.put(key, i + 1) == ERROR_CODE_OK) { success ++; } } key.set_value(0x80000000); ASSERT_TRUE(btree.put(key, 0x8000001) == ERROR_CODE_OK); btree.remove(key, value); ASSERT_TRUE(value == 0x8000001); // remove for(int32_t i = 0; i < TEST_COUNT - 10; i++) { key.set_value(ids[i]); ret = btree.remove(key); if (ret == ERROR_CODE_OK) { success --; } } free(ids); EXPECT_EQ(success, btree.get_object_count()); } btree.clear(); }
TEST(KeyBtreeTest, get) { StringBtree btree(TEST_KEY_MAX_SIZE); { TestKey key; int32_t ret; int32_t success = 0; int32_t value = 0; EXPECT_EQ(0, btree.get_object_count()); for(int32_t i = 0; i < TEST_COUNT; i++) { key.set_value(i); ret = btree.put(key, i + 1); if (ret == ERROR_CODE_OK) { success ++; } } EXPECT_EQ(success, btree.get_object_count()); BtreeBaseHandle handle; key.set_value(0); ret = btree.get(handle, key, value); EXPECT_EQ(ret, ERROR_CODE_NOT_FOUND); btree.get_read_handle(handle); ret = btree.get(handle, key, value); EXPECT_EQ(ret, ERROR_CODE_OK); EXPECT_EQ(1, value); key.set_value(2); ret = btree.get(handle, key, value); EXPECT_EQ(ret, ERROR_CODE_OK); EXPECT_EQ(3, value); } btree.clear(); }
int main(int argc, char **argv) { if(argc==1 || (argc==2 && strcmp(argv[1],"-h")==0) || (argc==2 && strcmp(argv[1],"--help")==0) || (argc==2 && strcmp(argv[1],"--h")==0) ) { usage(argv[0]); exit(-1); } time_t global_start=clock(); int i,j,new_node, num_pushes=0, seed=0, nsplits=0, root=-1,subtree_root=-1,new_ms,max_bits=-1, num_spawns=0; // Set default p to 1/3 double p=0.3333; list<int>::iterator ii; char *DIMACS_file=NULL; bool has_graph=false,verbose=false,do_push=true,do_two_sep=true, do_init_push=false; Graph *G=NULL; time_t start,stop; //for printing out the graphviz representations of each move on the bd bool gviz_all = false; bool gviz_el = false; //edge labels on bool gviz_th = true; //thicknesses off char gvizfile[20]; int step = 0; // time_t begin=clock(); // Controller object has some methods which are used independently from // graph objects. goblinController *CT; CT = new goblinController(); //Turn off printing of dots. CT->traceLevel = 0; // Parse arguments for(i=0;i<argc;i++) { if(strcmp(argv[i],"-v")==0) verbose=true; if(strcmp(argv[i],"-f")==0) { DIMACS_file=argv[i+1]; // Read in the file G=new Graph(DIMACS_file, true); G->write_graphviz_file("orig.gviz"); char metis_file[100]; sprintf(metis_file,"%s.metis",argv[i+1]); G->write_METIS_file(metis_file); sprintf(metis_file,"%s.hmetis",argv[i+1]); G->write_HMETIS_file(metis_file); has_graph=true; if(verbose) { print_message(0,"Read in graph from file: %s\n",DIMACS_file); cout << *G; } } if(strcmp(argv[i],"-p")==0) p=atof(argv[i+1]); if(strcmp(argv[i],"-nopush")==0) do_push=false; if(strcmp(argv[i],"-no2sep")==0) do_two_sep=false; if(strcmp(argv[i],"-seed")==0) seed=atoi(argv[i+1]); if(strcmp(argv[i],"-root")==0) root=atoi(argv[i+1]); if(strcmp(argv[i],"-subtree")==0) subtree_root=atoi(argv[i+1]); if(strcmp(argv[i],"-exhaust")==0) max_bits=atoi(argv[i+1]); } // Make sure we have a graph if(!has_graph) fatal_error("Did not load graph\n"); if(!G->check_connected()) fatal_error("Graph is not connected\n"); if(!G->check_two_connected()) fatal_error("Graph is not 2 connected!\n"); // "seed" the rng for(i=0;i<seed;i++) lcgrand(0); // Create the tree BDTree btree(G); // Initialize to the star configuration btree.create_star(); if(gviz_all) { sprintf(gvizfile, "bd.%d.gviz", step); btree.write_graphviz_file(false,gvizfile,gviz_el, gviz_th); step++; } // Find candidate pushes if(do_init_push) { num_pushes=btree.push(0); print_message(0,"Found %d initial pushes\n",num_pushes); } if(gviz_all && num_pushes > 0) { sprintf(gvizfile, "bd.%d.gviz", step); btree.write_graphviz_file(false,gvizfile,gviz_el, gviz_th); step++; } if(do_two_sep) { // Look for 2-separations list<int> X1, Y1; bool ts = false; int bv = 0; bool found; while(!ts) { //we need to try to separate a vertex with at least 4 edges adjacent to it found = false; while(found == false && bv < btree.num_nodes) { if(btree.nodes[bv].edges.size() >3) found = true; else bv++; } if(!found) { print_message(0, "Did not find a(nother) node of btree to split.\n"); break; } if(verbose) print_message(0,"Running two separation function at vertex %d\n", bv); X1.clear(); Y1.clear(); start = clock(); ts= btree.two_separation(bv, &X1, &Y1, CT); //ts = btree.bf_two_separation(bv, &X1, &Y1); stop = clock(); print_message(0, "Checked for two separation in %f seconds.\n", ((double)(stop-start))/CLOCKS_PER_SEC); if(ts) { print_message(0, "Found a valid 2 separation!\n"); print_message(0, "Splitting node %d\n", bv); // Split the node new_node = btree.split_node(bv,&X1,EDGE_SPLIT,&new_ms); print_message(0,"After split - new edge has middle set of size %d\n", new_ms); if(gviz_all) { sprintf(gvizfile, "bd.%d.gviz", step); btree.write_graphviz_file(false,gvizfile,gviz_el, gviz_th); step++; } if(do_push) { //Push the vertex you split num_pushes=btree.push(bv); print_message(0, "Found %d pushes at %d \n",num_pushes, bv); if(gviz_all && num_pushes > 0) { sprintf(gvizfile, "bd.%d.gviz", step); btree.write_graphviz_file(false,gvizfile,gviz_el, gviz_th); step++; } //Push the new vertex created num_pushes=btree.push(new_node); print_message(0, "Found %d pushes at %d \n",num_pushes, new_node); if(gviz_all && num_pushes > 0) { sprintf(gvizfile, "bd.%d.gviz", step); btree.write_graphviz_file(false,gvizfile,gviz_el, gviz_th); step++; } } //Add one to our count, then reset ts and bv so we restart search for 2-seps. nsplits++; ts = false; bv = 0; } else { print_message(0, "No 2 separation at vertex %d!\n", bv); bv++; } } print_message(0, "Finished with two-separations. Split %d nodes.\n", nsplits); } // Now run eigenvector splitting until BD is valid int split_node=0,new_node_1, new_node_2; nsplits=0; list<int> A, B, CA, CB, partition, partition2; vector<int> candidates(btree.num_nodes); while(!btree.is_valid) { // Find a BDTreeNode with at least 4 neighbors // fill candidates with possibilities // This is not smart since we really should just update // the candidates as we split and add nodes... // but it's probably in the noise anyway j=0; split_node = -1; for(i=0;i<btree.num_nodes;i++) { if(btree.nodes[i].edges.size()>=4) { candidates[j]=i; j++; } } print_message(1,"generating random int in 0...%d\n",j-1); split_node=rand_int(0,j-1); split_node=candidates[split_node]; print_message(1,"split_node is %d (degree=%d)\n",split_node,btree.nodes[split_node].edges.size()); A.clear(); B.clear(); CA.clear(); CB.clear(); nsplits++; // Run eigenvector heuristic - if fill_extra=true then we will // we are adding "obvious" edges to A and B within this function! start=clock(); if(btree.num_interior_nodes==1) btree.eigenvector_split(split_node,&A, &B, p, false); else btree.eigenvector_leaf_split(split_node,&A, &B, p, false); stop=clock(); print_message(0,"Computed eigenvector with p=%f in %f seconds.\n",p, ((double)(stop-start))/CLOCKS_PER_SEC); print_message(0,"Eigenvector A:\n"); print(0,A); print_message(0,"Eigenvector B:\n"); print(0,B); // Should do this only if A and B require it if(A.size()+B.size() < btree.nodes[split_node].edges.size()) { // Run the max flow to get an actual splitting of the edges start=clock(); btree.split_maxflow_partition(split_node,&A,&B,&CA,&CB, CT); stop = clock(); print_message(0,"Computed partition given eigenvector results in %f seconds.\n", ((double)(stop-start))/CLOCKS_PER_SEC); // Create the edge set partition.clear(); for(ii=A.begin();ii!=A.end();++ii) partition.push_back(*ii); for(ii=CA.begin();ii!=CA.end();++ii) partition.push_back(*ii); partition.sort(); } else { // Just use A partition.clear(); for(ii=A.begin();ii!=A.end();++ii) partition.push_back(*ii); } // Check the size of the exhaust BEFORE splitting the node int exhaust_bits=btree.nodes[split_node].edges.size() - A.size() - B.size(); print_message(1,"Exhaust size is %d bits\n",exhaust_bits); int exhaust_ms_size=-1; time_t exh_start=0, exh_stop=0; list<int> C; // Check to see if we can/want to exhaust if( exhaust_bits <= max_bits) { print_message(0,"Checking exhaust\n"); // Check this exhaustively exh_start=clock(); C.clear(); exhaust_ms_size=btree.best_partition(split_node,&A, &B, &C); exh_stop=clock(); } print_message(1,"Splitting %d with edge partition of size %d\n",split_node,partition.size()); print(1,partition); if(btree.num_interior_nodes==1) { // initial star - use split node new_node_2=-1; new_node_1 = btree.split_node(split_node,&partition,EDGE_SPLIT,&new_ms); btree.write_graphviz_file(true,"init.gviz",true,true); } else { // Later on in the process - use spawn node int ms1,ms2; btree.spawn_nodes(split_node,&partition,EDGE_SPLIT,&ms1,&ms2, &new_node_1, &new_node_2); print_message(0,"After spawn - new middle sets of size %d,%d (max ms is %d)\n",ms1,ms2,btree.max_middle_set_size); print_message(0,"new_nodes: %d,%d\n",new_node_1, new_node_2); //char spawn_file[100]; //sprintf(spawn_file,"spawn_%d.gviz",num_spawns); //btree.write_graphviz_file(true,spawn_file,true,true); num_spawns++; } // Check for validity here!!! if(btree.is_valid) break; // CSG - this fails because we had a spawn of a leaf that was an old node - // so new node1 and 2 are getting set incorrectly in spawn_node if(new_node_1!=-1) { // Try to push the newly created nodes if(btree.nodes[new_node_1].edges.size()>=4 && do_push) { num_pushes=btree.push(new_node_1); print_message(0,"\n\tFound %d pushes for newly introduced node %d\n",num_pushes,new_node_1); if(gviz_all && num_pushes > 0) { sprintf(gvizfile, "bd.%d.gviz", step); btree.write_graphviz_file(false,gvizfile,gviz_el, gviz_th); step++; } } // Check for validity here!!! if(btree.is_valid) break; } if(new_node_2!=-1) { if(btree.nodes[new_node_2].edges.size()>=4 && do_push) { num_pushes=btree.push(new_node_2); print_message(0,"\n\tFound %d pushes for newly introduced node %d\n",num_pushes,new_node_2); if(gviz_all && num_pushes > 0) { sprintf(gvizfile, "bd.%d.gviz", step); btree.write_graphviz_file(false,gvizfile,gviz_el, gviz_th); step++; } } } // Check for validity here!!! if(btree.is_valid) break; } if(root!=-1) { // This seems to be working when all graphviz flags are off, but something doesn't seem right // if last param is set to 2, probably because middle set is empty and we get 0 pen width??! // BDS - fixed this by making minimum penwidth 1 (i.e. pw = |mid set| unless |mid set| = 0, in which // case, pw = 1. btree.write_graphviz_file(false,"before_root.gviz",false,true); //cout<<btree; btree.root(root); btree.write_graphviz_file(false,"after_root.gviz",false,true); //cout<<btree; } if(verbose) cout<<btree; #if 0 // This section was just for generating a specific plot when running // c:\Users\tcg\PROJECTS\SGD\gaudi\code\trunk\branch_decomposition\Release>BranchDecomposition.exe -p . // 33 -no2sep -root 10 -subtree 330 -f ..\data\ch130.tsp.del.100.dimacs // Check to see if a subtree is desired if(subtree_root!=-1) { int roots[24]={400,328,267,292,263, 403,438,257,251,302, 276,452,294,405,364, 379,349,369,330,443, 338,420,291,425}; char *colors[6]={"red","blue","green","orange","purple","yellow"}; list<int> subtree; for(i=0;i<24;i++) { subtree.clear(); btree.find_subtree(roots[i], &subtree); print_message(1,"Subtree rooted at %d:\n",roots[i]); for(ii=subtree.begin();ii!=subtree.end();++ii) { printf("%d [label=\"\",style=filled,fillcolor=%s,color=%s];\n",*ii,colors[i%6],colors[i%6]); } printf("\n\n"); } } #endif print_message(0,"%d splits performed\n",nsplits); int max_ms=0; for(i=0;i<btree.num_edges;i++) if((int)btree.edges[i].middle_set.size()>max_ms) max_ms=btree.edges[i].middle_set.size(); print_message(0,"max middle set is %d\n",max_ms); vector<int> hist(max_ms+1,0); for(i=0;i<btree.num_edges;i++) hist[btree.edges[i].middle_set.size()]++; print(0,hist); if(gviz_all && num_pushes > 0) { sprintf(gvizfile, "bd.%d.gviz", step); btree.write_graphviz_file(false,gvizfile,gviz_el, gviz_th); step++; } time_t global_stop=clock(); printf("%s %3.3f %3.3f %d %d\n",DIMACS_file,p,(double)(global_stop-global_start)/CLOCKS_PER_SEC,nsplits,max_ms); fflush(stdout); //write a file with thick/thin lines. //btree.write_graphviz_file(false,"final.gviz",false, true); //write a file with thick/thin lines and edge labels //btree.write_graphviz_file(false,"final.gviz",true, true); delete G; delete CT; return 1; }
btreeDispatch::btreeDispatch(char *filename, long cacheSize) { t = New btree(wrap(this, &btreeDispatch::dispatcher)); t->open(filename, cacheSize); lastNonce = 1; }