Skip to content
Open
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
2 changes: 1 addition & 1 deletion conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class HomestoreConan(ConanFile):
name = "homestore"
version = "8.2.0"
version = "8.2.1"

homepage = "https://github.com/eBay/Homestore"
description = "HomeStore Storage Engine"
Expand Down
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,5 @@ add_library(homestore STATIC
${HOMESTORE_OBJECTS}
)
target_link_libraries(homestore ${COMMON_DEPS})
target_compile_definitions(homestore PRIVATE _PRERELEASE)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why we need this _PRERELEASE here? I think target_compile_definitions(test_index_chunk_selector PRIVATE _PRERELEASE) in tests/CmakeLists.txt is enough for the new test case

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Because otherwise the code won't compile.

@JacksonYao287 JacksonYao287 Sep 14, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

adding _PRERELEASE unconditionally to the homestore library itself means every build (including production Release builds) will now permanently carry _PRERELEASE: extra fault-injection checkpoints, extra assert branches, and extra debug fields get baked into the production library. That's a much bigger behavioral change than "just make the new test compile." pls correct me if I misunderstand something.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You are right. I added _PRERELEASE just to make this compile and run. Please suggest a better place/way to enable _PRERELEASE as I didn't really find how it is enabled in 7.x. I presume it is not the same as Debug build.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@szmyd since we disable prerelease in eBay/sisl#278, do you have any sugestion on this ?


8 changes: 6 additions & 2 deletions src/include/homestore/index/wb_cache_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@
namespace homestore {

class BtreeNode;
class Chunk;
struct CPContext;

using BtreeNodePtr = boost::intrusive_ptr< BtreeNode >;
using BtreeNodeList = boost::container::small_vector< BtreeNodePtr, 3 >;
using node_initializer_t = std::function< BtreeNodePtr(const IndexBufferPtr&) >;

struct CPContext;

class IndexWBCacheBase {
public:
virtual ~IndexWBCacheBase() = default;
Expand Down Expand Up @@ -67,6 +68,9 @@ class IndexWBCacheBase {
/// @return
// virtual IndexBufferPtr copy_buffer(const IndexBufferPtr& cur_buf, const CPContext* context) const = 0;
virtual void recover(sisl::byte_view sb) = 0;

/// Remove entries for a specific chunk from wbc
virtual void evict_chunk_blkids(const Chunk& chunk) = 0;
Comment thread
JacksonYao287 marked this conversation as resolved.
};

} // namespace homestore
13 changes: 13 additions & 0 deletions src/lib/device/chunk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,17 @@ void Chunk::reset_block_allocator() {
vdev_ptr->reset_chunk_blk_allocator(this);
}

void Chunk::foreach_allocated_blk(std::function< void(blk_id const&) >&& cb) const {
auto* ba = blk_allocator();
RELEASE_ASSERT(ba, "Blk allocator is null for chunk_id={}", chunk_id());

const auto total_blks = ba->get_total_blks();
const auto cid = chunk_id();

for (blk_num_t blk_num{}; blk_num < total_blks; ++blk_num) {
blk_id blkid{blk_num, 1, cid};
Comment thread
nnastonen marked this conversation as resolved.
if (ba->is_blk_alloced(blkid, false)) { cb(blkid); }
}
}

} // namespace homestore
5 changes: 5 additions & 0 deletions src/lib/device/chunk.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@
#include "device/physical_dev.hpp"

