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);
    }
예제 #2
0
/**
 * 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();
}
예제 #3
0
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);
}
예제 #4
0
파일: dblite.cpp 프로젝트: coinhelper/coin
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);
}
예제 #5
0
    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();
    }
예제 #6
0
/**
 *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();
}
예제 #7
0
    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);
    }
예제 #9
0
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);
}
예제 #10
0
    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();
    }
예제 #11
0
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;
}
예제 #12
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();
    }
예제 #13
0
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;
        }
    }
}
예제 #14
0
 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();
 }
예제 #15
0
    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();
    }
예제 #16
0
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;
    }
}
예제 #17
0
    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();
    }
예제 #18
0
    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();
    }
예제 #19
0
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;
}
예제 #20
0
btreeDispatch::btreeDispatch(char *filename, long cacheSize) {
  
  t = New btree(wrap(this, &btreeDispatch::dispatcher));
  t->open(filename, cacheSize);
  lastNonce = 1;
}