@@ -44,6 +44,112 @@ std::vector<LocatedTriple> LocatedTriple::locateSortedTriplesInPermutation(
4444 return out;
4545}
4646
47+ // Added for benchmarking
48+ std::vector<LocatedTriple> LocatedTriple::locateSortedTriplesInPermutation (
49+ const vector<IdTriple>& triples, const Permutation& permutation) {
50+ if (triples.size () == 0 ) return {};
51+
52+ auto keyOrder = permutation.keyOrder ();
53+ const Permutation::MetaData& meta = permutation.metaData ();
54+ const vector<CompressedBlockMetadata>& blocks = meta.blockData ();
55+
56+ vector<LocatedTriple> out{triples.size ()};
57+ size_t currentBlockIndex = 0 ;
58+
59+ for (auto [id1, id2, id3] : triples) {
60+ CompressedBlockMetadata::PermutedTriple triple = {id1, id2, id3};
61+
62+ while (triple > blocks.at (currentBlockIndex).lastTriple_ &&
63+ currentBlockIndex > blocks.size () - 1 ) {
64+ currentBlockIndex++;
65+ }
66+
67+ out.push_back (
68+ {currentBlockIndex, LocatedTriple::NO_ROW_INDEX, id1, id2, id3, false });
69+ }
70+
71+ return out;
72+ }
73+
74+ // Added for benchmarking
75+ std::vector<LocatedTriple> LocatedTriple::locateTriplesInPermutation (
76+ const IdTable& triples, const Permutation& permutation) {
77+ AD_CONTRACT_CHECK (triples.numColumns () == 3 );
78+
79+ if (triples.numRows () == 0 ) return {};
80+
81+ auto keyOrder = permutation.keyOrder ();
82+ const Permutation::MetaData& meta = permutation.metaData ();
83+ const vector<CompressedBlockMetadata>& blocks = meta.blockData ();
84+
85+ vector<LocatedTriple> out{triples.size ()};
86+ size_t currentBlockIndex;
87+ for (size_t i : std::views::iota ((size_t )0 , triples.size ())) {
88+ auto id1 = triples (i, keyOrder[0 ]);
89+ auto id2 = triples (i, keyOrder[1 ]);
90+ auto id3 = triples (i, keyOrder[2 ]);
91+ currentBlockIndex =
92+ std::lower_bound (blocks.begin (), blocks.end (),
93+ std::array<Id, 3 >{id1, id2, id3},
94+ [&](const CompressedBlockMetadata& block,
95+ const auto & triple) -> bool {
96+ // std::array<Id, 3> kann auch < aus den komponenten
97+ const auto & lastTriple = block.lastTriple_ ;
98+ if (lastTriple.col0Id_ < triple[0 ]) {
99+ return true ;
100+ } else if (lastTriple.col0Id_ == triple[0 ]) {
101+ if (lastTriple.col1Id_ < triple[1 ]) {
102+ return true ;
103+ } else if (lastTriple.col1Id_ == triple[1 ]) {
104+ return lastTriple.col2Id_ < triple[2 ];
105+ }
106+ }
107+ return false ;
108+ }) -
109+ blocks.begin ();
110+ out.push_back (
111+ {currentBlockIndex, LocatedTriple::NO_ROW_INDEX, id1, id2, id3, false });
112+ }
113+
114+ return out;
115+ }
116+
117+ // Added for benchmarking
118+ std::vector<LocatedTriple> LocatedTriple::locateTriplesInPermutation (
119+ const std::vector<IdTriple>& triples, const Permutation& permutation) {
120+ // Triples können auch sortiert sein.
121+ const Permutation::MetaData& meta = permutation.metaData ();
122+ const vector<CompressedBlockMetadata>& blocks = meta.blockData ();
123+
124+ vector<LocatedTriple> out{triples.size ()};
125+ size_t currentBlockIndex;
126+ for (auto & [id1, id2, id3] : triples) {
127+ currentBlockIndex =
128+ std::lower_bound (blocks.begin (), blocks.end (),
129+ std::array<Id, 3 >{id1, id2, id3},
130+ [&](const CompressedBlockMetadata& block,
131+ const auto & triple) -> bool {
132+ // std::array<Id, 3> kann auch < aus den komponenten
133+ const auto & lastTriple = block.lastTriple_ ;
134+ if (lastTriple.col0Id_ < triple[0 ]) {
135+ return true ;
136+ } else if (lastTriple.col0Id_ == triple[0 ]) {
137+ if (lastTriple.col1Id_ < triple[1 ]) {
138+ return true ;
139+ } else if (lastTriple.col1Id_ == triple[1 ]) {
140+ return lastTriple.col2Id_ < triple[2 ];
141+ }
142+ }
143+ return false ;
144+ }) -
145+ blocks.begin ();
146+ out.push_back (
147+ {currentBlockIndex, LocatedTriple::NO_ROW_INDEX, id1, id2, id3, false });
148+ }
149+
150+ return out;
151+ }
152+
47153// ____________________________________________________________________________
48154LocatedTriple LocatedTriple::locateTripleInPermutation (
49155 Id id1, Id id2, Id id3, const Permutation& permutation) {
@@ -118,14 +224,16 @@ LocatedTriple LocatedTriple::locateTripleInPermutation(
118224 DecompressedBlock blockTuples =
119225 reader.readAndDecompressBlock (*matchingBlock, columnIndices);
120226
121- if (matchingBlock->firstTriple_ .col0Id_ <= id1) {
227+ if (matchingBlock->firstTriple_ .col0Id_ <= id1) {
122228 // The triple is actually inside this block.
123229 locatedTriple.rowIndexInBlock =
124230 std::lower_bound (
125- blockTuples.begin (),
126- blockTuples. end (), std::array<Id, 3 >{id1, id2, id3},
231+ blockTuples.begin (), blockTuples. end (),
232+ std::array<Id, 3 >{id1, id2, id3},
127233 [](const auto & a, const auto & b) {
128- return a[0 ] < b[0 ] || (a[0 ] == b[0 ] && (a[1 ] < b[1 ] || (a[1 ] == b[1 ] && a[2 ] < b[2 ])));
234+ return a[0 ] < b[0 ] ||
235+ (a[0 ] == b[0 ] &&
236+ (a[1 ] < b[1 ] || (a[1 ] == b[1 ] && a[2 ] < b[2 ])));
129237 }) -
130238 blockTuples.begin ();
131239 // Check if the triple at the found position is equal to `id1 id2 id3` to
@@ -163,8 +271,8 @@ std::pair<size_t, size_t> LocatedTriplesPerBlock::numTriples(
163271 (scanSpec.col0Id ().value () == locatedTriple.id1 &&
164272 (!scanSpec.col1Id () ||
165273 (scanSpec.col1Id ().value () == locatedTriple.id2 &&
166- (!scanSpec.col2Id () || scanSpec. col2Id (). value () == locatedTriple. id3 )))))
167- {
274+ (!scanSpec.col2Id () ||
275+ scanSpec. col2Id (). value () == locatedTriple. id3 ))))) {
168276 if (locatedTriple.existsInIndex ) {
169277 ++countExists;
170278 } else {
@@ -175,13 +283,10 @@ std::pair<size_t, size_t> LocatedTriplesPerBlock::numTriples(
175283 return {countNew, countExists};
176284}
177285
178- size_t LocatedTriplesPerBlock::mergeTriples (size_t blockIndex,
179- std::optional<IdTable> block,
180- IdTable& result,
181- size_t offsetInResult,
182- ScanSpecification scanSpec,
183- size_t rowIndexInBlockBegin,
184- size_t rowIndexInBlockEnd) const {
286+ size_t LocatedTriplesPerBlock::mergeTriples (
287+ size_t blockIndex, std::optional<IdTable> block, IdTable& result,
288+ size_t offsetInResult, ScanSpecification scanSpec,
289+ size_t rowIndexInBlockBegin, size_t rowIndexInBlockEnd) const {
185290 // TODO:
186291 AD_CONTRACT_CHECK (!scanSpec.col2Id ().has_value ());
187292
@@ -229,9 +334,11 @@ size_t LocatedTriplesPerBlock::mergeTriples(size_t blockIndex,
229334 // considered, given the `matchMode`.
230335 auto locatedTripleMatches = [&]() {
231336 return !scanSpec.col0Id ().has_value () ||
232- (locatedTriple->id1 == scanSpec.col0Id ().value () && (!scanSpec.col1Id ().has_value () ||
233- (locatedTriple->id2 == scanSpec.col1Id ().value () && (!scanSpec.col2Id ().has_value () ||
234- locatedTriple->id3 == scanSpec.col2Id ().value ()))));
337+ (locatedTriple->id1 == scanSpec.col0Id ().value () &&
338+ (!scanSpec.col1Id ().has_value () ||
339+ (locatedTriple->id2 == scanSpec.col1Id ().value () &&
340+ (!scanSpec.col2Id ().has_value () ||
341+ locatedTriple->id3 == scanSpec.col2Id ().value ()))));
235342 };
236343
237344 // Advance to the first located triple in the specified range.
0 commit comments