Commit b8cd2f35 authored by jan.koester's avatar jan.koester
Browse files

test

parent 61e6de91
Loading
Loading
Loading
Loading
+18 −33
Original line number Diff line number Diff line
@@ -1328,48 +1328,36 @@ client::rebalance_result client::rebalance() {
    rebalance_result result;
    size_t n = k_ + m_;

    // Step 1: Collect all unique group IDs across all nodes (unlocked for listing)
    std::set<uint64_t> all_groups;
    // Step 1: Collect group presence per node (N round trips total, not N×G)
    std::map<uint64_t, std::set<size_t>> group_nodes; // gid → set of node indices
    for (size_t i = 0; i < nodes_.size(); ++i) {
        std::vector<uint64_t> node_groups;
        if (list_groups_on_node(i, node_groups)) {
            all_groups.insert(node_groups.begin(), node_groups.end());
            for (uint64_t gid : node_groups)
                group_nodes[gid].insert(i);
        }
    }

    if (all_groups.empty())
    if (group_nodes.empty())
        return result;

    std::cerr << "[PARITY] rebalance: " << all_groups.size() << " group(s) to check" << std::endl;
    std::cerr << "[PARITY] rebalance: " << group_nodes.size() << " group(s) to check" << std::endl;

    // Step 2: For each group, check block placement and re-store if misplaced
    for (uint64_t gid : all_groups) {
        // List blocks on each node for this group
        auto node_blocks = list(gid);  // acquires mutex internally

        // Check if blocks are correctly placed: block_index % n == node_index
        bool misplaced = false;
        size_t total_blocks = 0;
        for (const auto& [node_idx, blocks] : node_blocks) {
            for (uint32_t bidx : blocks) {
                ++total_blocks;
                size_t expected_node = bidx % n;
                if (expected_node != node_idx) {
                    misplaced = true;
                }
            }
        }

        // Also check: each node should have at most one block per stripe
        // and total blocks should be a multiple of n
        if (!misplaced && total_blocks > 0 && total_blocks % n == 0) {
    // Step 2: Groups present on all n nodes are likely OK — only do the
    // expensive per-block placement check for groups that aren't on all nodes.
    // This skips the costly list(gid) call for the majority of groups.
    std::vector<uint64_t> candidates;
    for (auto& [gid, nodes_set] : group_nodes) {
        if (nodes_set.size() >= n) {
            ++result.already_ok;
            continue;
        } else {
            candidates.push_back(gid);
        }
    }

        // Group needs rebalancing: retrieve → delete → re-store
    // Step 3: Fix misplaced / under-replicated groups
    for (uint64_t gid : candidates) {
        try {
            // Retrieve full data (parity decode handles misplaced blocks)
            auto data = retrieve(gid);
            if (data.empty()) {
                std::cerr << "[PARITY] rebalance: gid=" << gid
@@ -1378,10 +1366,7 @@ client::rebalance_result client::rebalance() {
                continue;
            }

            // Delete old (misplaced) blocks
            remove(gid);

            // Re-store with correct placement
            store(gid, data);

            ++result.rebalanced;
@@ -1394,7 +1379,7 @@ client::rebalance_result client::rebalance() {
        }
    }

    // Step 3: Vacuum all nodes to reclaim space from deleted blocks
    // Step 4: Vacuum all nodes to reclaim space from deleted blocks
    if (result.rebalanced > 0)
        vacuum_all_nodes();