@@ -33,9 +33,10 @@ class Rmi
3333 using layer2_type = Layer2;
3434
3535 protected:
36- std::size_t n_keys_; // /< The number of keys the index was built on.
37- layer1_type l1_; // /< The layer1 model.
38- std::vector<layer2_type> l2_; // /< The vector of layer2 models.
36+ std::size_t n_keys_; // /< The number of keys the index was built on.
37+ std::size_t layer2_size_; // /< The number of models in layer2.
38+ layer1_type l1_; // /< The layer1 model.
39+ layer2_type *l2_; // /< The array of layer2 models.
3940
4041 public:
4142 /* *
@@ -59,12 +60,13 @@ class Rmi
5960 template <typename RandomIt>
6061 Rmi (RandomIt first, RandomIt last, const std::size_t layer2_size)
6162 : n_keys_(std::distance(first, last))
63+ , layer2_size_(layer2_size)
6264 {
6365 // Train layer1.
6466 l1_ = layer1_type (first, last, 0 , static_cast <double >(layer2_size) / n_keys_); // train with compression
6567
6668 // Train layer2.
67- l2_ = std::vector< layer2_type>( layer2_size) ;
69+ l2_ = new layer2_type[ layer2_size] ;
6870 std::size_t segment_start = 0 ;
6971 std::size_t segment_id = 0 ;
7072 // Assign each key to its segment.
@@ -73,28 +75,33 @@ class Rmi
7375 std::size_t pred_segment_id = get_segment_id (*pos);
7476 // If a key is assigned to a new segment, all models must be trained up to the new segment.
7577 if (pred_segment_id > segment_id) {
76- l2_[segment_id] = layer2_type (first + segment_start, pos, segment_start);
78+ new (& l2_[segment_id]) layer2_type (first + segment_start, pos, segment_start);
7779 for (std::size_t j = segment_id + 1 ; j < pred_segment_id; ++j) {
78- l2_[j] = layer2_type (pos - 1 , pos, i - 1 ); // train other models on last key in previous segment
80+ new (& l2_[j]) layer2_type (pos - 1 , pos, i - 1 ); // train other models on last key in previous segment
7981 }
8082 segment_id = pred_segment_id;
8183 segment_start = i;
8284 }
8385 }
8486 // Train remaining models.
85- l2_[segment_id] = layer2_type (first + segment_start, last, segment_start);
87+ new (& l2_[segment_id]) layer2_type (first + segment_start, last, segment_start);
8688 for (std::size_t j = segment_id + 1 ; j < layer2_size; ++j) {
87- l2_[j] = layer2_type (last - 1 , last, n_keys_ - 1 ); // train remaining models on last key
89+ new (& l2_[j]) layer2_type (last - 1 , last, n_keys_ - 1 ); // train remaining models on last key
8890 }
8991 }
9092
93+ /* *
94+ * Destructor.
95+ */
96+ ~Rmi () { delete[] l2_; }
97+
9198 /* *
9299 * Returns the id of the segment @p key belongs to.
93100 * @param key to get segment id for
94101 * @return segment id of the given key
95102 */
96103 std::size_t get_segment_id (const key_type key) const {
97- return std::clamp<double >(l1_.predict (key), 0 , l2_. size () - 1 );
104+ return std::clamp<double >(l1_.predict (key), 0 , layer2_size_ - 1 );
98105 }
99106
100107 /* *
@@ -114,12 +121,18 @@ class Rmi
114121 */
115122 std::size_t n_keys () const { return n_keys_; }
116123
124+ /* *
125+ * Returns the number of models in layer2.
126+ * @return the number of models in layer2
127+ */
128+ std::size_t layer2_size () const { return layer2_size_; }
129+
117130 /* *
118131 * Returns the size of the index in bytes.
119132 * @return index size in bytes
120133 */
121134 std::size_t size_in_bytes () {
122- return l1_.size_in_bytes () + l2_. size () * l2_[0 ].size_in_bytes () + sizeof (n_keys_);
135+ return l1_.size_in_bytes () + layer2_size_ * l2_[0 ].size_in_bytes () + sizeof (n_keys_) + sizeof (layer2_size_ );
123136 }
124137};
125138
0 commit comments