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 framereader
old-commit-hash: 2b4a477fbc
commatwo_master
parent
3a8fdaba2f
commit
a031b938b0
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