|
1 | 1 | #pragma once |
2 | 2 |
|
3 | | -// Graph Interfaces |
4 | | -#include "deglib/graph/search_graph.h" |
| 3 | +// Core InternalGraph Interface (0..N-1 internal index) |
| 4 | +#include "deglib/graph/internal_graph.h" |
5 | 5 | #include "deglib/graph/mutable_graph.h" |
6 | 6 | #include "deglib/graph/dynamic_graph.h" |
7 | 7 |
|
|
11 | 11 | // Concrete Graph Implementations |
12 | 12 | #include "deglib/graph/readonly_graph.h" |
13 | 13 | #include "deglib/graph/sizebounded_graph.h" |
| 14 | + |
| 15 | +#include <vector> |
| 16 | +#include <span> |
| 17 | +#include <stdexcept> |
| 18 | +#include <memory> |
| 19 | + |
| 20 | +namespace deglib { |
| 21 | + |
| 22 | +/** |
| 23 | + * Public DynamicExplorationGraph Facade for End Users. |
| 24 | + * All public methods accept and return external_labels (User Object IDs). |
| 25 | + * Internal calls map transparently between external_label and internal_index. |
| 26 | + */ |
| 27 | +class DynamicExplorationGraph { |
| 28 | +private: |
| 29 | + deglib::graph::InternalGraph& internal_graph_; |
| 30 | + |
| 31 | +public: |
| 32 | + explicit DynamicExplorationGraph(deglib::graph::InternalGraph& graph) : internal_graph_(graph) {} |
| 33 | + |
| 34 | + const uint32_t size() const { |
| 35 | + return internal_graph_.size(); |
| 36 | + } |
| 37 | + |
| 38 | + const uint8_t getEdgesPerVertex() const { |
| 39 | + return internal_graph_.getEdgesPerVertex(); |
| 40 | + } |
| 41 | + |
| 42 | + const deglib::FloatSpace& getFeatureSpace() const { |
| 43 | + return internal_graph_.getFeatureSpace(); |
| 44 | + } |
| 45 | + |
| 46 | + bool hasVertex(const uint32_t external_label) const { |
| 47 | + return internal_graph_.hasVertex(external_label); |
| 48 | + } |
| 49 | + |
| 50 | + deglib::graph::InternalGraph& internal() { |
| 51 | + return internal_graph_; |
| 52 | + } |
| 53 | + const deglib::graph::InternalGraph& internal() const { |
| 54 | + return internal_graph_; |
| 55 | + } |
| 56 | + |
| 57 | + bool isMutable() const { |
| 58 | + return dynamic_cast<const deglib::graph::MutableGraph*>(&internal_graph_) != nullptr; |
| 59 | + } |
| 60 | + /** |
| 61 | + * Search for similar feature vectors using query data. |
| 62 | + * Returns a ResultSet where internal indices are mapped to external_labels. |
| 63 | + */ |
| 64 | + template <typename T> |
| 65 | + deglib::graph::ResultSet search( |
| 66 | + std::span<const T> query, |
| 67 | + const uint32_t k, |
| 68 | + const float eps = 0.0f, |
| 69 | + const deglib::graph::Filter* filter = nullptr, |
| 70 | + const uint32_t max_distance_computation_count = 0) const |
| 71 | + { |
| 72 | + auto internal_res = internal_graph_.search(query, k, eps, filter, max_distance_computation_count); |
| 73 | + deglib::graph::ResultSet external_res; |
| 74 | + for (const auto& od : internal_res) { |
| 75 | + uint32_t ext_label = internal_graph_.getExternalLabel(od.getInternalIndex()); |
| 76 | + external_res.push(deglib::graph::ObjectDistance(ext_label, od.getDistance())); |
| 77 | + } |
| 78 | + return external_res; |
| 79 | + } |
| 80 | + |
| 81 | + /** |
| 82 | + * Exploration starting at a specific external_label. |
| 83 | + * Maps entry external_label to internal_index, performs search, and maps result back to external_labels. |
| 84 | + */ |
| 85 | + deglib::graph::ResultSet explore( |
| 86 | + const uint32_t entry_external_label, |
| 87 | + const uint32_t k, |
| 88 | + const uint32_t max_distance_computation_count = 0, |
| 89 | + const float eps = 0.0f, |
| 90 | + const bool include_entry = true, |
| 91 | + const deglib::graph::Filter* filter = nullptr) const |
| 92 | + { |
| 93 | + uint32_t internal_entry = internal_graph_.getInternalIndex(entry_external_label); |
| 94 | + auto internal_res = internal_graph_.explore(internal_entry, k, max_distance_computation_count, eps, include_entry, filter); |
| 95 | + deglib::graph::ResultSet external_res; |
| 96 | + for (const auto& od : internal_res) { |
| 97 | + uint32_t ext_label = internal_graph_.getExternalLabel(od.getInternalIndex()); |
| 98 | + external_res.push(deglib::graph::ObjectDistance(ext_label, od.getDistance())); |
| 99 | + } |
| 100 | + return external_res; |
| 101 | + } |
| 102 | + |
| 103 | + /** |
| 104 | + * Get neighbors as external_labels for a given external_label. |
| 105 | + */ |
| 106 | + std::vector<uint32_t> getNeighbors(const uint32_t external_label) const { |
| 107 | + uint32_t internal_idx = internal_graph_.getInternalIndex(external_label); |
| 108 | + const uint32_t* internal_neighbors = internal_graph_.getNeighborIndices(internal_idx); |
| 109 | + uint8_t edges_count = internal_graph_.getEdgesPerVertex(); |
| 110 | + std::vector<uint32_t> external_neighbors(edges_count); |
| 111 | + for (size_t i = 0; i < edges_count; ++i) { |
| 112 | + external_neighbors[i] = internal_graph_.getExternalLabel(internal_neighbors[i]); |
| 113 | + } |
| 114 | + return external_neighbors; |
| 115 | + } |
| 116 | +}; |
| 117 | + |
| 118 | +} // namespace deglib |
0 commit comments