namespace homestore {

class BlkAllocator;
class CP;
struct blk_id;

class Chunk {
private:
std::shared_mutex m_mgmt_mutex;
Expand Down Expand Up @@ -74,6 +77,8 @@ class Chunk {
float get_blk_usage_report_threshold() const { return blk_usage_report_threshold; }
float get_blk_usage() const;

void foreach_allocated_blk(std::function< void(blk_id const&) >&& cb) const;

////////////// Setters /////////////////////
void set_user_private(const sisl::blob& data);
void set_block_allocator(cshared< BlkAllocator >& blkalloc) {
Expand Down
16 changes: 14 additions & 2 deletions src/lib/index/wb_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,13 @@ IndexWBCache::IndexWBCache(const std::shared_ptr< VirtualDev >& vdev, std::pair<
return static_cast< IndexBtreeNode* >(node.get())->m_idx_buf->m_blkid;
},
[](const sisl::CacheRecord& rec) -> bool {
const auto& hnode = (sisl::SingleEntryHashNode< BtreeNodePtr >&)rec;
return static_cast< IndexBtreeNode* >(hnode.m_value.get())->m_idx_buf->is_clean();
const auto& hnode = static_cast< const sisl::SingleEntryHashNode< BtreeNodePtr >& >(rec);
const auto* idx_node = static_cast< const IndexBtreeNode* >(hnode.m_value.get());
HS_REL_ASSERT(idx_node && idx_node->m_idx_buf,
"Cache evictor: invalid cache entry: idx_node={} m_idx_buf={}",
static_cast< const void* >(idx_node),
idx_node ? static_cast< const void* >(idx_node->m_idx_buf.get()) : nullptr);
return idx_node->m_idx_buf->is_clean();
}},
m_node_size{node_size},
m_meta_blk{sb.first} {
Expand Down Expand Up @@ -1214,6 +1219,13 @@ void IndexWBCache::get_next_bufs_internal(IndexCPContext* cp_ctx, uint32_t max_c
}
}

void IndexWBCache::evict_chunk_blkids(const Chunk& chunk) {
chunk.foreach_allocated_blk([this](blk_id const& blkid) {
BtreeNodePtr node;
(void)m_cache.remove(blkid, node);
});
Comment thread
nnastonen marked this conversation as resolved.
}

/*
IndexBtreeNode* IndexBtreeNode::convert(BtreeNode* bt_node) {
return r_cast< IndexBtreeNode* >(bt_node->get_node_context());
Expand Down
1 change: 1 addition & 0 deletions src/lib/index/wb_cache.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class IndexWBCache : public IndexWBCacheBase {
CPContext* cp_ctx) override;
void free_buf(const IndexBufferPtr& buf, CPContext* cp_ctx) override;
bool refresh_meta_buf(shared< MetaIndexBuffer >& meta_buf, CPContext* cp_ctx) override;
void evict_chunk_blkids(const Chunk& chunk) override;

//////////////////// CP Related API section /////////////////////////////////
sisl::async::task< bool > async_cp_flush(IndexCPContext* context);
Expand Down
9 changes: 9 additions & 0 deletions src/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ if (${io_tests})
add_test(NAME IndexCrashRecovery COMMAND test_index_crash_recovery)
set_property(TEST IndexCrashRecovery PROPERTY ENVIRONMENT "ASAN_OPTIONS=detect_stack_use_after_return=true")

set(TEST_RECOVERY_INDEX_SOURCE_FILES test_index_chunk_selector.cpp)
add_executable(test_index_chunk_selector ${TEST_RECOVERY_INDEX_SOURCE_FILES})
target_link_libraries(test_index_chunk_selector homestore ${COMMON_TEST_DEPS} GTest::gtest)
add_test(NAME IndexChunkSelector COMMAND test_index_chunk_selector)
set_property(TEST IndexChunkSelector PROPERTY ENVIRONMENT "ASAN_OPTIONS=detect_stack_use_after_return=true")

add_executable(test_data_service)
target_sources(test_data_service PRIVATE test_data_service.cpp)
target_link_libraries(test_data_service homestore ${COMMON_TEST_DEPS} GTest::gmock)
Expand Down Expand Up @@ -167,3 +173,6 @@ if (${non_coverage_build})
target_sources(index_btree_benchmark PRIVATE index_btree_benchmark.cpp)
target_link_libraries(index_btree_benchmark homestore ${COMMON_TEST_DEPS} benchmark::benchmark)
endif()

target_compile_definitions(test_index_chunk_selector PRIVATE _PRERELEASE)

2 changes: 1 addition & 1 deletion src/tests/btree_helpers/btree_test_helper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ struct BtreeTestHelper {
flip::FlipFrequency freq;
freq.set_count(10000);
freq.set_percent(100);
m_fc.inject_noreturn_flip(flip_name, {null_cond}, freq);
m_fc.inject_noreturn_flip(flip_name, std::array< flip::FlipCondition, 1 >{null_cond}, freq);
m_bt->set_flip_point(flip_name);
LOGINFO("Flip {} set", flip_name);
}
Expand Down
7 changes: 4 additions & 3 deletions src/tests/test_common/homestore_test_common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,8 @@ class HSTestHelper {

flip::FlipCondition dont_care_cond;
fc->create_condition("", flip::Operator::DONT_CARE, (int)1, &dont_care_cond);
fc->inject_retval_flip< long >("set_minimum_chunk_size", {dont_care_cond}, freq, chunk_size);
fc->inject_retval_flip< long >("set_minimum_chunk_size", std::array< flip::FlipCondition, 1 >{dont_care_cond},
freq, chunk_size);
#endif
}

Expand All @@ -253,7 +254,7 @@ class HSTestHelper {
flip::FlipFrequency freq;
freq.set_count(count);
freq.set_percent(percent);
m_fc.inject_noreturn_flip(flip_name, {null_cond}, freq);
m_fc.inject_noreturn_flip(flip_name, std::array< flip::FlipCondition, 1 >{null_cond}, freq);
LOGDEBUG("Flip {} set", flip_name);
}

Expand All @@ -262,7 +263,7 @@ class HSTestHelper {
flip::FlipFrequency freq;
freq.set_count(count);
freq.set_percent(percent);
m_fc.inject_delay_flip(flip_name, {null_cond}, freq, delay_usec);
m_fc.inject_delay_flip(flip_name, std::array< flip::FlipCondition, 1 >{null_cond}, freq, delay_usec);
LOGDEBUG("Flip {} set", flip_name);
}

Expand Down
Loading
Loading