Skip to content

Commit b33ab47

Browse files
authored
Merge pull request #308 from liulanzheng/main
add some method for lsmt, rename crc32c for zfile
2 parents 8f949ce + a3d5799 commit b33ab47

File tree

5 files changed

+107
-44
lines changed

5 files changed

+107
-44
lines changed

src/overlaybd/lsmt/file.cpp

Lines changed: 64 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ limitations under the License.
1515
*/
1616
#include "file.h"
1717
#include <cstdint>
18-
#include <openssl/bio.h>
1918
#include <string.h>
2019
#include <stdarg.h>
2120
#include <memory>
@@ -165,7 +164,7 @@ struct HeaderTrailer {
165164

166165
UUID::String uuid; // 37 bytes.
167166
UUID::String parent_uuid; // 37 bytes.
168-
uint16_t reserved; // Reserved.
167+
uint16_t reserved; // Reserved.
169168

170169
static const uint8_t LSMT_V1 = 1; // v1 (UUID check)
171170
static const uint8_t LSMT_SUB_V1 = 1; // .1 deprecated level range.
@@ -179,7 +178,8 @@ struct HeaderTrailer {
179178

180179
class LSMTReadOnlyFile;
181180
static LSMTReadOnlyFile *open_file_ro(IFile *file, bool ownership, bool reserve_tag);
182-
static HeaderTrailer *verify_ht(IFile *file, char *buf, bool is_trailer = false, ssize_t st_size = -1);
181+
static HeaderTrailer *verify_ht(IFile *file, char *buf, bool is_trailer = false,
182+
ssize_t st_size = -1);
183183

184184
static const uint32_t ALIGNMENT = 512; // same as trim block size.
185185
static const uint32_t ALIGNMENT4K = 4096;
@@ -520,6 +520,10 @@ class LSMTReadOnlyFile : public IFileRW {
520520
return 0;
521521
}
522522

523+
virtual std::vector<IFile *> get_lower_files() const override {
524+
return m_files;
525+
}
526+
523527
template <typename T1, typename T2, typename T3>
524528
inline void forward(void *&buffer, T1 &offset, T2 &count, T3 step) {
525529
(char *&)buffer += step * ALIGNMENT;
@@ -618,7 +622,8 @@ class LSMTReadOnlyFile : public IFileRW {
618622
if (!pht->is_sealed()) {
619623
LOG_ERROR_RETURN(ENOTSUP, -1, "Commit a compacted LSMTReadonlyFile is not allowed.");
620624
}
621-
CompactOptions opts(&m_files, (SegmentMapping*)m_index->buffer(), m_index->size(), m_vsize, &args);
625+
CompactOptions opts(&m_files, (SegmentMapping *)m_index->buffer(), m_index->size(), m_vsize,
626+
&args);
622627

623628
atomic_uint64_t _no_use_var(0);
624629
return compact(opts, _no_use_var);
@@ -1053,9 +1058,9 @@ class LSMTSparseFile : public LSMTFile {
10531058
class LSMTWarpFile : public LSMTFile {
10541059
public:
10551060
const static int READ_BUFFER_SIZE = 65536;
1056-
IFile* m_target_file = nullptr;
1061+
IFile *m_target_file = nullptr;
10571062

1058-
LSMTWarpFile(){
1063+
LSMTWarpFile() {
10591064
m_filetype = LSMTFileType::WarpFile;
10601065
}
10611066
~LSMTWarpFile() {
@@ -1074,11 +1079,11 @@ class LSMTWarpFile : public LSMTFile {
10741079
};
10751080
m.tag = tag;
10761081
auto file = m_files[tag];
1077-
LOG_DEBUG("insert segment: `, filePtr: `", m,file);
1082+
LOG_DEBUG("insert segment: `, filePtr: `", m, file);
10781083
auto ret = file->pwrite(buf, count, offset);
10791084
if (ret != (ssize_t)count) {
1080-
LOG_ERRNO_RETURN(0, -1, "write failed, file:`, ret:`, pos:`, count:`",
1081-
file, ret, offset, count);
1085+
LOG_ERRNO_RETURN(0, -1, "write failed, file:`, ret:`, pos:`, count:`", file, ret,
1086+
offset, count);
10821087
}
10831088
static_cast<IMemoryIndex0 *>(m_index)->insert(m);
10841089
append_index(m);
@@ -1102,8 +1107,8 @@ class LSMTWarpFile : public LSMTFile {
11021107
while (lba.count > 0) {
11031108
SegmentMapping m;
11041109
m.offset = lba.offset / ALIGNMENT;
1105-
m.length = (Segment::MAX_LENGTH < lba.count / ALIGNMENT ?
1106-
Segment::MAX_LENGTH : lba.count / ALIGNMENT);
1110+
m.length = (Segment::MAX_LENGTH < lba.count / ALIGNMENT ? Segment::MAX_LENGTH
1111+
: lba.count / ALIGNMENT);
11071112
m.moffset = lba.roffset / ALIGNMENT;
11081113
m.tag = m_rw_tag + (uint8_t)SegmentType::remoteData;
11091114
LOG_DEBUG("insert segment: ` into findex: `", m, m_findex);
@@ -1211,8 +1216,8 @@ static HeaderTrailer *verify_ht(IFile *file, char *buf, bool is_trailer, ssize_t
12111216
LOG_ERRNO_RETURN(0, nullptr, "failed to read file trailer.");
12121217
if (!pht->verify_magic() || !pht->is_trailer() || !pht->is_data_file() || !pht->is_sealed())
12131218
LOG_ERROR_RETURN(0, nullptr,
1214-
"trailer magic, trailer type, "
1215-
"file type or sealedness doesn't match");
1219+
"trailer magic, trailer type, "
1220+
"file type or sealedness doesn't match");
12161221
return pht;
12171222
}
12181223

@@ -1266,13 +1271,14 @@ static SegmentMapping *do_load_index(IFile *file, HeaderTrailer *pheader_trailer
12661271
if (ibuf[i].offset != SegmentMapping::INVALID_OFFSET) {
12671272
ibuf[index_size] = ibuf[i];
12681273
ibuf[index_size].tag = (warp_file_tag ? ibuf[i].tag : 0);
1269-
if (min_tag > ibuf[index_size].tag) min_tag = ibuf[index_size].tag;
1274+
if (min_tag > ibuf[index_size].tag)
1275+
min_tag = ibuf[index_size].tag;
12701276
index_size++;
12711277
}
12721278
}
12731279
if (warp_file_tag) {
12741280
LOG_INFO("rebuild index tag for LSMTWarpFile.");
1275-
for (size_t i = 0; i<index_size; i++) {
1281+
for (size_t i = 0; i < index_size; i++) {
12761282
if (warp_file_tag == 1) /* only fsmeta */
12771283
ibuf[i].tag = (uint8_t)SegmentType::fsMeta;
12781284
if (warp_file_tag == 2) /* only remote data */
@@ -1451,8 +1457,7 @@ IFileRW *open_warpfile_rw(IFile *findex, IFile *fsmeta_file, IFile *target_file,
14511457
auto rst = new LSMTWarpFile;
14521458
rst->m_files.resize(2);
14531459
LSMT::HeaderTrailer ht;
1454-
auto p = do_load_index(findex, &ht, false,
1455-
3);
1460+
auto p = do_load_index(findex, &ht, false, 3);
14561461
auto pi = create_memory_index0(p, ht.index_size, 0, -1);
14571462
if (!pi) {
14581463
delete[] p;
@@ -1785,4 +1790,46 @@ IFileRW *stack_files(IFileRW *upper_layer, IFileRO *lower_layers, bool ownership
17851790
return rst;
17861791
}
17871792

1793+
IMemoryIndex *open_file_index(IFile *file) {
1794+
HeaderTrailer ht;
1795+
auto p = do_load_index(file, &ht, true);
1796+
if (!p) {
1797+
LOG_ERROR_RETURN(0, nullptr, "failed to load index");
1798+
}
1799+
1800+
auto pi = create_memory_index(p, ht.index_size, HeaderTrailer::SPACE / ALIGNMENT,
1801+
ht.index_offset / ALIGNMENT, true, ht.virtual_size);
1802+
if (!pi) {
1803+
delete[] p;
1804+
LOG_ERROR_RETURN(0, nullptr, "failed to create memory index");
1805+
}
1806+
return pi;
1807+
}
1808+
1809+
IFileRO *open_files_with_merged_index(IFile **src_files, size_t n, IMemoryIndex *index,
1810+
bool ownership) {
1811+
vector<IFile *> m_files(src_files, src_files + n);
1812+
auto rst = new LSMTReadOnlyFile;
1813+
rst->m_index = index;
1814+
rst->m_files = move(m_files);
1815+
rst->m_vsize = index->vsize();
1816+
rst->m_uuid.resize(rst->m_files.size());
1817+
rst->m_file_ownership = ownership;
1818+
return rst;
1819+
}
1820+
1821+
int is_lsmt(IFile *file) {
1822+
char buf[HeaderTrailer::SPACE];
1823+
auto ret = file->pread(buf, HeaderTrailer::SPACE, 0);
1824+
if (ret < (ssize_t)HeaderTrailer::SPACE)
1825+
LOG_ERRNO_RETURN(0, -1, "failed to read file header.");
1826+
auto pht = (HeaderTrailer *)buf;
1827+
if (!pht->verify_magic() || !pht->is_header()) {
1828+
LOG_DEBUG("file: ` is not lsmt object", file);
1829+
return 1;
1830+
}
1831+
LOG_DEBUG("file: ` is lsmt object", file);
1832+
return 0;
1833+
}
1834+
17881835
} // namespace LSMT

src/overlaybd/lsmt/file.h

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ IMemoryIndex -> IMemoryIndex0 -> IComboIndex -> Index0 ( set<SegmentMap> ) -> Co
2525
#pragma once
2626
#include <inttypes.h>
2727
#include <cstddef>
28+
#include <vector>
2829
#include <photon/fs/filesystem.h>
2930
#include <photon/fs/virtual-file.h>
3031
#include <photon/common/uuid.h>
@@ -45,6 +46,8 @@ class IFileRO : public photon::fs::VirtualReadOnlyFile {
4546

4647
// return uuid of m_files[layer_idx];
4748
virtual int get_uuid(UUID &out, size_t layer_idx = 0) const = 0;
49+
50+
virtual std::vector<IFile *> get_lower_files() const = 0;
4851
};
4952

5053
struct CommitArgs {
@@ -104,23 +107,25 @@ struct LayerInfo {
104107
UUID uuid;
105108
char *user_tag = nullptr; // a user provided string of message, 256B at most
106109
bool sparse_rw = false;
107-
size_t len = 0; // len of user_tag; if it's 0, it will be detected with strlen()
108-
LayerInfo(photon::fs::IFile *_fdata = nullptr, photon::fs::IFile *_findex = nullptr) : fdata(_fdata), findex(_findex) {
110+
size_t len = 0; // len of user_tag; if it's 0, it will be detected with strlen()
111+
LayerInfo(photon::fs::IFile *_fdata = nullptr, photon::fs::IFile *_findex = nullptr)
112+
: fdata(_fdata), findex(_findex) {
109113
parent_uuid.clear();
110114
uuid.generate();
111115
}
112116
};
113117

114118
struct WarpFileArgs {
115119
photon::fs::IFile *findex = nullptr;
116-
photon::fs::IFile *fsmeta = nullptr; // sparse_file
117-
photon::fs::IFile *target_file = nullptr; // eg. remote target, local data file
120+
photon::fs::IFile *fsmeta = nullptr; // sparse_file
121+
photon::fs::IFile *target_file = nullptr; // eg. remote target, local data file
118122
uint64_t virtual_size;
119123
UUID::String parent_uuid;
120124
UUID uuid;
121125
char *user_tag = nullptr; // a user provided string of message, 256B at most
122126
size_t len = 0; // len of user_tag; if it's 0, it will be detected with strlen()
123-
WarpFileArgs(photon::fs::IFile *findex, photon::fs::IFile *fsmeta, photon::fs::IFile *target_file)
127+
WarpFileArgs(photon::fs::IFile *findex, photon::fs::IFile *fsmeta,
128+
photon::fs::IFile *target_file)
124129
: findex(findex), fsmeta(fsmeta), target_file(target_file) {
125130
uuid.generate();
126131
}
@@ -131,7 +136,8 @@ extern "C" IFileRW *create_file_rw(const LayerInfo &args, bool ownership = false
131136
// open a writable LSMT file constitued by a data file and a index file,
132137
// optionally obtaining the ownerships of the underlying files,
133138
// thus they will be destructed automatically.
134-
extern "C" IFileRW *open_file_rw(photon::fs::IFile *fdata, photon::fs::IFile *findex, bool ownership = false);
139+
extern "C" IFileRW *open_file_rw(photon::fs::IFile *fdata, photon::fs::IFile *findex,
140+
bool ownership = false);
135141

136142
// open a read-only LSMT file, which was created by
137143
// `close_seal()`ing or `commit()`ing a R/W LSMT file.
@@ -148,9 +154,10 @@ extern "C" IFileRO *open_files_ro(photon::fs::IFile **files, size_t n, bool owne
148154
extern "C" IFileRW *create_warpfile(WarpFileArgs &args, bool ownership = false);
149155

150156
extern "C" IFileRW *open_warpfile_rw(photon::fs::IFile *findex, photon::fs::IFile *fsmeta_file,
151-
photon::fs::IFile *target_file, bool ownership = false);
157+
photon::fs::IFile *target_file, bool ownership = false);
152158

153-
extern "C" IFileRO *open_warpfile_ro(photon::fs::IFile *warpfile, photon::fs::IFile *target_file, bool ownership = false);
159+
extern "C" IFileRO *open_warpfile_ro(photon::fs::IFile *warpfile, photon::fs::IFile *target_file,
160+
bool ownership = false);
154161

155162
// merge multiple RO files (layers) into a single RO file (layer)
156163
// returning 0 for success, -1 otherwise
@@ -164,4 +171,8 @@ extern "C" int merge_files_ro(photon::fs::IFile **src_files, size_t n, const Com
164171
extern "C" IFileRW *stack_files(IFileRW *upper_layer, IFileRO *lower_layers, bool ownership = false,
165172
bool check_order = true);
166173

174+
IMemoryIndex *open_file_index(photon::fs::IFile *file);
175+
IFileRO *open_files_with_merged_index(photon::fs::IFile **src_files, size_t n, IMemoryIndex *index,
176+
bool ownership = false);
177+
int is_lsmt(photon::fs::IFile *file);
167178
} // namespace LSMT

src/overlaybd/lsmt/index.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class Index : public IMemoryIndex {
6161
const SegmentMapping *pbegin = nullptr;
6262
const SegmentMapping *pend = nullptr;
6363
uint64_t alloc_blk = 0;
64+
uint64_t virtual_size = 0;
6465

6566
inline void get_alloc_blks() {
6667
for (auto m : mapping) {
@@ -72,16 +73,18 @@ class Index : public IMemoryIndex {
7273
delete[] pbegin;
7374
}
7475
}
75-
Index(const SegmentMapping *pmappings = nullptr, size_t n = 0, bool ownership = true)
76-
: ownership(ownership) {
76+
Index(const SegmentMapping *pmappings = nullptr, size_t n = 0, bool ownership = true,
77+
uint64_t vsize = 0)
78+
: ownership(ownership), virtual_size(vsize) {
7779
if (n == 0 || pmappings == nullptr) {
7880
pbegin = pend = nullptr;
7981
return;
8082
}
8183
pbegin = pmappings;
8284
pend = pbegin + n;
8385
}
84-
Index(vector<SegmentMapping> &&m) : mapping(std::move(m)) {
86+
Index(vector<SegmentMapping> &&m, uint64_t vsize = 0)
87+
: mapping(std::move(m)), virtual_size(vsize) {
8588
if (mapping.size()) {
8689
pbegin = &mapping[0];
8790
pend = pbegin + mapping.size();
@@ -146,6 +149,10 @@ class Index : public IMemoryIndex {
146149
m.tag += delta;
147150
return 0;
148151
}
152+
153+
uint64_t vsize() const override {
154+
return virtual_size;
155+
}
149156
};
150157

151158
class LevelIndex : public Index {
@@ -385,6 +392,7 @@ class Index0 : public IComboIndex {
385392
virtual const IMemoryIndex0 *front_index() const override {
386393
return this;
387394
}
395+
UNIMPLEMENTED(size_t vsize() const override);
388396
};
389397

390398
static void merge_indexes(uint8_t level, vector<SegmentMapping> &mapping, const Index **pindexes,
@@ -540,10 +548,10 @@ IMemoryIndex0 *create_memory_index0(const SegmentMapping *pmappings, size_t n,
540548
}
541549

542550
IMemoryIndex *create_memory_index(const SegmentMapping *pmappings, size_t n, uint64_t moffset_begin,
543-
uint64_t moffset_end, bool ownership) {
551+
uint64_t moffset_end, bool ownership, uint64_t vsize) {
544552
auto ok1 = verify_mapping_order(pmappings, n);
545553
auto ok2 = verify_mapping_moffset(pmappings, n, moffset_begin, moffset_end);
546-
return (ok1 && ok2) ? new Index(pmappings, n, ownership) : nullptr;
554+
return (ok1 && ok2) ? new Index(pmappings, n, ownership, vsize) : nullptr;
547555
}
548556

549557
IMemoryIndex *create_level_index(const SegmentMapping *pmappings, size_t n, uint64_t moffset_begin,
@@ -605,7 +613,8 @@ static void merge_indexes(uint8_t level, vector<SegmentMapping> &mapping, const
605613
}
606614
}
607615

608-
IComboIndex *create_combo_index(IMemoryIndex0 *index0, const IMemoryIndex *index, uint8_t ro_index_count, bool ownership) {
616+
IComboIndex *create_combo_index(IMemoryIndex0 *index0, const IMemoryIndex *index,
617+
uint8_t ro_index_count, bool ownership) {
609618
if (!index0 || !index)
610619
LOG_ERROR_RETURN(EINVAL, nullptr, "invalid argument(s)");
611620

@@ -666,6 +675,6 @@ IMemoryIndex *merge_memory_indexes(const IMemoryIndex **pindexes, size_t n) {
666675
auto pi = (const Index **)pindexes;
667676
mapping.reserve(pi[0]->size());
668677
merge_indexes(0, mapping, pi, n, 0, UINT64_MAX);
669-
return new Index(std::move(mapping));
678+
return new Index(std::move(mapping), pindexes[0]->vsize());
670679
}
671680
} // namespace LSMT

src/overlaybd/lsmt/index.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ class IMemoryIndex {
126126

127127
// number of 512B blocks allocated
128128
virtual uint64_t block_count() const = 0;
129+
130+
virtual uint64_t vsize() const = 0;
129131
};
130132

131133
// the level 0 memory index, which supports write
@@ -169,7 +171,7 @@ inline IMemoryIndex0 *create_memory_index0() {
169171
// the mapped offset must be within [moffset_begin, moffset_end)
170172
extern "C" IMemoryIndex *create_memory_index(const SegmentMapping *pmappings, std::size_t n,
171173
uint64_t moffset_begin, uint64_t moffset_end,
172-
bool ownership = true);
174+
bool ownership = true, uint64_t vsize = 0);
173175

174176
// merge multiple indexes into a single one index
175177
// the `tag` field of each element in the result is subscript of `pindexes`:

src/overlaybd/zfile/zfile.cpp

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,7 @@ const static uint8_t FLAG_VALID_FALSE = 0;
5151
const static uint8_t FLAG_VALID_TRUE = 1;
5252
const static uint8_t FLAG_VALID_CRC_CHECK = 2;
5353

54-
template <typename T>
55-
static std::unique_ptr<T[]> new_align_mem(size_t _size, size_t alignment = ALIGNMENT_4K) {
56-
size_t size = (_size + alignment - 1) / alignment * alignment;
57-
return std::unique_ptr<T[]>(new T[size]);
58-
}
59-
60-
inline uint32_t crc32c(void *buf, size_t size) {
54+
inline uint32_t crc32c_salt(void *buf, size_t size) {
6155
return crc32::crc32c_extend(buf, size, NOI_WELL_KNOWN_PRIME);
6256
}
6357
/* ZFile Format:
@@ -489,7 +483,7 @@ class CompressionFile : public VirtualReadOnlyFile {
489483
int retry = 3;
490484
again:
491485
if (m_ht.opt.verify) {
492-
auto c = crc32c((void *)block.buffer(), block.compressed_size);
486+
auto c = crc32c_salt((void *)block.buffer(), block.compressed_size);
493487
if (c != block.crc32_code()) {
494488
if ((valid == FLAG_VALID_TRUE) && (retry--)) {
495489
int reload_res = block.reload();
@@ -563,7 +557,7 @@ ssize_t compress_data(ICompressor *compressor, const unsigned char *buf, size_t
563557
// LOG_DEBUG("compress buffer {offset: `, count: `} into ` bytes.", i, step, ret);
564558
compressed_len = ret;
565559
if (gen_crc) {
566-
auto crc32_code = crc32c(dest_buf, compressed_len);
560+
auto crc32_code = crc32c_salt(dest_buf, compressed_len);
567561
*((uint32_t *)&dest_buf[compressed_len]) = crc32_code;
568562
LOG_DEBUG("append ` bytes crc32_code: `", sizeof(uint32_t), crc32_code);
569563
compressed_len += sizeof(uint32_t);
@@ -1157,7 +1151,7 @@ int zfile_compress(IFile *file, IFile *as, const CompressArgs *args) {
11571151
LOG_ERRNO_RETURN(0, -1, "failed to write compressed data.");
11581152
}
11591153
if (crc32_verify) {
1160-
auto crc32_code = crc32c(&compressed_data[j * buf_size], compressed_len[j]);
1154+
auto crc32_code = crc32c_salt(&compressed_data[j * buf_size], compressed_len[j]);
11611155
LOG_DEBUG("append ` bytes crc32_code: {offset: `, count: `, crc32: `}",
11621156
sizeof(uint32_t), moffset, compressed_len[j], HEX(crc32_code).width(8));
11631157
compressed_len[j] += sizeof(uint32_t);
@@ -1212,7 +1206,7 @@ int zfile_decompress(IFile *src, IFile *dst) {
12121206
for (off_t offset = 0; offset < raw_data_size; offset += block_size) {
12131207
auto len = (ssize_t)std::min(block_size, (size_t)raw_data_size - offset);
12141208
auto readn = file->pread(raw_buf.get(), len, offset);
1215-
LOG_DEBUG("readn: `, crc32: `", readn, HEX(crc32c(raw_buf.get(), len)).width(8));
1209+
LOG_DEBUG("readn: `, crc32: `", readn, HEX(crc32c_salt(raw_buf.get(), len)).width(8));
12161210
if (readn != len)
12171211
return -1;
12181212
if (dst->write(raw_buf.get(), readn) != readn) {

0 commit comments

Comments
 (0)