diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0ed7359 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +cmake-build-debug +.idea +.DS_Store +build \ No newline at end of file diff --git a/utils/io/Compactor.cpp b/utils/io/Compactor.cpp index b131de0..9c5b86d 100644 --- a/utils/io/Compactor.cpp +++ b/utils/io/Compactor.cpp @@ -27,7 +27,7 @@ namespace usub::utils std::string merged_filename = "L1_" + std::to_string(std::time(nullptr)) + ".dat"; - LFSkipList merged(this->version_manager); + LFSkipList merged(this->version_manager); for (const auto& file : this->level0_files) { read_sstable_with_mmap(merged, file); @@ -49,7 +49,7 @@ namespace usub::utils std::string merged_filename = "L2_" + std::to_string(std::time(nullptr)) + ".dat"; - LFSkipList merged(this->version_manager); + LFSkipList merged(this->version_manager); for (const auto& file : this->level1_files) { read_sstable_with_mmap(merged, file); diff --git a/utils/io/Compactor.h b/utils/io/Compactor.h index a0aef73..cf82ef5 100644 --- a/utils/io/Compactor.h +++ b/utils/io/Compactor.h @@ -10,6 +10,7 @@ #include #include "utils/datastructures/LFSkipList.h" #include "utils/io/SSTableIO.h" +#include "utils/hash/Hash128.h" namespace usub::utils { diff --git a/utils/io/SSTableIO.h b/utils/io/SSTableIO.h index 0a272eb..f3aae5c 100644 --- a/utils/io/SSTableIO.h +++ b/utils/io/SSTableIO.h @@ -15,6 +15,7 @@ #include #include +#include "utils/hash/Hash128.h" namespace usub::utils { @@ -113,57 +114,40 @@ namespace usub::utils template void write_sstable_with_index(const SkipList& memtable, const std::string& filename) { - int fd = ::open(filename.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0644); - if (fd < 0) + std::ofstream out(filename, std::ios::binary | std::ios::trunc); + if (!out.is_open()) { - throw std::runtime_error("Failed to open file: " + filename); + throw std::runtime_error("Failed to open SSTable file"); } - FILE* file = ::fdopen(fd, "wb"); - if (!file) - { - ::close(fd); - throw std::runtime_error("Failed to fdopen file: " + filename); - } - - std::vector> index_entries; + std::vector> index_entries; uint64_t current_offset = 0; memtable.for_each_raw([&](const auto& key, const auto& value, bool is_tombstone, uint64_t version) { - uint32_t key_len = key.size(); - uint32_t value_len = value.size(); - uint8_t tombstone_flag = is_tombstone ? 1 : 0; + out.write(reinterpret_cast(&key), sizeof(key)); - ::fwrite(&key_len, sizeof(key_len), 1, file); - ::fwrite(key.data(), key_len, 1, file); - ::fwrite(&value_len, sizeof(value_len), 1, file); - ::fwrite(value.data(), value_len, 1, file); - ::fwrite(&tombstone_flag, sizeof(tombstone_flag), 1, file); - ::fwrite(&version, sizeof(version), 1, file); + uint32_t value_len = value.size(); + out.write(reinterpret_cast(&value_len), sizeof(value_len)); + out.write(value.data(), value_len); + + uint8_t tombstone_flag = is_tombstone ? 1 : 0; + out.write(reinterpret_cast(&tombstone_flag), sizeof(tombstone_flag)); + out.write(reinterpret_cast(&version), sizeof(version)); index_entries.emplace_back(key, current_offset); - - current_offset += sizeof(key_len) + key_len + sizeof(value_len) + value_len + sizeof(tombstone_flag) + - sizeof(version); + current_offset += sizeof(key) + sizeof(value_len) + value_len + sizeof(tombstone_flag) + sizeof(version); }); - uint64_t index_start_offset = current_offset; + uint64_t index_offset = current_offset; - // Записываем индекс for (const auto& [key, offset] : index_entries) { - uint32_t key_len = key.size(); - ::fwrite(&key_len, sizeof(key_len), 1, file); - ::fwrite(key.data(), key_len, 1, file); - ::fwrite(&offset, sizeof(offset), 1, file); + out.write(reinterpret_cast(&key), sizeof(key)); + out.write(reinterpret_cast(&offset), sizeof(offset)); } - ::fwrite(&index_start_offset, sizeof(index_start_offset), 1, file); - - ::fflush(file); - ::fsync(fd); - ::fclose(file); + out.write(reinterpret_cast(&index_offset), sizeof(index_offset)); } template @@ -342,18 +326,16 @@ namespace usub::utils uint64_t index_offset = *reinterpret_cast(end - sizeof(uint64_t)); const char* index_ptr = ptr + index_offset; - std::vector> index_entries; + std::vector> index_entries; while (index_ptr < end - sizeof(uint64_t)) { - uint32_t key_len = *reinterpret_cast(index_ptr); - index_ptr += sizeof(uint32_t); + usub::utils::Hash128 key; + std::memcpy(&key, index_ptr, sizeof(key)); + index_ptr += sizeof(key); - std::string key(key_len, '\0'); - std::memcpy(key.data(), index_ptr, key_len); - index_ptr += key_len; - - uint64_t offset = *reinterpret_cast(index_ptr); - index_ptr += sizeof(uint64_t); + uint64_t offset; + std::memcpy(&offset, index_ptr, sizeof(offset)); + index_ptr += sizeof(offset); index_entries.emplace_back(key, offset); } @@ -362,12 +344,9 @@ namespace usub::utils { const char* record = ptr + offset; - uint32_t key_len = *reinterpret_cast(record); - record += sizeof(uint32_t); - - std::string file_key(key_len, '\0'); - std::memcpy(file_key.data(), record, key_len); - record += key_len; + usub::utils::Hash128 file_key; + std::memcpy(&file_key, record, sizeof(file_key)); + record += sizeof(file_key); uint32_t value_len = *reinterpret_cast(record); record += sizeof(uint32_t); @@ -385,10 +364,11 @@ namespace usub::utils memtable.insert_raw(file_key, value, tombstone_flag == 1, version); } - munmap(data, st.st_size); + munmap((void*)ptr, st.st_size); ::close(fd); } + template void optimized_range_query_sstable(const std::string& filename, const typename SkipList::key_type& from_key, diff --git a/utils/io/Wal.cpp b/utils/io/Wal.cpp index ec6fc13..a509fa8 100644 --- a/utils/io/Wal.cpp +++ b/utils/io/Wal.cpp @@ -12,26 +12,22 @@ namespace usub::utils if (!this->out.is_open()) throw std::runtime_error("Failed to open WAL"); } - void WAL::write_put(const std::string& key, const std::string& value) + void WAL::write_put(const Hash128& key, const std::string& value) { uint8_t op = 0; - uint32_t key_len = key.size(); uint32_t value_len = value.size(); - this->out.write(reinterpret_cast(&op), sizeof(op)); - this->out.write(reinterpret_cast(&key_len), sizeof(key_len)); - this->out.write(key.data(), key_len); - this->out.write(reinterpret_cast(&value_len), sizeof(value_len)); + this->out.write(reinterpret_cast(&op), sizeof(op)); + this->out.write(reinterpret_cast(&key), sizeof(key)); + this->out.write(reinterpret_cast(&value_len), sizeof(value_len)); this->out.write(value.data(), value_len); this->out.flush(); } - void WAL::write_delete(const std::string& key) + void WAL::write_delete(const Hash128& key) { uint8_t op = 1; - uint32_t key_len = key.size(); - this->out.write(reinterpret_cast(&op), sizeof(op)); - this->out.write(reinterpret_cast(&key_len), sizeof(key_len)); - this->out.write(key.data(), key_len); + this->out.write(reinterpret_cast(&op), sizeof(op)); + this->out.write(reinterpret_cast(&key), sizeof(key)); this->out.flush(); } diff --git a/utils/io/Wal.h b/utils/io/Wal.h index 59cc5a0..6e10f35 100644 --- a/utils/io/Wal.h +++ b/utils/io/Wal.h @@ -7,6 +7,8 @@ #include +#include "utils/hash/Hash128.h" + namespace usub::utils { class WAL @@ -16,9 +18,9 @@ namespace usub::utils public: explicit WAL(const std::string& filename); - void write_put(const std::string& key, const std::string& value); + void write_put(const Hash128& key, const std::string& value); - void write_delete(const std::string& key); + void write_delete(const Hash128& key); void close(); };