IndexDecoderData(std::string const & rfilename) : filename(rfilename), numentries(0), posbits(0), kbits(0), kacc(0), vbits(0), vacc(0), indexvectorpos(0) // , posadpt(this), kadpt(this), vadpt(this) { uint64_t const indexpos = getIndexPos(filename); std::ifstream indexistr(filename.c_str(),std::ios::binary); if ( ! indexistr.is_open() ) { ::libmaus2::exception::LibMausException se; se.getStream() << "IndexDecoderData::IndexDecoderData(): Failed to open file " << filename << std::endl; se.finish(); throw se; } // seek to index position indexistr.clear(); indexistr.seekg(indexpos,std::ios::beg); if ( static_cast<int64_t>(indexistr.tellg()) != static_cast<int64_t>(indexpos) ) { ::libmaus2::exception::LibMausException se; se.getStream() << "Failed to seek to position " << indexpos << " of index in file " << filename << " of size " << ::libmaus2::util::GetFileSize::getFileSize(filename) << std::endl; se.finish(); throw se; } ::libmaus2::bitio::StreamBitInputStream SBIS(indexistr); // read size of index numentries = ::libmaus2::bitio::readElias2(SBIS); // pos bits posbits = ::libmaus2::bitio::readElias2(SBIS); // k bits kbits = ::libmaus2::bitio::readElias2(SBIS); // k acc kacc = ::libmaus2::bitio::readElias2(SBIS); // v bits vbits = ::libmaus2::bitio::readElias2(SBIS); // v acc vacc = ::libmaus2::bitio::readElias2(SBIS); // align SBIS.flush(); assert ( SBIS.getBitsRead() % 8 == 0 ); indexvectorpos = indexpos + SBIS.getBitsRead() / 8; }
/* * load index for one file */ static IndexEntryContainer::unique_ptr_type loadAccIndex(std::string const & filename) { uint64_t const indexpos = getIndexPos(filename); ::libmaus::aio::CheckedInputStream indexistr(filename); // seek to index position indexistr.seekg(indexpos,std::ios::beg); // ::libmaus::bitio::StreamBitInputStream SBIS(indexistr); // read size of index uint64_t const numentries = ::libmaus::bitio::readElias2(SBIS); // pos bits unsigned int const posbits = ::libmaus::bitio::readElias2(SBIS); // k bits unsigned int const kbits = ::libmaus::bitio::readElias2(SBIS); // k acc /* uint64_t const symacc = */ ::libmaus::bitio::readElias2(SBIS); // v bits unsigned int const vbits = ::libmaus::bitio::readElias2(SBIS); // v acc /* uint64_t const symacc = */ ::libmaus::bitio::readElias2(SBIS); // align SBIS.flush(); SBIS.getBitsRead(); // std::cerr << "numentries " << numentries << std::endl; // read index libmaus::autoarray::AutoArray< IndexEntry > index(numentries+1,false); for ( uint64_t i = 0; i < numentries+1; ++i ) { uint64_t const pos = SBIS.read(posbits); uint64_t const kcnt = SBIS.read(kbits); uint64_t const vcnt = SBIS.read(vbits); index[i] = IndexEntry(pos,kcnt,vcnt); } IndexEntryContainer::unique_ptr_type IEC(new IndexEntryContainer(index)); return UNIQUE_PTR_MOVE(IEC); }
IndexLoaderSequential(std::string const & filename) : indexistr(filename), SBIS(indexistr) { uint64_t const indexpos = getIndexPos(filename); indexistr.seekg(indexpos,std::ios::beg); // read size of index numentries = ::libmaus::bitio::readElias2(SBIS); // pos bits posbits = ::libmaus::bitio::readElias2(SBIS); // k bits kbits = ::libmaus::bitio::readElias2(SBIS); // k acc /* uint64_t const symacc = */ ::libmaus::bitio::readElias2(SBIS); // v bits vbits = ::libmaus::bitio::readElias2(SBIS); // v acc /* uint64_t const symacc = */ ::libmaus::bitio::readElias2(SBIS); // align SBIS.flush(); }
/* * load index for one file */ static libmaus::autoarray::AutoArray< IndexEntry > loadIndex(std::string const & filename) { uint64_t const indexpos = getIndexPos(filename); std::ifstream indexistr(filename.c_str(),std::ios::binary); if ( ! indexistr.is_open() ) { ::libmaus::exception::LibMausException se; se.getStream() << "RLDecoder::loadIndex(): Failed to open file " << filename << std::endl; se.finish(); throw se; } // seek to index position indexistr.seekg(indexpos,std::ios::beg); if ( static_cast<int64_t>(indexistr.tellg()) != static_cast<int64_t>(indexpos) ) { ::libmaus::exception::LibMausException se; se.getStream() << "Failed to seek to index position " << indexpos << " in file " << filename << " of size " << ::libmaus::util::GetFileSize::getFileSize(filename) << std::endl; se.finish(); throw se; } ::libmaus::bitio::StreamBitInputStream SBIS(indexistr); // read size of index uint64_t const numentries = ::libmaus::bitio::readElias2(SBIS); // pos bits unsigned int const posbits = ::libmaus::bitio::readElias2(SBIS); // k bits unsigned int const kbits = ::libmaus::bitio::readElias2(SBIS); // k acc /* uint64_t const symacc = */ ::libmaus::bitio::readElias2(SBIS); // v bits unsigned int const vbits = ::libmaus::bitio::readElias2(SBIS); // v acc /* uint64_t const symacc = */ ::libmaus::bitio::readElias2(SBIS); // align SBIS.flush(); SBIS.getBitsRead(); // std::cerr << "numentries " << numentries << std::endl; // read index libmaus::autoarray::AutoArray< IndexEntry > index(numentries,false); // #define INDEXLOADERDEBUG #if defined(INDEXLOADERDEBUG) libmaus::autoarray::AutoArray< IndexEntry > tindex(numentries+1); #endif for ( uint64_t i = 0; i < numentries; ++i ) { uint64_t const pos = SBIS.read(posbits); uint64_t const kcnt = SBIS.read(kbits); uint64_t const vcnt = SBIS.read(vbits); index[i] = IndexEntry(pos,kcnt,vcnt); #if defined(INDEXLOADERDEBUG) tindex[i] = index[i]; #endif } if ( numentries ) { assert ( index[0].kcnt == 0 ); assert ( index[0].vcnt == 0 ); for ( uint64_t i = 1; i < numentries; ++i ) { index[i-1].kcnt = index[i].kcnt; index[i-1].vcnt = index[i].vcnt; } /* uint64_t const pos = */ SBIS.read(posbits); index[numentries-1].kcnt = SBIS.read(kbits); index[numentries-1].vcnt = SBIS.read(vbits); #if defined(INDEXLOADERDEBUG) tindex[numentries].kcnt = index[numentries-1].kcnt; tindex[numentries].vcnt = index[numentries-1].vcnt; #endif } for ( uint64_t i = numentries-1; i >= 1; --i ) { index[i].kcnt -= index[i-1].kcnt; index[i].vcnt -= index[i-1].vcnt; } #if defined(INDEXLOADERDEBUG) for ( uint64_t i = 0; i < numentries; ++i ) { assert ( index[i].kcnt == tindex[i+1].kcnt-tindex[i].kcnt ); assert ( index[i].vcnt == tindex[i+1].vcnt-tindex[i].vcnt ); } #endif #if defined(INDEXLOADERDEBUG) IndexDecoderData IDD(filename); assert ( IDD.numentries == numentries ); assert ( IDD.posbits == posbits ); assert ( IDD.kbits == kbits ); assert ( IDD.vbits == vbits ); // assert ( IDD.symacc == symacc ); std::cerr << "((**++CHECKING " << numentries << "..."; uint64_t tkacc = 0; uint64_t tvacc = 0; for ( uint64_t i = 0; i < numentries; ++i ) { IndexEntry const P = IDD.readEntry(i); assert ( P.pos == index[i].pos ); assert ( P.kcnt == tkacc ); assert ( P.vcnt == tvacc ); tkacc += index[i].kcnt; tvacc += index[i].vcnt; } assert ( tkacc == IDD.readEntry(numentries).kcnt ); assert ( tvacc == IDD.readEntry(numentries).vcnt ); std::cerr << "**++))" << std::endl; #endif // std::cerr << "loaded index of size " << numentries << std::endl; return index; }
std::vector<v3s16> Pathfinder::getPath(ServerEnvironment *env, v3s16 source, v3s16 destination, unsigned int searchdistance, unsigned int max_jump, unsigned int max_drop, PathAlgorithm algo) { #ifdef PATHFINDER_CALC_TIME timespec ts; clock_gettime(CLOCK_REALTIME, &ts); #endif std::vector<v3s16> retval; //check parameters if (env == 0) { ERROR_TARGET << "missing environment pointer" << std::endl; return retval; } m_searchdistance = searchdistance; m_env = env; m_maxjump = max_jump; m_maxdrop = max_drop; m_start = source; m_destination = destination; m_min_target_distance = -1; m_prefetch = true; if (algo == PA_PLAIN_NP) { m_prefetch = false; } int min_x = MYMIN(source.X, destination.X); int max_x = MYMAX(source.X, destination.X); int min_y = MYMIN(source.Y, destination.Y); int max_y = MYMAX(source.Y, destination.Y); int min_z = MYMIN(source.Z, destination.Z); int max_z = MYMAX(source.Z, destination.Z); m_limits.MinEdge.X = min_x - searchdistance; m_limits.MinEdge.Y = min_y - searchdistance; m_limits.MinEdge.Z = min_z - searchdistance; m_limits.MaxEdge.X = max_x + searchdistance; m_limits.MaxEdge.Y = max_y + searchdistance; m_limits.MaxEdge.Z = max_z + searchdistance; v3s16 diff = m_limits.MaxEdge - m_limits.MinEdge; m_max_index_x = diff.X; m_max_index_y = diff.Y; m_max_index_z = diff.Z; delete m_nodes_container; if (diff.getLength() > 5) { m_nodes_container = new MapGridNodeContainer(this); } else { m_nodes_container = new ArrayGridNodeContainer(this, diff); } #ifdef PATHFINDER_DEBUG printType(); printCost(); printYdir(); #endif //validate and mark start and end pos v3s16 StartIndex = getIndexPos(source); v3s16 EndIndex = getIndexPos(destination); PathGridnode &startpos = getIndexElement(StartIndex); PathGridnode &endpos = getIndexElement(EndIndex); if (!startpos.valid) { VERBOSE_TARGET << "invalid startpos" << "Index: " << PP(StartIndex) << "Realpos: " << PP(getRealPos(StartIndex)) << std::endl; return retval; } if (!endpos.valid) { VERBOSE_TARGET << "invalid stoppos" << "Index: " << PP(EndIndex) << "Realpos: " << PP(getRealPos(EndIndex)) << std::endl; return retval; } endpos.target = true; startpos.source = true; startpos.totalcost = 0; bool update_cost_retval = false; switch (algo) { case PA_DIJKSTRA: update_cost_retval = updateAllCosts(StartIndex, v3s16(0, 0, 0), 0, 0); break; case PA_PLAIN_NP: case PA_PLAIN: update_cost_retval = updateCostHeuristic(StartIndex, v3s16(0, 0, 0), 0, 0); break; default: ERROR_TARGET << "missing PathAlgorithm"<< std::endl; break; } if (update_cost_retval) { #ifdef PATHFINDER_DEBUG std::cout << "Path to target found!" << std::endl; printPathLen(); #endif //find path std::vector<v3s16> path; buildPath(path, EndIndex, 0); #ifdef PATHFINDER_DEBUG std::cout << "Full index path:" << std::endl; printPath(path); #endif //finalize path std::vector<v3s16> full_path; for (std::vector<v3s16>::iterator i = path.begin(); i != path.end(); ++i) { full_path.push_back(getIndexElement(*i).pos); } #ifdef PATHFINDER_DEBUG std::cout << "full path:" << std::endl; printPath(full_path); #endif #ifdef PATHFINDER_CALC_TIME timespec ts2; clock_gettime(CLOCK_REALTIME, &ts2); int ms = (ts2.tv_nsec - ts.tv_nsec)/(1000*1000); int us = ((ts2.tv_nsec - ts.tv_nsec) - (ms*1000*1000))/1000; int ns = ((ts2.tv_nsec - ts.tv_nsec) - ( (ms*1000*1000) + (us*1000))); std::cout << "Calculating path took: " << (ts2.tv_sec - ts.tv_sec) << "s " << ms << "ms " << us << "us " << ns << "ns " << std::endl; #endif return full_path; } else { #ifdef PATHFINDER_DEBUG printPathLen(); #endif ERROR_TARGET << "failed to update cost map"<< std::endl; } //return return retval; }