FBlockedLinearTree.hpp 4.41 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
#ifndef _FBLOCKED_LINEAR_TREE_HPP_
#define _FBLOCKED_LINEAR_TREE_HPP_

#include <vector>
#include "../../Utils/FLog.hpp"
#include "FDistributedGroupTreeBuilder.hpp"

template<class node_t>
class FBlockedLinearTree {

protected:

    const int block_size;
    int nb_leaf;
    int nb_block;

    std::vector<node_t>* linear_tree;

public:

////////////////////////////////////////////////
// constructor
////////////////////////////////////////////////

    /**
     * FBlockedLinearTree This constructer create a blocked linear tree
     * from a linear tree. This linear tree will be balanced BEFORE calling
     * this constructer
     * @author benjamin.dufoyer@inria.fr
     * @param  in_linear_tree current linear_tree
     * @param  in_block_size  block_size needed
     */
    FBlockedLinearTree(const int in_block_size ,std::vector<node_t>* in_linear_tree):
        block_size(in_block_size),
        nb_leaf((int)in_linear_tree->size())
    {
        if(nb_leaf%block_size == 0)
            this->nb_block = nb_leaf/block_size;
        else
            this->nb_block = nb_leaf/block_size+1;

    std::swap(in_linear_tree,linear_tree);
    }

////////////////////////////////////////////////
// destructor
////////////////////////////////////////////////

    ~FBlockedLinearTree(){
        delete linear_tree;
    }

////////////////////////////////////////////////
// Function
////////////////////////////////////////////////

    /**
     * redistribute_block redistribute leaf of the linear_tree with the good
     * block size. For N proc, N-1 proc have the same number of leaf,
     * the rest is for the proc N
     * @author benjamin.dufoyer@inria.fr
     * @param  conf mpi configuration to work with the other process
     */
    void redistribute_block(const inria::mpi_config& conf){
        dstr_grp_tree_builder::parrallel_build_block(conf,
                                            this->linear_tree,
                                            this->block_size);
        //Update nb_leaf and nb_block
        this->nb_leaf = (int)this->linear_tree->size();
        if(nb_leaf%block_size == 0)
            this->nb_block = nb_leaf/block_size;
        else
            this->nb_block = nb_leaf/block_size+1;

    }

    int get_nb_leaf() const{
        return this->nb_leaf;
    }

    int get_nb_block() const{
        return this->nb_block;
    }

    int get_block_size() const{
        return this->block_size;
    }

    /**
     * get_block_size_at return the block size of the number of the block
     * placed in parametter,
     * [INFO] first block is 0
     * [INFO] last block is this->nb_block-1
     * @author benjamin.dufoyer@inria.fr
     * @param  num_block number of the block
     * @return size of the block
     */
    int get_block_size_at(int num_block) {
        int size;
        if(num_block < this->nb_block){
            if(num_block == this->nb_block-1){
                size = this->nb_leaf - ((this->nb_block-1)*this->block_size);
            } else {
                size = this->block_size;
            }
        } else {
            FLOG(FLog::Controller << "[ERROR][FBlockedLinearTree] Trying to access to undefined block, returning block_size  " << "\n");
            size = this->block_size;
        }
        return size;
    }

    /**
     * get_leaf_at return the leaf at the position placed in parameter
     * @author benjamin.dufoyer@inria.fr
     * @param  position position of the leaf
     * @return the leaf
     */
    node_t get_leaf_at(int position){
        node_t leaf;
        if(position < this->nb_leaf && position >= 0) {
            leaf = this->linear_tree->at(position);
        } else {
            FLOG(FLog::Controller << "[ERROR][FBlockedLinearTree] Trying to access to undefined leaf " << "\n");
            leaf = this->linear_tree->first();
        }
        return leaf;
    }

    int get_leaf_level(){
        return this->linear_tree->front().level;
    }

    int get_first_morton_index(){
        return this->linear_tree->front().morton_index;
    }

    int get_last_morton_index(){
        return linear_tree->back().morton_index;
    }

    void print_info_tree(){
        std::cout << " nb_leaf : " << nb_leaf << std::endl;
        std::cout << " nb_block : " << nb_block << std::endl;
        std::cout << " block_size : " << block_size << std::endl;
        for(int i = 0 ; i < nb_leaf ; i++){
            std::cout << linear_tree->at(i) << std::endl;
        }
    }

};

#endif //_FBLOCKED_LINEAR_TREE_HPP_