예제 #1
0
파일: abc.cpp 프로젝트: okiwan/adts
int main(int argc, char **argv) {
	
	int unnumero;

#ifdef PERFPROFILE
	HeapProfilerStart("/Users/Sergio/Desktop/volcado");
	HeapProfilerDump("**Heap a l'inici**");
#endif

	cout << "> Demostració d'ABCs" << endl;
	
	cout << "> Inicialització de variables de l'entorn" << endl;
	srand(time(NULL));
	
	cout << "> Creem un arbre, buit per defecte" << endl;
	ABC<int, int> arbre;
	
	cout << "> Afegim un total de " << NELEMENTSDEMO << " element(s), cadascun un natural de l'1 al " << NELEMENTSBASE << endl;
	for(int i=0; i<NELEMENTSDEMO; ++i) {
		int tmp = (rand() % NELEMENTSBASE) + 1;
		unnumero = tmp;
		arbre.inserir(tmp, tmp);
	}
	
	cout << "> Altura de l'arbre" << endl;
	cout << arbre.altura() << endl;
	
	cout << "> Recorregut en inordre de l'arbre" << endl;
	arbre.inordre();

	cout << "> Cerca d'un element inexistent" << endl;
	try {
		arbre.consultar(-1);
	} catch (char *m) {
		cout << m << endl;
	}
	
	cout << "> Cerca d'un element existent" << endl;
	cout << arbre.consultar(unnumero) << endl;
	
	cout << "> Mínim i màxim de l'arbre" << endl;
	cout << "min = " << arbre.minim() << ", max = " << arbre.maxim() << endl;
	
	cout << "> Buidat de l'arbre" << endl;
	while(arbre.elements() > 0) {
		cout << ">> Treiem el..." << arbre.minim() << endl;
		arbre.esborrar(arbre.minim());
	}
	cout << "> Recorregut en inordre de l'arbre després del buidat" << endl;
	arbre.inordre();
	
	cout << "> Fi de la demostració" << endl;

#ifdef PERFPROFILE
	HeapProfilerDump("**Heap al final**");
	HeapProfilerStop();
#endif

	return 0;
}
예제 #2
0
bool AdminRequestHandler::handleHeapProfilerRequest(const std::string &cmd,
                                                    Transport *transport) {
  string root = RuntimeOption::ProfilerOutputDir + "/" +
    Process::HostName;
  string file = root + "/hphp.prof";

  if (cmd == "prof-heap-on") {
    if (IsHeapProfilerRunning()) {
      transport->sendString("HeapProfiler is already running.\n");
    } else {
      if (Util::mkdir(file)) {
        // clean up leftovers
        string cmd = "/bin/rm -f ";
        cmd += file + ".*.heap";
        Util::ssystem(cmd.c_str());

        HeapProfilerStart(file.c_str());
        HeapProfilerDump("start");
        transport->sendString("OK\n");
      } else {
        transport->sendString("Unable to mkdir for profile data.\n");
      }
    }
    return true;
  }
  if (cmd == "prof-heap-dump") {
    if (!IsHeapProfilerRunning()) {
      transport->sendString("HeapProfiler is not running.\n");
    } else {
      HeapProfilerDump("end");
      transport->sendString("OK\n");
    }
    return true;
  }
  if (cmd == "prof-heap-off") {
    if (!IsHeapProfilerRunning()) {
      transport->sendString("HeapProfiler is not running.\n");
    } else {
      HeapProfilerDump("end");
      HeapProfilerStop();
      transport->sendString("OK\n");

      const char *argv[] = {"", root.c_str(), "-name", "*.heap", NULL};
      string files;
      Process::Exec("find", argv, NULL, files);
      vector<string> out;
      Util::split('\n', files.c_str(), out, true);
      if (out.size() > 1) {
        string base = "--base=";
        base += out[0];
        pprof(out[out.size() - 1], base.c_str());
      } else {
        Logger::Error("Unable to find heap profiler output");
      }
    }
    return true;
  }
  return false;
}
예제 #3
0
void memTest() {
    SmartKey::SmartKeyDictionary* dict = new SmartKeyDictionary(g_settings);

    HeapProfilerStart("smartkey");
    HeapProfilerDump("period");
    dict->loadSkippedCharsFromFile("/var/tmp/key_skipped");
    dict->loadCompiledDictionary("/var/tmp/compiled_key_dict_us");
    dict->loadEquivalencesFromFile("/var/tmp/key_equiv");
    HeapProfilerDump("period");

    test(*dict, "ofrss", "ideas");

    delete dict;
    HeapProfilerDump("period");
}
예제 #4
0
void Stdout_Worker::run() {
    std::cerr << "Waiting:" << std::endl;
#ifdef PROFILE
    //ProfilerStart("zmq_worker.log");
    HeapProfilerStart("worker_heap_2.log");
#endif
    std::string line;
    unsigned x, y;
    int z;
    while(std::getline(std::cin, line)) {
        std::istringstream line_stream(line);
        //std::cerr << "LINE:" << line << std::endl;
        if (line_stream.get() == '[') {
          line_stream >> x;
          line_stream >> y;
          line_stream >> z;
          auto tileData = this->tileReader.get_tile(z, x, y);
#ifdef PROFILE
          if (this->received_tiles%50==0) {
            HeapProfilerDump("TileRead");
          }
#endif
          this->received_tiles++;
          if (tileData) {
              //std::cerr << " Found tile" << std::endl;
              map(std::move(tileData));
          } else{
              send(0);
          }
        }
    }
예제 #5
0
파일: heaptrace.c 프로젝트: trws/flux-core
static void dump_cb (flux_t *h, flux_msg_handler_t *mh,
                     const flux_msg_t *msg, void *arg)
{
    const char *reason;

    if (flux_request_unpack (msg, NULL, "{s:s}", "reason", &reason) < 0)
        goto error;
#if WITH_TCMALLOC
    if (!IsHeapProfilerRunning ()) {
        errno = EINVAL;
        goto error;
    }
    HeapProfilerDump (reason);
#else
    errno = ENOSYS;
    goto error;
#endif
    if (flux_respond (h, msg, 0, NULL) < 0)
        FLUX_LOG_ERROR (h);
    return;
error:
    if (flux_respond (h, msg, errno, NULL) < 0)
        FLUX_LOG_ERROR (h);
}
예제 #6
0
void read_mRNAs(FILE* f, GList<GSeqData>& seqdata, GList<GSeqData>* ref_data,
	         int check_for_dups, int qfidx, const char* fname, bool only_multiexon) {
	//>>>>> read all transcripts/features from a GTF/GFF3 file
	//int imrna_counter=0;
#ifdef HEAPROFILE
    if (IsHeapProfilerRunning())
      HeapProfilerDump("00");
#endif
	int loci_counter=0;
	if (ref_data==NULL) ref_data=&seqdata;
	bool isRefData=(&seqdata==ref_data);
	                          //(f, transcripts_only)
	GffReader* gffr=new GffReader(f, true); //load only transcript annotations
	gffr->showWarnings(gtf_tracking_verbose);
	//            keepAttrs   mergeCloseExons   noExonAttrs
	gffr->readAll(!isRefData,          true,        isRefData || gtf_tracking_largeScale);
	//so it will read exon attributes only for low number of Cufflinks files
#ifdef HEAPROFILE
    if (IsHeapProfilerRunning())
      HeapProfilerDump("post_readAll");
#endif

	int d=parse_mRNAs(gffr->gflst, seqdata, isRefData, check_for_dups, qfidx,only_multiexon);
#ifdef HEAPROFILE
    if (IsHeapProfilerRunning())
      HeapProfilerDump("post_parse_mRNAs");
#endif
	if (gtf_tracking_verbose && d>0) {
	  if (isRefData) GMessage(" %d duplicate reference transcripts discarded.\n",d);
	            else GMessage(" %d redundant query transfrags discarded.\n",d);
	  }
	//imrna_counter=gffr->mrnas.Count();
	delete gffr; //free the extra memory and unused GffObjs
#ifdef HEAPROFILE
    if (IsHeapProfilerRunning())
      HeapProfilerDump("post_del_gffr");
#endif
	
	//for each genomic sequence, cluster transcripts
	int oriented_by_overlap=0;
	int initial_unoriented=0;
	int final_unoriented=0;
	GStr bname(fname);
	GStr s;
	if (!bname.is_empty()) {
		int di=bname.rindex('.');
		if (di>0) bname.cut(di);
		int p=bname.rindex('/');
		if (p<0) p=bname.rindex('\\');
		if (p>=0) bname.remove(0,p);
	}
	FILE* fdis=NULL;
	FILE* frloci=NULL;

	for (int g=0;g<seqdata.Count();g++) {
		//find the corresponding refseqdata with the same gseq_id
		int gseq_id=seqdata[g]->get_gseqid();
		if (!isRefData) { //query data, find corresponding ref data
			GSeqData* rdata=getRefData(gseq_id, *ref_data);
			initial_unoriented+=seqdata[g]->umrnas.Count();
			if (seqdata[g]->umrnas.Count()>0) {
			    oriented_by_overlap+=fix_umrnas(*seqdata[g], rdata, fdis);
			    final_unoriented+=seqdata[g]->umrnas.Count();
			    }
			}
		//>>>>> group mRNAs into locus-clusters (based on exon overlap)
		cluster_mRNAs(seqdata[g]->mrnas_f, seqdata[g]->loci_f, qfidx);
		cluster_mRNAs(seqdata[g]->mrnas_r, seqdata[g]->loci_r, qfidx);
		if (!isRefData) {
			cluster_mRNAs(seqdata[g]->umrnas, seqdata[g]->nloci_u, qfidx);
			}
		loci_counter+=seqdata[g]->loci_f.Count();
		loci_counter+=seqdata[g]->loci_r.Count();
//		if (refData) {
//			if (frloci==NULL) {
//				s=bname;
//				s.append(".loci.lst");
//				frloci=fopen(s.chars(), "w");
//			}
//			writeLoci(frloci, seqdata[g]->loci_f);
//			writeLoci(frloci, seqdata[g]->loci_r);
//		}//write ref loci
	}//for each genomic sequence
	if (fdis!=NULL) fclose(fdis);
	if (frloci!=NULL) fclose(frloci);
	if (initial_unoriented || final_unoriented) {
	  if (gtf_tracking_verbose) GMessage(" Found %d transfrags with undetermined strand (%d out of initial %d were fixed by overlaps)\n",
			    final_unoriented, oriented_by_overlap, initial_unoriented);
	}
	//if (fdis!=NULL) remove(s.chars()); remove 0-length file
#ifdef HEAPROFILE
    if (IsHeapProfilerRunning())
      HeapProfilerDump("post_cluster");
#endif
}
예제 #7
0
void bigDictTest() {
    SmartKey::SmartKeyDictionary dictionary(g_settings);

#ifdef HEAP
    HeapProfilerStart("smartkey");
    HeapProfilerDump("period");
#endif

    dictionary.loadSkippedCharsFromFile("/var/tmp/key_skipped");

#ifdef HEAP
    HeapProfilerDump("period");
#endif

    dictionary.loadTermsFromFile("/var/tmp/key_dict_us");
    //dictionary.loadCompiledDictionary("/var/tmp/compiled_key_dict_us");

    //HeapProfilerDump("period");

    dictionary.loadEquivalencesFromFile("/var/tmp/key_equiv");

    //testExactMatchesInFile(dictionary, "/var/tmp/key_dict_us");


     // old test
    /*
    int numInserts = 0;
    dictionary.insert("dork", 69); numInserts++;
    dictionary.insert("door", 67); numInserts++;
    dictionary.insert("doored", 39); numInserts++;
    dictionary.insert("flake", 70); numInserts++;
    dictionary.insert("the", 90); numInserts++;
    dictionary.insert("that", 90); numInserts++;
    dictionary.insert("they", 80); numInserts++;
    dictionary.insert("there", 82); numInserts++;
    dictionary.insert("There's", 81); numInserts++;
    dictionary.insert("at", 90); numInserts++;
    dictionary.insert("it", 91); numInserts++;
    dictionary.insert("for", 69); numInserts++;
    dictionary.insert("attempt", 30); numInserts++;
    dictionary.insert("substantial", 43); numInserts++;
    dictionary.insert("subs", 2); numInserts++;
    dictionary.insert("nonsense", 4); numInserts++;

    dictionary.print();
*/




    allWordsTest(dictionary);

    // small tree insertion test


/*
    std::string there = "there";

    std::string theres = "theres";
    
    std::string therr = "therr";
    
    std::string rhsy = "rhsy";
    
    std::string that = "that";
    std::string that_rgsr = "rgsy";

    dictionary.find(there);
    dictionary.find(therr);
    
    dictionary.find(that);
    dictionary.find(that_rgsr);

    dictionary.find(theres);

    dictionary.find(std::string("fot"));
    dictionary.find(std::string("ot"));
    dictionary.find(std::string("dindrsmrusl"));
  */




/*
    //tiny test
    printf("---- inserting ------\n");
    dictionary.insert("that", 80);
    dictionary.print();
    printf("---- inserting ------\n");
    dictionary.insert("there", 90);
    dictionary.print();
    printf("---- inserting ------\n");
    dictionary.insert("they", 70);
    dictionary.print();
    printf("---- inserting ------\n");
    dictionary.insert("that's", 70);
    dictionary.print();
*/
    /* weird ordering issue
    dictionary.insert("theater", 2);
    dictionary.insert("theaters", 3);
    dictionary.insert("there", 2);
    dictionary.insert("the", 1);
    dictionary.insert("Theme", 4);
    dictionary.insert("Thematic", 1);
    dictionary.insert("Th", 10);
    dictionary.insert("those", 1);
     */

    //dictionary.print();
    //test(dictionary, "there", "there");
#ifdef HEAP
    ProfilerStart("smartkeyCpu");
#endif

    /*
    test(dictionary, "tha", "that");
    test(dictionary, "rgru", "they");
    test(dictionary, "subs", "sub's");
    test(dictionary, "substanti", "substantial");
    test(dictionary, "mimdrbdr", "nonsense");
*/
#ifdef HEAP
    ProfilerStop();
#endif

    //dictionary.insert("the", 100000);



    int size = 0;
    int numOfSize = -1;

    printf("%s: number of nodes: %d\n", __FUNCTION__, dictionary.getNodeCount());

    while (numOfSize != 0) {
        int capacity = 0;
        numOfSize = dictionary.singlesCounter(size, capacity);
        printf("%s: number of child maps with only %d child: %d\n", __FUNCTION__, size, numOfSize);
        size++;
    }

    printf("%s: num removable nodes: %d\n", __FUNCTION__, dictionary.numRemovableNodes());



    printf("%s: node size: %d\n", __FUNCTION__,
            sizeof(SmartKeyNode));
}
예제 #8
0
int main(int argc, char* argv[])
{
  std::string   map;
  std::string   style;
  double        latTop,latBottom,lonLeft,lonRight;
  unsigned int  startZoom;
  unsigned int  endZoom;
  unsigned int  tileWidth;
  unsigned int  tileHeight;
  std::string   driver;
  bool          heapProfile;
  std::string   heapProfilePrefix;

  if (argc<12) {
    std::cerr << "DrawMap " << std::endl;
    std::cerr << "  <map directory> <style-file> " << std::endl;
    std::cerr << "  <lat_top> <lon_left> <lat_bottom> <lon_right> " << std::endl;
    std::cerr << "  <start zoom> <end zoom>" << std::endl;
    std::cerr << "  <tile width> <tile height>" << std::endl;
    std::cerr << "  <cairo|Qt|noop|none>" << std::endl;
#if defined(HAVE_LIB_GPERFTOOLS)    
    std::cerr << "  [heap profile prefix]" << std::endl;    
#endif
    return 1;
  }
  heapProfile = false;
#if defined(HAVE_LIB_GPERFTOOLS)    
  if (argc>12) {
      heapProfile = true;
      heapProfilePrefix = argv[12];
  }
#endif
  
  map=argv[1];
  style=argv[2];

  if (sscanf(argv[3],"%lf",&latTop)!=1) {
    std::cerr << "lon is not numeric!" << std::endl;
    return 1;
  }

  if (sscanf(argv[4],"%lf",&lonLeft)!=1) {
    std::cerr << "lat is not numeric!" << std::endl;
    return 1;
  }

  if (sscanf(argv[5],"%lf",&latBottom)!=1) {
    std::cerr << "lon is not numeric!" << std::endl;
    return 1;
  }

  if (sscanf(argv[6],"%lf",&lonRight)!=1) {
    std::cerr << "lat is not numeric!" << std::endl;
    return 1;
  }

  if (sscanf(argv[7],"%u",&startZoom)!=1) {
    std::cerr << "start zoom is not numeric!" << std::endl;
    return 1;
  }

  if (sscanf(argv[8],"%u",&endZoom)!=1) {
    std::cerr << "end zoom is not numeric!" << std::endl;
    return 1;
  }

  if (sscanf(argv[9],"%u",&tileWidth)!=1) {
    std::cerr << "tile width is not numeric!" << std::endl;
    return 1;
  }

  if (sscanf(argv[10],"%u",&tileHeight)!=1) {
    std::cerr << "tile height is not numeric!" << std::endl;
    return 1;
  }

  driver=argv[11];

#if defined(HAVE_LIB_OSMSCOUTMAPCAIRO)
  cairo_surface_t * cairoSurface=NULL;
  cairo_t         *cairo=NULL;
#endif

#if defined(HAVE_LIB_OSMSCOUTMAPQT)
  QPixmap         *qtPixmap=NULL;
  QPainter        *qtPainter=NULL;
  QApplication    application(argc,argv,true);
#endif

  if (driver=="cairo") {
    std::cout << "Using driver 'cairo'..." << std::endl;
#if defined(HAVE_LIB_OSMSCOUTMAPCAIRO)
    cairoSurface=cairo_image_surface_create(CAIRO_FORMAT_RGB24,tileWidth,tileHeight);

    if (cairoSurface==NULL) {
      std::cerr << "Cannot create cairo image cairoSurface" << std::endl;
      return 1;
    }

    cairo=cairo_create(cairoSurface);

    if (cairo==NULL) {
      std::cerr << "Cannot create cairo_t for image cairoSurface" << std::endl;
      return 1;
    }
#else
    std::cerr << "Driver 'cairo' is not enabled" << std::endl;
    return 1;
#endif
  }
  else if (driver=="Qt") {
    std::cout << "Using driver 'Qt'..." << std::endl;
#if defined(HAVE_LIB_OSMSCOUTMAPQT)
    qtPixmap=new QPixmap(tileWidth,tileHeight);

    if (qtPixmap==NULL) {
      std::cerr << "Cannot create QPixmap" << std::endl;
      return 1;
    }

    qtPainter=new QPainter(qtPixmap);

    if (qtPainter==NULL) {
      std::cerr << "Cannot create QPainter image cairoSurface" << std::endl;
      return 1;
    }
#else
    std::cerr << "Driver 'Qt' is not enabled" << std::endl;
  return 1;
#endif
  }
  else if (driver=="noop") {
    std::cout << "Using driver 'noop'..." << std::endl;
  }
  else if (driver=="none") {
    std::cout << "Using driver 'none'..." << std::endl;
  }
  else {
    std::cerr << "Unsupported driver '" << driver << "'" << std::endl;
    return 1;
  }

  osmscout::DatabaseParameter databaseParameter;

  //databaseParameter.SetDebugPerformance(true);

  osmscout::DatabaseRef       database=std::make_shared<osmscout::Database>(databaseParameter);
  osmscout::MapServiceRef     mapService=std::make_shared<osmscout::MapService>(database);

  if (!database->Open(map.c_str())) {
    std::cerr << "Cannot open database" << std::endl;
    return 1;
  }

  osmscout::StyleConfigRef styleConfig=std::make_shared<osmscout::StyleConfig>(database->GetTypeConfig());

  if (!styleConfig->Load(style)) {
    std::cerr << "Cannot open style" << std::endl;
    return 1;
  }
  
#if defined(HAVE_LIB_GPERFTOOLS)  
  if (heapProfile){
    HeapProfilerStart(heapProfilePrefix.c_str());
  }
#endif

  osmscout::TileProjection      projection;
  osmscout::MapParameter        drawParameter;
  osmscout::AreaSearchParameter searchParameter;
  std::list<LevelStats>         statistics;

  searchParameter.SetUseMultithreading(true);

  for (uint32_t level=std::min(startZoom,endZoom);
       level<=std::max(startZoom,endZoom);
       level++) {
    LevelStats              stats(level);
    osmscout::Magnification magnification;
    int                     xTileStart,xTileEnd,xTileCount,yTileStart,yTileEnd,yTileCount;

    magnification.SetLevel(level);

    xTileStart=osmscout::LonToTileX(std::min(lonLeft,lonRight),
                                    magnification);
    xTileEnd=osmscout::LonToTileX(std::max(lonLeft,lonRight),
                                  magnification);
    xTileCount=xTileEnd-xTileStart+1;

    yTileStart=osmscout::LatToTileY(std::max(latTop,latBottom),
                                    magnification);
    yTileEnd=osmscout::LatToTileY(std::min(latTop,latBottom),
                                  magnification);

    yTileCount=yTileEnd-yTileStart+1;

    std::cout << "----------" << std::endl;
    std::cout << "Drawing level " << level << ", " << (xTileCount)*(yTileCount) << " tiles [" << xTileStart << "," << yTileStart << " - " <<  xTileEnd << "," << yTileEnd << "]" << std::endl;

#if defined(HAVE_LIB_OSMSCOUTMAPCAIRO)
    osmscout::MapPainterCairo cairoMapPainter(styleConfig);
#endif
#if defined(HAVE_LIB_OSMSCOUTMAPQT)
    osmscout::MapPainterQt    qtMapPainter(styleConfig);
#endif
    osmscout::MapPainterNoOp  noOpMapPainter(styleConfig);

    size_t current=1;
    size_t tileCount=(yTileEnd-yTileStart+1)*(xTileEnd-xTileStart+1);
    size_t delta=tileCount/20;

    if (delta==0) {
      delta=1;
    }

    for (int y=yTileStart; y<=yTileEnd; y++) {
      for (int x=xTileStart; x<=xTileEnd; x++) {
        osmscout::MapData  data;
        osmscout::GeoBox   boundingBox;

        if ((current % delta)==0) {
          std::cout << current*100/tileCount << "% " << current;

          if (stats.tileCount>0) {
            std::cout << " " << stats.dbTotalTime/stats.tileCount;
            std::cout << " " << stats.drawTotalTime/stats.tileCount;
          }

          std::cout << std::endl;
        }

        projection.Set(x-1,y-1,
                       x+1,y+1,
                       magnification,
                       DPI,
                       tileWidth,
                       tileHeight);

        projection.GetDimensions(boundingBox);

        osmscout::StopClock dbTimer;

        osmscout::GeoBox dataBoundingBox(osmscout::GeoCoord(osmscout::TileYToLat(y-1,magnification),osmscout::TileXToLon(x-1,magnification)),
                                         osmscout::GeoCoord(osmscout::TileYToLat(y+1,magnification),osmscout::TileXToLon(x+1,magnification)));

        std::list<osmscout::TileRef> tiles;

        // set cache size almost unlimited, 
        // for better estimate of peak memory usage by tile loading
        mapService->SetCacheSize(10000000);
        
        mapService->LookupTiles(magnification,dataBoundingBox,tiles);
        mapService->LoadMissingTileData(searchParameter,*styleConfig,tiles);
        mapService->ConvertTilesToMapData(tiles,data);

        stats.nodeCount+=data.nodes.size();
        stats.wayCount+=data.ways.size();
        stats.areaCount+=data.areas.size();


#if defined(HAVE_LIB_GPERFTOOLS)
        if (heapProfile){
            std::ostringstream buff;
            buff << "load-" << level << "-" << x << "-" << y;
            HeapProfilerDump(buff.str().c_str());
        }
        struct mallinfo alloc_info = tc_mallinfo();
#else
#if defined(HAVE_MALLINFO)
        struct mallinfo alloc_info = mallinfo();
#endif
#endif
#if defined(HAVE_MALLINFO) || defined(HAVE_LIB_GPERFTOOLS)
        std::cout << "memory usage: " << formatAlloc(alloc_info.uordblks) << std::endl;
        stats.allocMax = std::max(stats.allocMax, (double)alloc_info.uordblks);
        stats.allocSum = stats.allocSum + (double)alloc_info.uordblks;
#endif

        // set cache size back to default
        mapService->SetCacheSize(25);
        dbTimer.Stop();

        double dbTime=dbTimer.GetMilliseconds();

        stats.dbMinTime=std::min(stats.dbMinTime,dbTime);
        stats.dbMaxTime=std::max(stats.dbMaxTime,dbTime);
        stats.dbTotalTime+=dbTime;

        osmscout::StopClock drawTimer;

#if defined(HAVE_LIB_OSMSCOUTMAPCAIRO)
        if (driver=="cairo") {
          //std::cout << data.nodes.size() << " " << data.ways.size() << " " << data.areas.size() << std::endl;
          cairoMapPainter.DrawMap(projection,
                                  drawParameter,
                                  data,
                                  cairo);
        }
#endif
#if defined(HAVE_LIB_OSMSCOUTMAPQT)
        if (driver=="Qt") {
          //std::cout << data.nodes.size() << " " << data.ways.size() << " " << data.areas.size() << std::endl;
          qtMapPainter.DrawMap(projection,
                               drawParameter,
                               data,
                               qtPainter);
        }
#endif
        if (driver=="noop") {
          noOpMapPainter.DrawMap(projection,
                                 drawParameter,
                                 data);
        }
        if (driver=="none") {
          // Do nothing
        }

        drawTimer.Stop();

        stats.tileCount++;

        double drawTime=drawTimer.GetMilliseconds();

        stats.drawMinTime=std::min(stats.drawMinTime,drawTime);
        stats.drawMaxTime=std::max(stats.drawMaxTime,drawTime);
        stats.drawTotalTime+=drawTime;

        current++;
      }
    }

    statistics.push_back(stats);
  }
  
#if defined(HAVE_LIB_GPERFTOOLS)  
  if (heapProfile){
    HeapProfilerStop();
  }
#endif  

  std::cout << "==========" << std::endl;

  for (const auto& stats : statistics) {
    std::cout << "Level: " << stats.level << std::endl;

#if defined(HAVE_MALLINFO) || defined(HAVE_LIB_GPERFTOOLS)
    std::cout << " Used memory: ";
    std::cout << "max: " << formatAlloc(stats.allocMax) << " ";
    std::cout << "avg: " << formatAlloc(stats.allocSum / stats.tileCount) << std::endl;
#endif
    
    std::cout << " Tot. data  : ";
    std::cout << "nodes: " << stats.nodeCount << " ";
    std::cout << "way: " << stats.wayCount << " ";
    std::cout << "areas: " << stats.areaCount << std::endl;

    std::cout << " Avg. data  : ";
    std::cout << "nodes: " << stats.nodeCount/stats.tileCount << " ";
    std::cout << "way: " << stats.wayCount/stats.tileCount << " ";
    std::cout << "areas: " << stats.areaCount/stats.tileCount << std::endl;

    std::cout << " DB         : ";
    std::cout << "total: " << stats.dbTotalTime << " ";
    std::cout << "min: " << stats.dbMinTime << " ";
    std::cout << "avg: " << stats.dbTotalTime/stats.tileCount << " ";
    std::cout << "max: " << stats.dbMaxTime << " " << std::endl;

    std::cout << " Map        : ";
    std::cout << "total: " << stats.drawTotalTime << " ";
    std::cout << "min: " << stats.drawMinTime << " ";
    std::cout << "avg: " << stats.drawTotalTime/stats.tileCount << " ";
    std::cout << "max: " << stats.drawMaxTime << std::endl;
  }

  database->Close();

#if defined(HAVE_LIB_OSMSCOUTMAPCAIRO)
  if (driver=="cairo") {
    cairo_destroy(cairo);
    cairo_surface_destroy(cairoSurface);
  }
#endif

  return 0;
}
예제 #9
0
int main(int argc, char* argv[])
{
  osmscout::CmdLineParser     argParser("PerformanceTest",
                                        argc,argv);
  Arguments                   args;
  osmscout::DatabaseParameter databaseParameter;

  argParser.AddOption(osmscout::CmdLineFlag([&args](const bool& value) {
                        args.help=value;
                      }),
                      std::vector<std::string>{"h","help"},
                      "Display help",
                      true);
  argParser.AddOption(osmscout::CmdLineFlag([&args](const bool& value) {
                        args.debug=value;
                      }),
                      "debug",
                      "Enable debug output",
                      false);
  argParser.AddOption(osmscout::CmdLineUIntOption([&args](const unsigned int& value) {
                        args.startZoom=osmscout::MagnificationLevel(value);
                      }),
                      "start-zoom",
                      "Start zoom, default: " + std::to_string(args.startZoom.Get()),
                      false);
  argParser.AddOption(osmscout::CmdLineUIntOption([&args](const unsigned int& value) {
                        args.endZoom=osmscout::MagnificationLevel(value);
                      }),
                      "end-zoom",
                      "End zoom, default: " + std::to_string(args.endZoom.Get()),
                      false);
  argParser.AddOption(osmscout::CmdLineUIntOption([&args](const unsigned int& value) {
                        args.tileDimension=std::make_tuple(value, std::get<1>(args.tileDimension));
                      }),
                      "tile-width",
                      "Tile width, default: " + std::to_string(std::get<0>(args.tileDimension)),
                      false);
  argParser.AddOption(osmscout::CmdLineUIntOption([&args](const unsigned int& value) {
                        args.tileDimension=std::make_tuple(std::get<0>(args.tileDimension), value);
                      }),
                      "tile-height",
                      "Tile height, default: " + std::to_string(std::get<1>(args.tileDimension)),
                      false);
  argParser.AddOption(osmscout::CmdLineStringOption([&args](const std::string& value) {
                        args.driver = value;
                      }),
                      "driver",
                      "Rendering driver (cairo|Qt|ag|opengl|noop|none), default: " + args.driver,
                      false);
  argParser.AddOption(osmscout::CmdLineDoubleOption([&args](const double& value) {
                        if (value > 0) {
                          args.dpi = value;
                        } else {
                          std::cerr << "DPI can't be negative or zero" << std::endl;
                        }
                      }),
                      "dpi",
                      "Rendering DPI, default: " + std::to_string(args.dpi),
                      false);
  argParser.AddOption(osmscout::CmdLineUIntOption([&args](const unsigned int& value) {
                        args.drawRepeat = value;
                      }),
                      "draw-repeat",
                      "Repeat every draw call, default: " + std::to_string(args.drawRepeat),
                      false);
  argParser.AddOption(osmscout::CmdLineUIntOption([&args](const unsigned int& value) {
                        args.loadRepeat = value;
                      }),
                      "load-repeat",
                      "Repeat every load call, default: " + std::to_string(args.loadRepeat),
                      false);
  argParser.AddOption(osmscout::CmdLineFlag([&args](const bool& value) {
                        args.flushCache=value;
                      }),
                      "flush-cache",
                      "Flush data caches after each data load, default: " + std::to_string(args.flushCache),
                      false);
  argParser.AddOption(osmscout::CmdLineFlag([&args](const bool& value) {
                        args.flushDiskCache=value;
                      }),
                      "flush-disk",
                      "Flush system disk caches after each data load, default: " + std::to_string(args.flushDiskCache) +
                      " (It work just on Linux with admin rights.)",
                      false);

  argParser.AddOption(osmscout::CmdLineUIntOption([&databaseParameter](const unsigned int& value) {
                        databaseParameter.SetNodeDataCacheSize(value);
                      }),
                      "cache-nodes",
                      "Cache size for nodes, default: " + std::to_string(databaseParameter.GetNodeDataCacheSize()),
                      false);
  argParser.AddOption(osmscout::CmdLineUIntOption([&databaseParameter](const unsigned int& value) {
                        databaseParameter.SetWayDataCacheSize(value);
                      }),
                      "cache-ways",
                      "Cache size for ways, default: " + std::to_string(databaseParameter.GetWayDataCacheSize()),
                      false);
  argParser.AddOption(osmscout::CmdLineUIntOption([&databaseParameter](const unsigned int& value) {
                        databaseParameter.SetAreaDataCacheSize(value);
                      }),
                      "cache-areas",
                      "Cache size for areas, default: " + std::to_string(databaseParameter.GetAreaDataCacheSize()),
                      false);

#if defined(HAVE_LIB_GPERFTOOLS)
  argParser.AddOption(osmscout::CmdLineStringOption([&args](const std::string& value) {
                        args.heapProfilePrefix = value;
                        args.heapProfile = !args.heapProfilePrefix.empty();
                      }),
                      "heap-profile",
                      "GPerf heap profile prefix, profiler is disabled by default",
                      false);
#endif

  argParser.AddPositional(osmscout::CmdLineStringOption([&args](const std::string& value) {
                            args.databaseDirectory=value;
                          }),
                          "databaseDir",
                          "Database directory");
  argParser.AddPositional(osmscout::CmdLineStringOption([&args](const std::string& value) {
                            args.style=value;
                          }),
                          "stylesheet",
                          "Map stylesheet");
  argParser.AddPositional(osmscout::CmdLineGeoCoordOption([&args](const osmscout::GeoCoord& coord) {
                            args.coordTopLeft = coord;
                          }),
                          "lat_top lon_left",
                          "Bounding box top-left coordinate");
  argParser.AddPositional(osmscout::CmdLineGeoCoordOption([&args](const osmscout::GeoCoord& coord) {
                            args.coordBottomRight = coord;
                          }),
                          "lat_bottom lon_right",
                          "Bounding box bottom-right coordinate");

  osmscout::CmdLineParseResult argResult=argParser.Parse();
  if (argResult.HasError()) {
    std::cerr << "ERROR: " << argResult.GetErrorDescription() << std::endl;
    std::cout << argParser.GetHelp() << std::endl;
    return 1;
  }
  else if (args.help) {
    std::cout << argParser.GetHelp() << std::endl;
    return 0;
  }

  osmscout::log.Debug(args.debug);
  //databaseParameter.SetDebugPerformance(true);

  osmscout::DatabaseRef       database=std::make_shared<osmscout::Database>(databaseParameter);
  osmscout::MapServiceRef     mapService=std::make_shared<osmscout::MapService>(database);

  if (!database->Open(args.databaseDirectory)) {
    std::cerr << "Cannot open database" << std::endl;
    return 1;
  }

  osmscout::StyleConfigRef styleConfig=std::make_shared<osmscout::StyleConfig>(database->GetTypeConfig());

  if (!styleConfig->Load(args.style)) {
    std::cerr << "Cannot open style" << std::endl;
    return 1;
  }

  PerformanceTestBackendPtr backendPtr = PrepareBackend(argc, argv, args, styleConfig);
  if (!backendPtr){
    return 1;
  }

#if defined(HAVE_LIB_GPERFTOOLS)
  if (args.heapProfile){
    HeapProfilerStart(args.heapProfilePrefix.c_str());
  }
#endif

  osmscout::TileProjection      projection;
  osmscout::MapParameter        drawParameter;
  osmscout::AreaSearchParameter searchParameter;
  std::list<LevelStats>         statistics;

  // TODO: Use some way to find a valid font on the system (Agg display a ton of messages otherwise)
  drawParameter.SetFontName("/usr/share/fonts/TTF/DejaVuSans.ttf");
  searchParameter.SetUseMultithreading(true);

  for (osmscout::MagnificationLevel level=osmscout::MagnificationLevel(std::min(args.startZoom,args.endZoom));
       level<=osmscout::MagnificationLevel(std::max(args.startZoom,args.endZoom));
       level++) {
    LevelStats              stats(level.Get());
    osmscout::Magnification magnification(level);

    osmscout::OSMTileId     tileA(osmscout::OSMTileId::GetOSMTile(magnification,
                                                                  osmscout::GeoCoord(args.LatBottom(),args.LonLeft())));
    osmscout::OSMTileId     tileB(osmscout::OSMTileId::GetOSMTile(magnification,
                                                                  osmscout::GeoCoord(args.LatTop(),args.LonRight())));
    osmscout::OSMTileIdBox  tileArea(tileA,tileB);

    std::cout << "----------" << std::endl;
    std::cout << "Drawing level " << level << ", " << tileArea.GetCount() << " tiles " << tileArea.GetDisplayText() << std::endl;

    size_t current=1;
    size_t tileCount=tileArea.GetCount();
    size_t delta=tileCount/20;

    if (delta==0) {
      delta=1;
    }

    for (const auto& tile : tileArea) {
      osmscout::MapData       data;
      osmscout::OSMTileIdBox  tileBox(osmscout::OSMTileId(tile.GetX()-1,tile.GetY()-1),
                                      osmscout::OSMTileId(tile.GetX()+1,tile.GetY()+1));
      osmscout::GeoBox        boundingBox;

      if ((current % delta)==0) {
        std::cout << current*100/tileCount << "% " << current;

        if (stats.tileCount>0) {
          std::cout << " " << stats.dbTotalTime/stats.tileCount;
          std::cout << " " << stats.drawTotalTime/stats.tileCount;
        }

        std::cout << std::endl;
      }

      projection.Set(tile,
                     magnification,
                     args.dpi,
                     args.TileWidth(),
                     args.TileHeight());

      projection.GetDimensions(boundingBox);
      projection.SetLinearInterpolationUsage(level.Get() >= 10);

      for (size_t i=0; i<args.loadRepeat; i++) {
        data.nodes.clear();
        data.ways.clear();
        data.areas.clear();

        osmscout::StopClock dbTimer;

        osmscout::GeoBox dataBoundingBox(tileBox.GetBoundingBox(magnification));

        std::list<osmscout::TileRef> tiles;

        // set cache size almost unlimited,
        // for better estimate of peak memory usage by tile loading
        mapService->SetCacheSize(10000000);

        mapService->LookupTiles(magnification, dataBoundingBox, tiles);
        mapService->LoadMissingTileData(searchParameter, *styleConfig, tiles);
        mapService->AddTileDataToMapData(tiles, data);

#if defined(HAVE_LIB_GPERFTOOLS)
        if (args.heapProfile) {
          std::ostringstream buff;
          buff << "load-" << level << "-" << tile.GetX() << "-" << tile.GetY();
          HeapProfilerDump(buff.str().c_str());
        }
        struct mallinfo alloc_info = tc_mallinfo();
#else
#if defined(HAVE_MALLINFO)
        struct mallinfo alloc_info = mallinfo();
#endif
#endif
#if defined(HAVE_MALLINFO) || defined(HAVE_LIB_GPERFTOOLS)
        std::cout << "memory usage: " << formatAlloc(alloc_info.uordblks) << std::endl;
        stats.allocMax = std::max(stats.allocMax, (double) alloc_info.uordblks);
        stats.allocSum = stats.allocSum + (double) alloc_info.uordblks;
#endif

        // set cache size back to default
        mapService->SetCacheSize(25);
        dbTimer.Stop();

        double dbTime = dbTimer.GetMilliseconds();

        stats.dbMinTime = std::min(stats.dbMinTime, dbTime);
        stats.dbMaxTime = std::max(stats.dbMaxTime, dbTime);
        stats.dbTotalTime += dbTime;

        if (args.flushCache) {
          tiles.clear(); // following flush method removes only tiles with use_count() == 1
          mapService->FlushTileCache();

          // simplest way howto flush database caches is close it and open again
          database->Close();
          if (!database->Open(args.databaseDirectory)) {
            std::cerr << "Cannot open database" << std::endl;
            return 1;
          }
        }
        if (args.flushDiskCache) {
          // Linux specific
          if (osmscout::ExistsInFilesystem("/proc/sys/vm/drop_caches")){
            osmscout::FileWriter f;
            try {
              f.Open("/proc/sys/vm/drop_caches");
              f.Write(std::string("3"));
              f.Close();
            }catch(const osmscout::IOException &e){
              std::cerr << "Can't flush disk cache: " << e.what() << std::endl;
            }
          }else{
            std::cerr << "Can't flush disk cache, \"/proc/sys/vm/drop_caches\" file don't exists" << std::endl;
          }
        }
      }

      stats.nodeCount+=data.nodes.size();
      stats.wayCount+=data.ways.size();
      stats.areaCount+=data.areas.size();

      stats.tileCount++;
      for (size_t i=0; i<args.drawRepeat; i++) {
        osmscout::StopClock drawTimer;
        backendPtr->DrawMap(projection, drawParameter, data);
        drawTimer.Stop();

        double drawTime = drawTimer.GetMilliseconds();

        stats.drawMinTime = std::min(stats.drawMinTime, drawTime);
        stats.drawMaxTime = std::max(stats.drawMaxTime, drawTime);
        stats.drawTotalTime += drawTime;
      }

      current++;
    }

    statistics.push_back(stats);
  }

#if defined(HAVE_LIB_GPERFTOOLS)
  if (args.heapProfile){
    HeapProfilerStop();
  }
#endif

  std::cout << "==========" << std::endl;

  for (const auto& stats : statistics) {
    std::cout << "Level: " << stats.level << std::endl;
    std::cout << "Tiles: " << stats.tileCount << " (load " << args.loadRepeat << "x, drawn " << args.drawRepeat << "x)" << std::endl;

#if defined(HAVE_MALLINFO) || defined(HAVE_LIB_GPERFTOOLS)
    std::cout << " Used memory: ";
    std::cout << "max: " << formatAlloc(stats.allocMax) << " ";
    std::cout << "avg: " << formatAlloc(stats.allocSum / (stats.tileCount * args.loadRepeat)) << std::endl;
#endif

    std::cout << " Tot. data  : ";
    std::cout << "nodes: " << stats.nodeCount << " ";
    std::cout << "way: " << stats.wayCount << " ";
    std::cout << "areas: " << stats.areaCount << std::endl;

    if (stats.tileCount>0) {
      std::cout << " Avg. data  : ";
      std::cout << "nodes: " << stats.nodeCount/stats.tileCount << " ";
      std::cout << "way: " << stats.wayCount/stats.tileCount << " ";
      std::cout << "areas: " << stats.areaCount/stats.tileCount << std::endl;
    }

    std::cout << " DB         : ";
    std::cout << "total: " << stats.dbTotalTime << " ";
    std::cout << "min: " << stats.dbMinTime << " ";
    if (stats.tileCount>0) {
      std::cout << "avg: " << stats.dbTotalTime/(stats.tileCount * args.loadRepeat) << " ";
    }
    std::cout << "max: " << stats.dbMaxTime << " " << std::endl;

    std::cout << " Map        : ";
    std::cout << "total: " << stats.drawTotalTime << " ";
    std::cout << "min: " << stats.drawMinTime << " ";
    if (stats.tileCount>0) {
      std::cout << "avg: " << stats.drawTotalTime/(stats.tileCount * args.drawRepeat) << " ";
    }
    std::cout << "max: " << stats.drawMaxTime << std::endl;
  }

  database->Close();

  return 0;
}