27
27
#include " impl/odescent_graph_builder.h"
28
28
#include " impl/pruning_strategy.h"
29
29
#include " index/iterator_filter.h"
30
+ #include " logger.h"
31
+ #include " serialization.h"
32
+ #include " stream_reader.h"
33
+ #include " typing.h"
30
34
#include " utils/standard_heap.h"
31
35
#include " utils/util_functions.h"
36
+ #include " vsag/options.h"
32
37
33
38
namespace vsag {
34
39
@@ -605,7 +610,7 @@ HGraph::RangeSearch(const DatasetPtr& query,
605
610
}
606
611
607
612
void
608
- HGraph::serialize_basic_info (StreamWriter& writer) const {
613
+ HGraph::serialize_basic_info_v0_14 (StreamWriter& writer) const {
609
614
StreamWriter::WriteObj (writer, this ->use_reorder_ );
610
615
StreamWriter::WriteObj (writer, this ->dim_ );
611
616
StreamWriter::WriteObj (writer, this ->metric_ );
@@ -627,12 +632,126 @@ HGraph::serialize_basic_info(StreamWriter& writer) const {
627
632
}
628
633
}
629
634
635
+ void
636
+ HGraph::deserialize_basic_info_v0_14 (StreamReader& reader) {
637
+ StreamReader::ReadObj (reader, this ->use_reorder_ );
638
+ StreamReader::ReadObj (reader, this ->dim_ );
639
+ StreamReader::ReadObj (reader, this ->metric_ );
640
+ uint64_t max_level;
641
+ StreamReader::ReadObj (reader, max_level);
642
+ for (uint64_t i = 0 ; i < max_level; ++i) {
643
+ this ->route_graphs_ .emplace_back (this ->generate_one_route_graph ());
644
+ }
645
+ StreamReader::ReadObj (reader, this ->entry_point_id_ );
646
+ StreamReader::ReadObj (reader, this ->ef_construct_ );
647
+ StreamReader::ReadObj (reader, this ->mult_ );
648
+ InnerIdType capacity;
649
+ StreamReader::ReadObj (reader, capacity);
650
+ this ->max_capacity_ .store (capacity);
651
+ StreamReader::ReadVector (reader, this ->label_table_ ->label_table_ );
652
+
653
+ uint64_t size;
654
+ StreamReader::ReadObj (reader, size);
655
+ for (uint64_t i = 0 ; i < size; ++i) {
656
+ LabelType key;
657
+ StreamReader::ReadObj (reader, key);
658
+ InnerIdType value;
659
+ StreamReader::ReadObj (reader, value);
660
+ this ->label_table_ ->label_remap_ .emplace (key, value);
661
+ }
662
+ }
663
+
664
+ #define TO_JSON (json_obj, var ) \
665
+ json_obj[#var] = this ->var##_;
666
+
667
+ #define TO_JSON_BASE64 (json_obj, var ) \
668
+ json_obj[#var] = base64_encode_obj(this ->var##_);
669
+
670
+ #define TO_JSON_ATOMIC (json_obj, var ) \
671
+ json_obj[#var] = this ->var##_.load();
672
+
673
+ JsonType
674
+ HGraph::serialize_basic_info () const {
675
+ JsonType jsonify_basic_info;
676
+ TO_JSON (jsonify_basic_info, use_reorder);
677
+ TO_JSON (jsonify_basic_info, dim);
678
+ TO_JSON (jsonify_basic_info, metric);
679
+ TO_JSON (jsonify_basic_info, entry_point_id);
680
+ TO_JSON (jsonify_basic_info, ef_construct);
681
+ // logger::debug("mult: {}", this->mult_);
682
+ TO_JSON_BASE64 (jsonify_basic_info, mult);
683
+ TO_JSON_ATOMIC (jsonify_basic_info, max_capacity);
684
+ jsonify_basic_info[" max_level" ] = this ->route_graphs_ .size ();
685
+
686
+ return jsonify_basic_info;
687
+ }
688
+
689
+ #define FROM_JSON (json_obj, var ) \
690
+ this ->var##_ = (json_obj)[#var];
691
+
692
+ #define FROM_JSON_BASE64 (json_obj, var ) \
693
+ base64_decode_obj ((json_obj)[#var], this ->var##_);
694
+
695
+ #define FROM_JSON_ATOMIC (json_obj, var ) \
696
+ this ->var##_.store((json_obj)[#var]);
697
+
698
+ void
699
+ HGraph::deserialize_basic_info (JsonType jsonify_basic_info) {
700
+ FROM_JSON (jsonify_basic_info, use_reorder);
701
+ FROM_JSON (jsonify_basic_info, dim);
702
+ FROM_JSON (jsonify_basic_info, metric);
703
+ FROM_JSON (jsonify_basic_info, entry_point_id);
704
+ FROM_JSON (jsonify_basic_info, ef_construct);
705
+ FROM_JSON_BASE64 (jsonify_basic_info, mult);
706
+ // logger::debug("mult: {}", this->mult_);
707
+ FROM_JSON_ATOMIC (jsonify_basic_info, max_capacity);
708
+
709
+ uint64_t max_level = jsonify_basic_info[" max_level" ];
710
+ for (uint64_t i = 0 ; i < max_level; ++i) {
711
+ this ->route_graphs_ .emplace_back (this ->generate_one_route_graph ());
712
+ }
713
+ }
714
+
715
+ void
716
+ HGraph::serialize_label_info (StreamWriter& writer) const {
717
+ StreamWriter::WriteVector (writer, this ->label_table_ ->label_table_ );
718
+ uint64_t size = this ->label_table_ ->label_remap_ .size ();
719
+ StreamWriter::WriteObj (writer, size);
720
+ for (const auto & pair : this ->label_table_ ->label_remap_ ) {
721
+ auto key = pair.first ;
722
+ StreamWriter::WriteObj (writer, key);
723
+ StreamWriter::WriteObj (writer, pair.second );
724
+ }
725
+ }
726
+
727
+ void
728
+ HGraph::deserialize_label_info (StreamReader& reader) const {
729
+ StreamReader::ReadVector (reader, this ->label_table_ ->label_table_ );
730
+ uint64_t size;
731
+ StreamReader::ReadObj (reader, size);
732
+ for (uint64_t i = 0 ; i < size; ++i) {
733
+ LabelType key;
734
+ StreamReader::ReadObj (reader, key);
735
+ InnerIdType value;
736
+ StreamReader::ReadObj (reader, value);
737
+ this ->label_table_ ->label_remap_ .emplace (key, value);
738
+ }
739
+ }
740
+
630
741
void
631
742
HGraph::Serialize (StreamWriter& writer) const {
632
743
if (this ->ignore_reorder_ ) {
633
744
this ->use_reorder_ = false ;
634
745
}
635
- this ->serialize_basic_info (writer);
746
+
747
+ // basic info moved to metadata since version 0.15
748
+ // only for test
749
+ if (Options::Instance ().new_version ()) {
750
+ this ->serialize_label_info (writer);
751
+ } else {
752
+ this ->serialize_basic_info_v0_14 (writer);
753
+ }
754
+
636
755
this ->basic_flatten_codes_ ->Serialize (writer);
637
756
this ->bottom_graph_ ->Serialize (writer);
638
757
if (this ->use_reorder_ ) {
@@ -644,11 +763,32 @@ HGraph::Serialize(StreamWriter& writer) const {
644
763
if (this ->extra_info_size_ > 0 && this ->extra_infos_ != nullptr ) {
645
764
this ->extra_infos_ ->Serialize (writer);
646
765
}
766
+
767
+ // serialize footer (introduce since v0.15)
768
+ if (Options::Instance ().new_version ()) {
769
+ auto metadata = std::make_shared<Metadata>();
770
+ auto jsonify_basic_info = this ->serialize_basic_info ();
771
+ metadata->Set (" basic_info" , jsonify_basic_info);
772
+ logger::debug (jsonify_basic_info.dump ());
773
+ auto footer = std::make_shared<Footer>(metadata);
774
+ footer->Write (writer);
775
+ }
647
776
}
648
777
649
778
void
650
779
HGraph::Deserialize (StreamReader& reader) {
651
- this ->deserialize_basic_info (reader);
780
+ // try to deserialize footer (only in new version)
781
+ auto footer = Footer::Parse (reader);
782
+ if (footer != nullptr ) {
783
+ logger::debug (" parse with new version format" );
784
+ auto metadata = footer->GetMetadata ();
785
+ this ->deserialize_basic_info (metadata->Get (" basic_info" ));
786
+ this ->deserialize_label_info (reader);
787
+ } else {
788
+ logger::debug (" parse with v0.14 version format" );
789
+ this ->deserialize_basic_info_v0_14 (reader);
790
+ }
791
+
652
792
this ->basic_flatten_codes_ ->Deserialize (reader);
653
793
this ->bottom_graph_ ->Deserialize (reader);
654
794
if (this ->use_reorder_ ) {
@@ -674,35 +814,6 @@ HGraph::Deserialize(StreamReader& reader) {
674
814
}
675
815
}
676
816
677
- void
678
- HGraph::deserialize_basic_info (StreamReader& reader) {
679
- StreamReader::ReadObj (reader, this ->use_reorder_ );
680
- StreamReader::ReadObj (reader, this ->dim_ );
681
- StreamReader::ReadObj (reader, this ->metric_ );
682
- uint64_t max_level;
683
- StreamReader::ReadObj (reader, max_level);
684
- for (uint64_t i = 0 ; i < max_level; ++i) {
685
- this ->route_graphs_ .emplace_back (this ->generate_one_route_graph ());
686
- }
687
- StreamReader::ReadObj (reader, this ->entry_point_id_ );
688
- StreamReader::ReadObj (reader, this ->ef_construct_ );
689
- StreamReader::ReadObj (reader, this ->mult_ );
690
- InnerIdType capacity;
691
- StreamReader::ReadObj (reader, capacity);
692
- this ->max_capacity_ .store (capacity);
693
- StreamReader::ReadVector (reader, this ->label_table_ ->label_table_ );
694
-
695
- uint64_t size;
696
- StreamReader::ReadObj (reader, size);
697
- for (uint64_t i = 0 ; i < size; ++i) {
698
- LabelType key;
699
- StreamReader::ReadObj (reader, key);
700
- InnerIdType value;
701
- StreamReader::ReadObj (reader, value);
702
- this ->label_table_ ->label_remap_ .emplace (key, value);
703
- }
704
- }
705
-
706
817
float
707
818
HGraph::CalcDistanceById (const float * query, int64_t id) const {
708
819
auto flat = this ->basic_flatten_codes_ ;
0 commit comments