#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "track_builder_internal.hpp" extern "C" { #include #include #include } namespace { namespace internal = lardon3d::track_builder_internal; bool profile_enabled() { const char *value = std::getenv("LARDON3D_TRACK_BUILDER_PROFILE"); return value != nullptr && std::strcmp(value, "1") == 0; } double elapsed_seconds(const std::chrono::steady_clock::time_point &start) { return std::chrono::duration(std::chrono::steady_clock::now() - start).count(); } /* CONTRACT: profile output is opt-in diagnostic stderr only. It carries no * task identity or scientific state, so a restarted task remains exactly the * same durable operation whether profiling is enabled or absent. */ void report_profile(bool enabled, uint64_t gvr_count, uint64_t raw_edge_hint, const internal::CompactGraph &graph, double hint_seconds, double graph_seconds, double resolve_seconds, double core_seconds, double serialize_seconds, double revalidate_seconds) { if (!enabled) return; const internal::Profile &profile = graph.profile(); const uint64_t identity_operations = profile.identity_lookups + profile.identity_inserts; const double mean_probe = identity_operations == 0 ? 0.0 : static_cast(profile.identity_probes) / static_cast(identity_operations); std::fprintf(stderr, "track_builder_profile gvr=%llu raw_edge_hint=%llu nodes=%zu raw_edges=%llu " "hint_s=%.3f graph_s=%.3f resolve_s=%.3f core_s=%.3f serialize_s=%.3f " "revalidate_s=%.3f identity_lookups=%llu identity_inserts=%llu " "identity_mean_probe=%.3f identity_max_probe=%llu\n", static_cast(gvr_count), static_cast(raw_edge_hint), graph.node_count(), static_cast(graph.raw_edge_count()), hint_seconds, graph_seconds, resolve_seconds, core_seconds, serialize_seconds, revalidate_seconds, static_cast(profile.identity_lookups), static_cast(profile.identity_inserts), mean_probe, static_cast(profile.identity_max_probe)); } #ifdef LARDON3D_TRACK_BUILDER_PROJECT_TESTING extern "C" void lardon3d_track_builder_project_test_publication_capacities( uint64_t node_count, uint64_t serialization_capacity_bytes); #endif struct FeatureCacheEntry { uint64_t feature_set_id = 0; uint64_t image_id = 0; uint32_t feature_count = 0; uint32_t metadata_index = 0; }; internal::FeatureMetadata project_metadata(const Lardon3DProjectDbFeatureSet &set) { internal::FeatureMetadata value{}; value.feature_set_id = set.feature_set_id; value.image_id = set.image_id; std::memcpy(value.extractor_kind, set.extractor_kind, sizeof(value.extractor_kind)); value.extractor_version = set.extractor_version; std::memcpy(value.parameter_fingerprint, set.parameter_fingerprint, 32); value.descriptor_type = set.descriptor_type; value.descriptor_dimension = set.descriptor_dimension; return value; } Lardon3DTrackBuilderProjectStatus map_db(Lardon3DProjectDbResult value) { if (value == LARDON3D_PROJECT_DB_INVALID_ARGUMENT || value == LARDON3D_PROJECT_DB_CONSTRAINT) return LARDON3D_TRACK_BUILDER_PROJECT_INVALID_ARGUMENT; if (value == LARDON3D_PROJECT_DB_NOT_FOUND) return LARDON3D_TRACK_BUILDER_PROJECT_NOT_FOUND; if (value == LARDON3D_PROJECT_DB_CORRUPT) return LARDON3D_TRACK_BUILDER_PROJECT_INPUT_CORRUPT; return LARDON3D_TRACK_BUILDER_PROJECT_DATABASE_ERROR; } bool join_path(char *output, size_t capacity, const char *root, const char *relative) { if (!output || !root || !relative || relative[0] == '\0') return false; int written = std::snprintf(output, capacity, "%s/%s", root, relative); return written > 0 && static_cast(written) < capacity; } bool scope_hash(const uint64_t *ids, size_t count, unsigned char output[32]) { if (count > (std::numeric_limits::max() - 8U) / sizeof(uint64_t)) return false; std::vector bytes(8U + count * sizeof(uint64_t)); std::memcpy(bytes.data(), "L3DTSIS1", 8); for (size_t i = 0; i < count; ++i) { uint64_t value = ids[i]; for (size_t byte = 0; byte < sizeof(value); ++byte) { bytes[8U + i * sizeof(value) + byte] = static_cast(value & 0xffU); value >>= 8U; } } unsigned int length = 0; return EVP_Digest(bytes.data(), bytes.size(), output, &length, EVP_sha256(), nullptr) == 1 && length == 32; } bool selector_matches(const Lardon3DProjectDbGeometricVerificationResult &gvr, const Lardon3DTrackBuilderProjectRequest &request) { return static_cast(gvr.verifier_kind) == request.verifier_kind && gvr.verifier_version == request.verifier_version && std::memcmp(gvr.parameter_fingerprint, request.verifier_fingerprint, 32) == 0; } Lardon3DProjectDbResult validate_gvr_snapshot( const Lardon3DTrackBuilderProjectRequest &request, uint64_t gvr_id) { Lardon3DProjectDbGeometricVerificationResult gvr{}; Lardon3DProjectDbResult db = lardon3d_project_db_load_geometric_verification_result( request.database, gvr_id, &gvr); if (db != LARDON3D_PROJECT_DB_OK) return db; if (gvr.status != LARDON3D_GEOMETRIC_VERIFIED || !selector_matches(gvr, request)) return LARDON3D_PROJECT_DB_CORRUPT; Lardon3DProjectDbMatchResult match{}; db = lardon3d_project_db_load_match_result(request.database, gvr.match_result_id, &match); if (db != LARDON3D_PROJECT_DB_OK || match.result_status != LARDON3D_MATCH_RESULT_STATUS_MATCHED || !match.has_match_asset) return db == LARDON3D_PROJECT_DB_OK ? LARDON3D_PROJECT_DB_CORRUPT : db; Lardon3DProjectDbCandidatePair pair{}; db = lardon3d_project_db_load_candidate_pair(request.database, match.candidate_pair_id, &pair); if (db != LARDON3D_PROJECT_DB_OK) return db; Lardon3DProjectDbFeatureSet set_a{}; Lardon3DProjectDbFeatureSet set_b{}; db = lardon3d_project_db_load_feature_set(request.database, match.feature_set_id_a, &set_a); if (db != LARDON3D_PROJECT_DB_OK) return db; db = lardon3d_project_db_load_feature_set(request.database, match.feature_set_id_b, &set_b); if (db != LARDON3D_PROJECT_DB_OK) return db; if (set_a.image_id != pair.image_id_a || set_b.image_id != pair.image_id_b || match.feature_set_id_a == match.feature_set_id_b) return LARDON3D_PROJECT_DB_CORRUPT; char path[LARDON3D_PROJECT_DB_PATH_CAPACITY]; if (!join_path(path, sizeof(path), request.project_path, match.match_asset_path)) return LARDON3D_PROJECT_DB_CORRUPT; Lardon3DMatchFileHeader header{}; if (lardon3d_match_file_validate_asset(path, match.match_asset_sha256, match.match_asset_size_bytes, &header, set_a.feature_set_id, set_b.feature_set_id, set_a.feature_count, set_b.feature_count) != LARDON3D_MATCH_FILE_OK || header.match_count != match.match_count) return LARDON3D_PROJECT_DB_CORRUPT; return LARDON3D_PROJECT_DB_OK; } Lardon3DTrackBuilderProjectStatus resolve_gvr( const Lardon3DTrackBuilderProjectRequest &request, uint64_t gvr_id, std::unordered_map &cache, internal::CompactGraph &graph) { Lardon3DProjectDbGeometricVerificationResult gvr{}; Lardon3DProjectDbResult db = lardon3d_project_db_load_geometric_verification_result( request.database, gvr_id, &gvr); if (db != LARDON3D_PROJECT_DB_OK) return map_db(db); if (gvr.status != LARDON3D_GEOMETRIC_VERIFIED || !selector_matches(gvr, request)) return LARDON3D_TRACK_BUILDER_PROJECT_INPUT_CORRUPT; Lardon3DProjectDbMatchResult match{}; db = lardon3d_project_db_load_match_result(request.database, gvr.match_result_id, &match); if (db != LARDON3D_PROJECT_DB_OK) return map_db(db); if (match.result_status != LARDON3D_MATCH_RESULT_STATUS_MATCHED || !match.has_match_asset || match.match_count == 0) return LARDON3D_TRACK_BUILDER_PROJECT_INPUT_CORRUPT; Lardon3DProjectDbCandidatePair pair{}; db = lardon3d_project_db_load_candidate_pair(request.database, match.candidate_pair_id, &pair); if (db != LARDON3D_PROJECT_DB_OK) return map_db(db); auto load_set = [&](uint64_t id, FeatureCacheEntry **out) { auto found = cache.find(id); if (found != cache.end()) { *out = &found->second; return LARDON3D_PROJECT_DB_OK; } FeatureCacheEntry entry{}; Lardon3DProjectDbFeatureSet loaded{}; Lardon3DProjectDbResult value = lardon3d_project_db_load_feature_set( request.database, id, &loaded); if (value == LARDON3D_PROJECT_DB_OK) { entry.feature_set_id = loaded.feature_set_id; entry.image_id = loaded.image_id; entry.feature_count = loaded.feature_count; entry.metadata_index = graph.register_feature(project_metadata(loaded)); auto inserted = cache.emplace(id, entry); *out = &inserted.first->second; } return value; }; FeatureCacheEntry *set_a = nullptr; FeatureCacheEntry *set_b = nullptr; db = load_set(match.feature_set_id_a, &set_a); if (db != LARDON3D_PROJECT_DB_OK) return map_db(db); db = load_set(match.feature_set_id_b, &set_b); if (db != LARDON3D_PROJECT_DB_OK) return map_db(db); if (set_a->image_id != pair.image_id_a || set_b->image_id != pair.image_id_b || match.feature_set_id_a == match.feature_set_id_b) return LARDON3D_TRACK_BUILDER_PROJECT_INPUT_CORRUPT; char path[LARDON3D_PROJECT_DB_PATH_CAPACITY]; if (!join_path(path, sizeof(path), request.project_path, match.match_asset_path)) return LARDON3D_TRACK_BUILDER_PROJECT_INPUT_CORRUPT; Lardon3DMatchFileHeader header{}; if (lardon3d_match_file_validate_asset(path, match.match_asset_sha256, match.match_asset_size_bytes, &header, set_a->feature_set_id, set_b->feature_set_id, set_a->feature_count, set_b->feature_count) != LARDON3D_MATCH_FILE_OK || header.match_count != match.match_count) return LARDON3D_TRACK_BUILDER_PROJECT_INPUT_CORRUPT; std::vector entries(match.match_count); int fd = open(path, O_RDONLY | O_NOFOLLOW | O_CLOEXEC); uint32_t count = 0; bool read_ok = fd >= 0 && lardon3d_match_file_read( fd, &header, entries.data(), entries.size(), &count, set_a->feature_set_id, set_b->feature_set_id, set_a->feature_count, set_b->feature_count) == LARDON3D_MATCH_FILE_OK; if (fd >= 0) (void)close(fd); if (!read_ok || count != match.match_count || gvr.inlier_mask_size != (count + 7U) / 8U) return LARDON3D_TRACK_BUILDER_PROJECT_INPUT_CORRUPT; size_t selected = 0; for (uint32_t i = 0; i < count; ++i) { if ((gvr.inlier_mask[i / 8U] & static_cast(1U << (i % 8U))) == 0) continue; ++selected; const auto &entry = entries[i]; const auto cache_a = cache.find(set_a->feature_set_id); const auto cache_b = cache.find(set_b->feature_set_id); if (cache_a == cache.end() || cache_b == cache.end() || !graph.add_edge(cache_a->second.metadata_index, entry.feature_index_a, cache_b->second.metadata_index, entry.feature_index_b)) return LARDON3D_TRACK_BUILDER_PROJECT_INPUT_CORRUPT; } if (selected != gvr.inlier_count) return LARDON3D_TRACK_BUILDER_PROJECT_INPUT_CORRUPT; return LARDON3D_TRACK_BUILDER_PROJECT_OK; } } // namespace Lardon3DTrackBuilderProjectStatus internal::build_project( const Lardon3DTrackBuilderProjectRequest *request, Lardon3DTrackBuilderProjectResult *result, Checkpoint checkpoint, void *checkpoint_userdata) { if (!request || !result || !request->project_path || !request->database || !request->verifier_fingerprint || !request->gvr_ids || request->gvr_count == 0 || request->verifier_kind <= 0 || request->verifier_version == 0) { return LARDON3D_TRACK_BUILDER_PROJECT_INVALID_ARGUMENT; } *result = {}; for (size_t i = 0; i < request->gvr_count; ++i) { if (request->gvr_ids[i] == 0 || (i != 0 && request->gvr_ids[i - 1] >= request->gvr_ids[i])) return LARDON3D_TRACK_BUILDER_PROJECT_INVALID_ARGUMENT; } try { const bool profiling = profile_enabled(); std::vector owned_ids(request->gvr_ids, request->gvr_ids + request->gvr_count); Lardon3DTrackBuilderProjectRequest owned_request = *request; owned_request.gvr_ids = owned_ids.data(); request = &owned_request; unsigned char input_hash[32]; if (!scope_hash(request->gvr_ids, request->gvr_count, input_hash)) return LARDON3D_TRACK_BUILDER_PROJECT_OUT_OF_MEMORY; unsigned char builder_fingerprint[32]; if (!lardon3d_track_builder_fingerprint(builder_fingerprint)) return LARDON3D_TRACK_BUILDER_PROJECT_CORE_ERROR; Lardon3DProjectDbTrackSet identity{}; std::snprintf(identity.builder_kind, sizeof(identity.builder_kind), "track_builder"); identity.builder_version = LARDON3D_TRACK_BUILDER_VERSION; std::memcpy(identity.parameter_fingerprint, builder_fingerprint, 32); identity.verifier_kind = request->verifier_kind; identity.verifier_version = request->verifier_version; std::memcpy(identity.verifier_fingerprint, request->verifier_fingerprint, 32); std::memcpy(identity.input_scope_hash, input_hash, 32); identity.gvr_count = request->gvr_count; Lardon3DProjectDbTrackSet found{}; Lardon3DProjectDbResult db = lardon3d_project_db_find_track_set( request->database, &identity, &found); if (db == LARDON3D_PROJECT_DB_OK) { if (found.gvr_count != request->gvr_count) return LARDON3D_TRACK_BUILDER_PROJECT_INPUT_CORRUPT; result->track_set_id = found.track_set_id; result->gvr_count = found.gvr_count; result->track_count = found.track_count; result->reused = true; return LARDON3D_TRACK_BUILDER_PROJECT_OK; } if (db != LARDON3D_PROJECT_DB_NOT_FOUND) return map_db(db); const auto hint_start = std::chrono::steady_clock::now(); uint64_t raw_edge_hint = 0; for (size_t i = 0; i < request->gvr_count; ++i) { Lardon3DProjectDbGeometricVerificationResult gvr{}; db = lardon3d_project_db_load_geometric_verification_result( request->database, request->gvr_ids[i], &gvr); if (db != LARDON3D_PROJECT_DB_OK) return map_db(db); if (gvr.inlier_count > UINT64_MAX - raw_edge_hint) return LARDON3D_TRACK_BUILDER_PROJECT_OUT_OF_MEMORY; raw_edge_hint += gvr.inlier_count; } const double hint_seconds = elapsed_seconds(hint_start); const auto graph_start = std::chrono::steady_clock::now(); internal::CompactGraph graph(raw_edge_hint); const double graph_seconds = elapsed_seconds(graph_start); std::unordered_map cache; const auto resolve_start = std::chrono::steady_clock::now(); for (size_t i = 0; i < request->gvr_count; ++i) { auto status = resolve_gvr(*request, request->gvr_ids[i], cache, graph); if (status != LARDON3D_TRACK_BUILDER_PROJECT_OK) return status; /* CONTRACT: Task pause/cancel is observed only between complete GVR * reads. DSU, canonicalization and atomic publication are never * preempted, so interruption cannot expose a partial Track Set. */ if (checkpoint && !checkpoint(checkpoint_userdata)) return LARDON3D_TRACK_BUILDER_PROJECT_INTERRUPTED; } const double resolve_seconds = elapsed_seconds(resolve_start); const auto core_start = std::chrono::steady_clock::now(); internal::Output core; auto core_status = graph.build(&core); if (core_status != LARDON3D_TRACK_BUILDER_OK) { return core_status == LARDON3D_TRACK_BUILDER_OUT_OF_MEMORY ? LARDON3D_TRACK_BUILDER_PROJECT_OUT_OF_MEMORY : LARDON3D_TRACK_BUILDER_PROJECT_CORE_ERROR; } const double core_seconds = elapsed_seconds(core_start); /* GATE D CONTRACT: Gate B (DSU/canonicalization) is deliberately * non-preemptible, but a pause/cancel raised during it must be observed * before any publication preparation can become durable. */ if (checkpoint && !checkpoint(checkpoint_userdata)) return LARDON3D_TRACK_BUILDER_PROJECT_INTERRUPTED; /* CONTRACT/SERIALIZATION: this is the sole transient conversion from * canonical compact membership to Track Model rows. position_in_track is * the already-canonical flat order; DB publication below remains the sole * atomic, owner-only persistence point. */ const auto serialize_start = std::chrono::steady_clock::now(); std::vector> stored(core.tracks.size()); std::vector publish(core.tracks.size()); for (size_t i = 0; i < core.tracks.size(); ++i) { const internal::TrackRange &range = core.tracks[i]; stored[i].resize(range.count); for (size_t j = 0; j < stored[i].size(); ++j) { const auto &source = core.memberships[range.begin + j]; stored[i][j] = {source.feature_set_id, source.feature_index, static_cast(j)}; } publish[i] = {0, 0, static_cast(stored[i].size()), stored[i].data()}; } const double serialize_seconds = elapsed_seconds(serialize_start); #ifdef LARDON3D_TRACK_BUILDER_PROJECT_TESTING uint64_t stored_observation_capacity = 0; for (const auto &observations : stored) stored_observation_capacity += observations.capacity(); const uint64_t serialization_capacity_bytes = stored_observation_capacity * sizeof(Lardon3DProjectDbTrackObservation) + stored.capacity() * sizeof(std::vector) + publish.capacity() * sizeof(Lardon3DProjectDbTrack); lardon3d_track_builder_project_test_publication_capacities( graph.node_count(), serialization_capacity_bytes); lardon3d_track_builder_project_test_before_revalidation( request->database, request->gvr_ids, request->gvr_count); #endif const auto revalidate_start = std::chrono::steady_clock::now(); for (size_t i = 0; i < request->gvr_count; ++i) { db = validate_gvr_snapshot(*request, request->gvr_ids[i]); if (db != LARDON3D_PROJECT_DB_OK) { return map_db(db); } } const double revalidate_seconds = elapsed_seconds(revalidate_start); report_profile(profiling, request->gvr_count, raw_edge_hint, graph, hint_seconds, graph_seconds, resolve_seconds, core_seconds, serialize_seconds, revalidate_seconds); /* GATE D CONTRACT: this is the final interruptible boundary. Refusal * guarantees zero publication; create_track_set below remains one * non-preemptible atomic publication. */ if (checkpoint && !checkpoint(checkpoint_userdata)) return LARDON3D_TRACK_BUILDER_PROJECT_INTERRUPTED; Lardon3DProjectDbTrackSet published{}; identity.track_count = core.tracks.size(); #ifdef LARDON3D_TRACK_BUILDER_PROJECT_TESTING lardon3d_track_builder_project_test_before_publication(request); Lardon3DProjectDbTrackSet raced_before_publish{}; if (lardon3d_project_db_find_track_set(request->database, &identity, &raced_before_publish) == LARDON3D_PROJECT_DB_OK) { result->track_set_id = raced_before_publish.track_set_id; result->gvr_count = raced_before_publish.gvr_count; result->track_count = raced_before_publish.track_count; result->raw_inlier_edge_count = graph.raw_edge_count(); result->core_observation_count = graph.node_count(); result->reused = true; return LARDON3D_TRACK_BUILDER_PROJECT_OK; } #endif db = lardon3d_project_db_create_track_set(request->database, &identity, publish.data(), publish.size(), &published); if (db == LARDON3D_PROJECT_DB_CONSTRAINT) { Lardon3DProjectDbTrackSet raced{}; db = lardon3d_project_db_find_track_set(request->database, &identity, &raced); if (db == LARDON3D_PROJECT_DB_OK) { result->track_set_id = raced.track_set_id; result->gvr_count = raced.gvr_count; result->track_count = raced.track_count; result->raw_inlier_edge_count = graph.raw_edge_count(); result->core_observation_count = graph.node_count(); result->reused = true; return LARDON3D_TRACK_BUILDER_PROJECT_OK; } } if (db != LARDON3D_PROJECT_DB_OK) return map_db(db); result->track_set_id = published.track_set_id; result->gvr_count = published.gvr_count; result->track_count = published.track_count; result->raw_inlier_edge_count = graph.raw_edge_count(); result->core_observation_count = graph.node_count(); result->reused = false; return LARDON3D_TRACK_BUILDER_PROJECT_OK; } catch (const std::bad_alloc &) { return LARDON3D_TRACK_BUILDER_PROJECT_OUT_OF_MEMORY; } catch (const std::invalid_argument &) { return LARDON3D_TRACK_BUILDER_PROJECT_INPUT_CORRUPT; } catch (...) { return LARDON3D_TRACK_BUILDER_PROJECT_DATABASE_ERROR; } } extern "C" Lardon3DTrackBuilderProjectStatus lardon3d_track_builder_build_project( const Lardon3DTrackBuilderProjectRequest *request, Lardon3DTrackBuilderProjectResult *result) { return internal::build_project(request, result, nullptr, nullptr); }