Skip to content

Commit 45ac222

Browse files
authored
Merge pull request #113 from SGSSGene/fix/search_ng26/besthit
Fix/search ng26/besthit
2 parents aa98c8f + 46ac50e commit 45ac222

File tree

14 files changed

+1906
-79
lines changed

14 files changed

+1906
-79
lines changed

cpm.dependencies

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@
134134
},
135135
{
136136
"name": "mmser",
137-
"version": "1.0.0",
137+
"version": "1.0.1",
138138
"github_repository": "SGSSGene/mmser",
139139
},
140140
]
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
// SPDX-FileCopyrightText: 2025 Simon Gene Gottlieb
2+
// SPDX-License-Identifier: BSD-3-Clause
3+
#pragma once
4+
5+
#include "DenseVector.h"
6+
7+
#include <array>
8+
#include <variant>
9+
10+
namespace fmc {
11+
12+
template <typename Ts>
13+
struct DenseMultiVector;
14+
15+
template <>
16+
struct DenseMultiVector<std::monostate> {
17+
DenseMultiVector() = default;
18+
19+
static auto concat(DenseMultiVector const& lhs, DenseMultiVector const& rhs) {
20+
(void)lhs;
21+
(void)rhs;
22+
return DenseMultiVector{};
23+
}
24+
25+
DenseMultiVector(DenseMultiVector const&) = default;
26+
DenseMultiVector(DenseMultiVector&&) noexcept = default;
27+
DenseMultiVector& operator=(DenseMultiVector const&) = default;
28+
DenseMultiVector& operator=(DenseMultiVector&&) noexcept = default;
29+
30+
void reserve(size_t) {}
31+
void push_back(std::monostate) {}
32+
auto operator[](size_t) const -> std::monostate { return {}; }
33+
auto access(size_t) const -> std::monostate { return {}; }
34+
size_t size() const { return 0; }
35+
36+
template <typename Archive>
37+
void serialize(this auto&& self, Archive& ar) {
38+
(void)self;
39+
(void)ar;
40+
}
41+
};
42+
43+
44+
/* Like DenseVector but stores multiple values per entry
45+
*/
46+
template <typename ...Ts>
47+
requires (std::convertible_to<Ts, size_t> && ...)
48+
&& (std::convertible_to<size_t, Ts> && ...)
49+
struct DenseMultiVector<std::tuple<Ts...>> {
50+
std::array<DenseVector, sizeof...(Ts)> data;
51+
52+
DenseMultiVector() = default;
53+
54+
static auto concat(DenseMultiVector const& lhs, DenseMultiVector const& rhs) {
55+
auto v = DenseMultiVector{};
56+
for (size_t i{0}; i < lhs.data.size(); ++i) {
57+
v.data[i] = DenseVector::concat(lhs.data[i], rhs.data[i]);
58+
}
59+
return v;
60+
}
61+
62+
63+
DenseMultiVector(DenseMultiVector const&) = default;
64+
DenseMultiVector(DenseMultiVector&&) noexcept = default;
65+
DenseMultiVector& operator=(DenseMultiVector const&) = default;
66+
DenseMultiVector& operator=(DenseMultiVector&&) noexcept = default;
67+
68+
template <std::ranges::range range_t>
69+
requires std::convertible_to<std::ranges::range_value_t<range_t>, std::tuple<Ts...>>
70+
DenseMultiVector(range_t const& _range) {
71+
auto largestValue = std::array<size_t, sizeof...(Ts)>{};
72+
auto commonDivisor = std::array<size_t, sizeof...(Ts)>{};
73+
size_t ct{};
74+
75+
// find largest value
76+
for (auto const& t : _range) {
77+
// using template magic to spread a single entry into multiple vectors
78+
map<sizeof...(Ts)>([&]<size_t I>() {
79+
auto const v = static_cast<size_t>(std::get<I>(t));
80+
largestValue[I] = std::max<size_t>(largestValue[I], v);
81+
commonDivisor[I] = std::gcd(commonDivisor[I], v);
82+
});
83+
ct += 1;
84+
}
85+
86+
// make sure commonDivisor and largestValue are at least 1
87+
map<sizeof...(Ts)>([&]<size_t I>() {
88+
if (commonDivisor[I] == 0) {
89+
commonDivisor[I] = 1;
90+
}
91+
if (largestValue[I] == 0) {
92+
largestValue[I] = 1;
93+
}
94+
});
95+
96+
// Initialize each vector accordinlgy
97+
map<sizeof...(Ts)>([&]<size_t I>() {
98+
data[I] = DenseVector(/*.largestValue = */ largestValue[I], /*.commonDivisor = */commonDivisor[I]);
99+
data[I].reserve(ct);
100+
});
101+
for (auto const& t : _range) {
102+
push_back(t);
103+
}
104+
}
105+
106+
107+
/** Reserve memory for a certain number of integers.
108+
*
109+
* \param s number of integer
110+
*/
111+
void reserve(size_t s) {
112+
for (size_t i{0}; i < data.size(); ++i) {
113+
data[i].reserve(s);
114+
}
115+
}
116+
117+
template <size_t End>
118+
static void map(auto const& cb) {
119+
if constexpr (End > 0) {
120+
cb.template operator()<End-1>();
121+
map<End-1>(cb);
122+
}
123+
}
124+
125+
/** Push a value to the end of the vector
126+
*/
127+
void push_back(std::tuple<Ts...> const& value) {
128+
map<sizeof...(Ts)>([&]<size_t I>() {
129+
data[I].push_back(std::get<I>(value));
130+
});
131+
}
132+
133+
/** Read integer at a certain position
134+
*/
135+
auto operator[](size_t i) const -> std::tuple<Ts...> {
136+
return access(i);
137+
}
138+
139+
/** Read integer at a certain position
140+
*/
141+
auto access(size_t i) const -> std::tuple<Ts...> {
142+
auto ret = std::tuple<Ts...>{};
143+
map<sizeof...(Ts)>([&]<size_t I>() {
144+
std::get<I>(ret) = data[I].access(i);
145+
});
146+
return ret;
147+
}
148+
149+
size_t size() const {
150+
return data[0].size();
151+
}
152+
153+
template <typename Archive>
154+
void serialize(this auto&& self, Archive& ar) {
155+
ar(self.data);
156+
}
157+
};
158+
159+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// SPDX-FileCopyrightText: 2025 Simon Gene Gottlieb
2+
// SPDX-License-Identifier: BSD-3-Clause
3+
#pragma once
4+
5+
#include <cstddef>
6+
#include <cstdint>
7+
#include <mmser/mmser.h>
8+
9+
namespace fmc {
10+
11+
struct VectorBool {
12+
struct Proxy {
13+
uint8_t& value;
14+
size_t offset;
15+
operator bool() const {
16+
return (value >> offset) & 1;
17+
}
18+
void operator=(bool b) {
19+
// value clears value at offset | sets value at offset
20+
value = (value & ~(uint8_t{1} << offset)) | (uint8_t{b} << offset);
21+
}
22+
};
23+
24+
mmser::vector<uint8_t> values;
25+
size_t used_capacity{};
26+
27+
28+
void reserve(size_t i) {
29+
values.reserve((i+7)/8);
30+
}
31+
void resize(size_t i) {
32+
values.resize((i+7)/8, 0);
33+
used_capacity = i;
34+
}
35+
36+
auto unused_capacity() const {
37+
return values.size()*8 - used_capacity;
38+
}
39+
void resize(size_t newSize, bool value) {
40+
values.resize((newSize+7)/8, 0);
41+
for (size_t i{used_capacity}; i < newSize; ++i) {
42+
at(i) = value;
43+
}
44+
used_capacity = newSize;
45+
}
46+
47+
void push_back(bool b) {
48+
if (unused_capacity() == 0) {
49+
values.emplace_back(0);
50+
}
51+
at(size()) = b;
52+
used_capacity += 1;
53+
}
54+
55+
auto size() const -> size_t {
56+
return used_capacity;
57+
}
58+
59+
auto at(size_t idx) -> Proxy {
60+
size_t block = idx/8;
61+
size_t offset = idx%8;
62+
return Proxy{values[block], offset};
63+
}
64+
auto at(size_t idx) const -> bool {
65+
size_t block = idx/8;
66+
size_t offset = idx%8;
67+
return (values[block] >> offset) & 1;
68+
}
69+
auto operator[](this auto& self, size_t idx) {
70+
return self.at(idx);
71+
}
72+
73+
template <typename Archive>
74+
void serialize(this auto&& self, Archive& ar) {
75+
ar(self.used_capacity, self.values);
76+
}
77+
};
78+
79+
}

0 commit comments

Comments
 (0)