MCPcopy Create free account
hub / github.com/PlotJuggler/PlotJuggler / runMimoIncremental

Function runMimoIncremental

pj_datastore/src/derived_engine.cpp:921–1079  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

919// ---------------------------------------------------------------------------
920
921static PJ::Status runMimoIncremental(DerivedEngineImpl& /*impl*/, DataEngine& engine, DerivedNode& node) {
922 const std::size_t num_inputs = node.mimo_input_topic_ids.size();
923 if (num_inputs == 0) {
924 return PJ::okStatus();
925 }
926
927 // 1. Collect (timestamp, chunk*, row_index) for each input topic,
928 // only for rows strictly newer than the watermark.
929 struct SampleLoc {
930 PJ::Timestamp ts;
931 const TopicChunk* chunk;
932 uint32_t row;
933 };
934 std::vector<std::vector<SampleLoc>> per_topic(num_inputs);
935
936 PJ::ChunkId max_chunk_seen = node.mimo_last_chunk_id;
937 for (std::size_t i = 0; i < num_inputs; ++i) {
938 const TopicStorage* storage = engine.getTopicStorage(node.mimo_input_topic_ids[i]);
939 if (!storage) {
940 return PJ::unexpected(
941 fmt::format("run_mimo_incremental: input topic {} not found", node.mimo_input_topic_ids[i]));
942 }
943 for (const TopicChunk& chunk : storage->sealedChunks()) {
944 max_chunk_seen = std::max(max_chunk_seen, chunk.id);
945 if (chunk.stats.t_max <= node.mimo_last_ts) {
946 continue; // entire chunk already processed
947 }
948 for (uint32_t r = 0; r < chunk.stats.row_count; ++r) {
949 PJ::Timestamp ts = chunk.timestamps[r];
950 if (ts <= node.mimo_last_ts) {
951 continue;
952 }
953 per_topic[i].push_back({ts, &chunk, r});
954 }
955 }
956 }
957 // Every committed chunk has now been considered — regression detection in
958 // the scheduler compares against this watermark. Updated even when the run
959 // produces no joins, so a fruitless chunk is not re-flagged forever.
960 node.mimo_last_chunk_id = max_chunk_seen;
961 for (std::size_t i = 0; i < num_inputs; ++i) {
962 // If any topic has no new data, no new join is possible.
963 if (per_topic[i].empty()) {
964 return PJ::okStatus();
965 }
966 }
967 // Chunks are gathered in commit order, which under out-of-order ingest is
968 // not time order; joined_ts is derived from topic 0, so sort it (stable:
969 // duplicate timestamps keep commit order for last-write-wins lookups).
970 std::stable_sort(
971 per_topic[0].begin(), per_topic[0].end(), [](const SampleLoc& a, const SampleLoc& b) { return a.ts < b.ts; });
972
973 // 2. N-way timestamp intersection: find timestamps present in ALL input topics.
974 // Start from topic 0's sorted timestamps, remove any not in subsequent topics.
975 std::vector<PJ::Timestamp> joined_ts;
976 joined_ts.reserve(per_topic[0].size());
977 for (const auto& s : per_topic[0]) {
978 joined_ts.push_back(s.ts);

Callers 2

scheduleActiveLockedMethod · 0.85
recomputeNodeSelfOnlyFunction · 0.85

Calls 15

decodeAsVarvalueFunction · 0.85
writeVarvalueFunction · 0.85
getTopicStorageMethod · 0.80
reserveMethod · 0.80
eraseMethod · 0.80
createWriterMethod · 0.80
atMethod · 0.80
commitChunksLockedMethod · 0.80
sizeMethod · 0.45
emptyMethod · 0.45
beginMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected