Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 51 additions & 3 deletions src/image_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,12 +334,12 @@ LSMT::IFileRO *ImageFile::open_lowers(std::vector<ImageConfigNS::LayerConfig> &l
return NULL;

photon::join_handle *ths[PARALLEL_LOAD_INDEX];
std::vector<IFile *> files;
std::vector<IFile *> files; // layer0 ... layerN-1
files.resize(lowers.size(), nullptr);
auto n = std::min(PARALLEL_LOAD_INDEX, (int)lowers.size());
LOG_DEBUG("create ` photon threads to open lowers", n);

ParallelOpenTask tm(files, lowers.size(), lowers);
ParallelOpenTask tm(files, lowers.size(), lowers); // layer0 ... layerN-1
for (auto i = 0; i < n; ++i) {
ths[i] =
photon::thread_enable_join(photon::thread_create11(&do_parallel_open_files, this, tm));
Expand Down Expand Up @@ -443,7 +443,7 @@ int ImageFile::init_image_file() {
ImageConfigNS::UpperConfig upper;
bool record_no_download = false;
bool has_error = false;
auto lowers = conf.lowers();
auto lowers = conf.lowers(); // layer0 ... layerN-1
auto concurrency = image_service.global_conf.prefetchConfig().concurrency();

if (conf.accelerationLayer() && !conf.recordTracePath().empty()) {
Expand Down Expand Up @@ -554,3 +554,51 @@ void ImageFile::set_failed(const Ts &...xs) {
m_exception = estring().appends(xs...);
}
}

int ImageFile::create_snapshot(const char *config_path) {
// load new config file to get the snapshot layer path
// open new upper layer
// restack() current RW layer as snapshot layer
if(!m_lower_file || !m_upper_file)
LOG_ERROR_RETURN(0, -1, "Lower or upper layer is NULL.");

ImageConfigNS::ImageConfig new_cfg;
LSMT::IFileRW *upper_file = nullptr;

LOG_INFO("Load new config `.", config_path);
if (!new_cfg.ParseJSON(config_path)) {
LOG_ERROR_RETURN(0, -1, "Error parse new config json: `.", config_path);
}

auto upper = new_cfg.upper();
auto lowers = new_cfg.lowers();
// if(lowers[lowers.size()-1].file() != conf.upper().data())
// LOG_ERROR_RETURN(0, -1, "The last lower layer(`) should be the same as old upper layer(`) after restack.", lowers[lowers.size()-1].file(), conf.upper().data());
if(upper.index() == conf.upper().index() || upper.data() == conf.upper().data())
LOG_ERROR_RETURN(0, -1, "The new upper layer(`, `) should be different from the old upper layer(`, `).", upper.data(), upper.index(), conf.upper().data(), conf.upper().index());

upper_file = open_upper(upper);
if (!upper_file)
LOG_ERROR_RETURN(0, -1, "Open upper layer failed.");

if(((LSMT::IFileRW *)m_file)->restack(upper_file) != 0)
LOG_ERRNO_RETURN(0, -1, "Restack new rwlayer failed.");

if(m_upper_file) {
// transfer the sealed layer from m_upper_file to m_lower_file before m_upper_file is destructed
auto sealed = ((LSMT::IFileRW *)m_upper_file)->get_file(0);
((LSMT::IFileRO *)m_lower_file)->insert_file(sealed);
((LSMT::IFileRW *)m_upper_file)->clear_files();
delete m_upper_file;
}
// set m_lower_file->m_index = m_file->m_index->m_backing_index because m_file is not responsible for the destruction of m_backing_index
auto combo_index = (LSMT::IComboIndex *)((LSMT::IFileRW *)m_file)->index(); // m_file->m_index
((LSMT::IFileRO *)m_lower_file)->index(combo_index->backing_index());
// set m_file->m_index->m_index0 = upper_file->m_index
auto upper_file_index = (LSMT::IMemoryIndex0 *)((LSMT::IFileRW *)upper_file)->index(); // upper_file->m_index
combo_index->front_index(upper_file_index);

m_upper_file = upper_file;

return 0;
}
8 changes: 1 addition & 7 deletions src/image_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,7 @@ class ImageFile : public photon::fs::ForwardFile {

int compact(IFile *as);

int create_snapshot(const char *config_path) {
// load new config file to get the snapshot layer path
// open new upper layer
// restack() current RW layer as snapshot layer
LOG_INFO("call create_snapshot, dev_id: `", m_dev_id);
return 0;
}
int create_snapshot(const char *config_path);

private:
Prefetcher *m_prefetcher = nullptr;
Expand Down
38 changes: 36 additions & 2 deletions src/overlaybd/lsmt/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,20 @@ class LSMTReadOnlyFile : public IFileRW {
return (IMemoryIndex0 *)m_index;
}

virtual int index(const IMemoryIndex *index) override {
if(!index || !index->buffer()) {
errno = EINVAL;
LOG_ERROR("Invalid index!");
return -1;
}
if (m_index != nullptr) {
delete m_index;
m_index = nullptr;
}
m_index = (IMemoryIndex *)index;
return 0;
}

virtual int close() override {
safe_delete(m_index);
if (m_file_ownership) {
Expand All @@ -523,6 +537,23 @@ class LSMTReadOnlyFile : public IFileRW {
return m_files;
}

virtual IFile *get_file(size_t file_idx) const override {
if (file_idx >= m_files.size()) {
LOG_ERROR_RETURN(0, nullptr, "file_idx out of range.");
}
return m_files[file_idx];
}

virtual int insert_file(IFile * file) override {
m_files.insert(m_files.begin(), file);
return 0;
}

virtual int clear_files() override {
m_files.clear();
return 0;
}

template <typename T1, typename T2, typename T3>
inline void forward(void *&buffer, T1 &offset, T2 &count, T3 step) {
(char *&)buffer += step * ALIGNMENT;
Expand Down Expand Up @@ -1038,6 +1069,9 @@ class LSMTFile : public LSMTReadOnlyFile {
m_findex = u->m_findex;
m_vsize = u->m_vsize;
((IComboIndex *)m_index)->commit_index0();

delete fseal;
delete gc_layer;
return 0;
}

Expand Down Expand Up @@ -1333,7 +1367,7 @@ static SegmentMapping *do_load_index(IFile *file, HeaderTrailer *pheader_trailer
auto ret = file->fstat(&stat);
if (ret < 0)
LOG_ERRNO_RETURN(0, nullptr, "failed to stat file.");
assert(pht->is_sparse_rw() == false);
assert(trailer || pht->is_sparse_rw() == false);
uint64_t index_bytes;
if (trailer) {
if (!pht->is_data_file())
Expand Down Expand Up @@ -1738,7 +1772,7 @@ static IMemoryIndex *load_merge_index(vector<IFile *> &files, vector<UUID> &uuid
}
}

std::reverse(files.begin(), files.end());
std::reverse(files.begin(), files.end()); // reverse files: layerN-1 ... layer0
std::reverse(tm.indexes.begin(), tm.indexes.end());
std::reverse(uuid.begin(), uuid.end());
auto pmi = merge_memory_indexes((const IMemoryIndex **)&tm.indexes[0], tm.indexes.size());
Expand Down
8 changes: 8 additions & 0 deletions src/overlaybd/lsmt/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,19 @@ class IFileRO : public photon::fs::VirtualReadOnlyFile {

virtual IMemoryIndex *index() const = 0;

virtual int index(const IMemoryIndex *index) = 0;

// return uuid of m_files[layer_idx];
virtual int get_uuid(UUID &out, size_t layer_idx = 0) const = 0;

virtual std::vector<IFile *> get_lower_files() const = 0;

virtual IFile *get_file(size_t file_idx) const = 0;

virtual int insert_file(IFile * file) = 0;

virtual int clear_files() = 0;

virtual ssize_t seek_data(off_t begin, off_t end, std::vector<Segment> &segs) = 0;

virtual int flatten(IFile *as) = 0;
Expand Down
18 changes: 17 additions & 1 deletion src/overlaybd/lsmt/index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,7 @@ class Index0 : public IComboIndex {
virtual const IMemoryIndex0 *front_index() const override {
return this;
}
UNIMPLEMENTED(int front_index(const IMemoryIndex0 *fi) override);
UNIMPLEMENTED(size_t vsize() const override);
UNIMPLEMENTED(int commit_index0() override);
};
Expand Down Expand Up @@ -649,6 +650,19 @@ class ComboIndex : public Index0 {
}
}

virtual int front_index(const IMemoryIndex0 *fi) override {
if (!fi) {
errno = EINVAL;
LOG_ERROR("Invalid index!");
return -1;
}
if (m_ownership && m_index0 != nullptr) { // !!!
delete m_index0;
m_index0 = nullptr;
}
m_index0 = (Index0 *)fi;
return 0;
}
virtual const IMemoryIndex0 *front_index() const override {
return this->m_index0;
}
Expand Down Expand Up @@ -759,7 +773,9 @@ class ComboIndex : public Index0 {
p.tag = 0;
merged_index->insert(p);
}
delete m_backing_index;
if(m_ownership) { // !!!
delete m_backing_index;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need { }

}
m_backing_index = (Index*)(merged_index->make_read_only_index()); // set ownership=false
delete merged_index;
LOG_INFO("rebuild backing index done. {count: `}", m_backing_index->size());
Expand Down
1 change: 1 addition & 0 deletions src/overlaybd/lsmt/index.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ class IComboIndex : public IMemoryIndex0 {
// backing index must NOT be IMemoryIndex0!
virtual int backing_index(const IMemoryIndex *bi) = 0;
virtual const IMemoryIndex *backing_index() const = 0;
virtual int front_index(const IMemoryIndex0 *fi) = 0;
virtual const IMemoryIndex0 *front_index() const = 0;

// dump index0 which needs to compact
Expand Down
Loading