replay: improve segment download and merge (#22654)
* no-cache mode * fix test cases build error * space * don't create cache dir in no-cache mode * fix errors in test cases * no_local_cache_ * set the number of connections by chunk_size * use size_t instead of int64_t * add test case for no-cache mode * rename variables * fix SIGSEGV * cleanup * faster decompressBZ2 * always decompress bz2 * add test cases * prepare for python interface * fix test cases build error * continue * camera_replay: cache remote file * protected inheritance * single option name * TODO * test_case for LogReader&FrameReader * fix wrong require * test case for FileReader * cleanup test * test:fix wrong filename * check cached file's checksum * fix mkdir permissions err cleanup filereader * remove initialize libav network libraries. dd * abort all loading if one failed * cleanup tests * use threadpool to limit concurrent downloads * cache more segments * merge 3 segments for replay * one segment uses about 100M of memory * use segments_need_merge.size() * shutdown * fix stuck if exit replay before keyboard thread started * load one segment at a time * small cleanup * cleanup filereader * space * tiny cleanup * merge master * cleanup test cases * use util:create_directories * cleanup framereaderpull/22769/head
parent
5b93d44459
commit
2b4a477fbc
19 changed files with 347 additions and 237 deletions
@ -0,0 +1,62 @@ |
|||||||
|
#include "selfdrive/ui/replay/filereader.h" |
||||||
|
|
||||||
|
#include <sys/stat.h> |
||||||
|
|
||||||
|
#include <cassert> |
||||||
|
#include <cmath> |
||||||
|
#include <fstream> |
||||||
|
#include <iostream> |
||||||
|
#include <sstream> |
||||||
|
|
||||||
|
#include "selfdrive/common/util.h" |
||||||
|
#include "selfdrive/ui/replay/util.h" |
||||||
|
|
||||||
|
std::string cacheFilePath(const std::string &url) { |
||||||
|
static std::string cache_path = [] { |
||||||
|
const std::string comma_cache = util::getenv("COMMA_CACHE", "/tmp/comma_download_cache/"); |
||||||
|
util::create_directories(comma_cache, 0755); |
||||||
|
return comma_cache.back() == '/' ? comma_cache : comma_cache + "/"; |
||||||
|
}(); |
||||||
|
|
||||||
|
return cache_path + sha256(getUrlWithoutQuery(url));; |
||||||
|
} |
||||||
|
|
||||||
|
std::string FileReader::read(const std::string &file, std::atomic<bool> *abort) { |
||||||
|
const bool is_remote = file.find("https://") == 0; |
||||||
|
const std::string local_file = is_remote ? cacheFilePath(file) : file; |
||||||
|
std::string result; |
||||||
|
|
||||||
|
if ((!is_remote || cache_to_local_) && util::file_exists(local_file)) { |
||||||
|
result = util::read_file(local_file); |
||||||
|
} else if (is_remote) { |
||||||
|
result = download(file, abort); |
||||||
|
if (cache_to_local_ && !result.empty()) { |
||||||
|
std::ofstream fs(local_file, fs.binary | fs.out); |
||||||
|
fs.write(result.data(), result.size()); |
||||||
|
} |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
std::string FileReader::download(const std::string &url, std::atomic<bool> *abort) { |
||||||
|
std::string result; |
||||||
|
size_t remote_file_size = 0; |
||||||
|
for (int i = 0; i <= max_retries_ && !(abort && *abort); ++i) { |
||||||
|
if (i > 0) { |
||||||
|
std::cout << "download failed, retrying" << i << std::endl; |
||||||
|
} |
||||||
|
if (remote_file_size <= 0) { |
||||||
|
remote_file_size = getRemoteFileSize(url); |
||||||
|
} |
||||||
|
if (remote_file_size > 0 && !(abort && *abort)) { |
||||||
|
std::ostringstream oss; |
||||||
|
result.resize(remote_file_size); |
||||||
|
oss.rdbuf()->pubsetbuf(result.data(), result.size()); |
||||||
|
int chunks = chunk_size_ > 0 ? std::min(1, (int)std::nearbyint(remote_file_size / (float)chunk_size_)) : 1; |
||||||
|
if (httpMultiPartDownload(url, oss, chunks, remote_file_size, abort)) { |
||||||
|
return result; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return {}; |
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <atomic> |
||||||
|
#include <string> |
||||||
|
|
||||||
|
class FileReader { |
||||||
|
public: |
||||||
|
FileReader(bool cache_to_local, int chunk_size = -1, int max_retries = 3) |
||||||
|
: cache_to_local_(cache_to_local), chunk_size_(chunk_size), max_retries_(max_retries) {} |
||||||
|
virtual ~FileReader() {} |
||||||
|
std::string read(const std::string &file, std::atomic<bool> *abort = nullptr); |
||||||
|
|
||||||
|
private: |
||||||
|
std::string download(const std::string &url, std::atomic<bool> *abort); |
||||||
|
int chunk_size_; |
||||||
|
int max_retries_; |
||||||
|
bool cache_to_local_; |
||||||
|
}; |
||||||
|
|
||||||
|
std::string cacheFilePath(const std::string &url); |
Loading…
Reference in new issue