@@ -476,6 +476,30 @@ class EmbeddingRocksDB : public kv_db::EmbeddingKVDB {
476476#endif
477477 }
478478
479+ // / Create the metadata column family on shards that don't have it yet.
480+ // / Called by DRAM_SSD composite backend only — pure SSD tables don't need
481+ // / CF2.
482+ void ensure_metadata_cf () {
483+ for (size_t i = 0 ; i < dbs_.size (); ++i) {
484+ if (metadata_cf_handles_[i] == nullptr ) {
485+ rocksdb::ColumnFamilyHandle* md_handle = nullptr ;
486+ auto s =
487+ dbs_[i]->CreateColumnFamily (cf_options_, " metadata" , &md_handle);
488+ CHECK (s.ok ()) << " Failed to create metadata CF: " << s.ToString ();
489+ metadata_cf_handles_[i] = md_handle;
490+ }
491+ }
492+ }
493+
494+ void set_metadata_dim (int64_t dim) {
495+ metadata_dim_ = dim;
496+ LOG (INFO ) << " EmbeddingRocksDB::set_metadata_dim=" << metadata_dim_;
497+ }
498+
499+ int64_t get_metadata_dim () const {
500+ return metadata_dim_;
501+ }
502+
479503 void initialize_initializers (
480504 int64_t num_shards,
481505 int64_t max_D,
@@ -527,6 +551,76 @@ class EmbeddingRocksDB : public kv_db::EmbeddingKVDB {
527551 std::vector<folly::Unit>{});
528552 }
529553
554+ folly::SemiFuture<std::vector<folly::Unit>> set_kv_metadata_async (
555+ const at::Tensor& indices,
556+ const at::Tensor& metadata,
557+ const at::Tensor& count) override {
558+ auto count_ = count.scalar_type () == at::ScalarType::Long
559+ ? *(count.data_ptr <int64_t >())
560+ : *(count.data_ptr <int32_t >());
561+ if (count_ <= 0 || metadata_dim_ <= 0 ) {
562+ return folly::makeSemiFuture (std::vector<folly::Unit>());
563+ }
564+
565+ ensure_metadata_cf ();
566+ CHECK (indices.is_contiguous ());
567+ CHECK (metadata.is_contiguous ());
568+ CHECK_EQ (indices.size (0 ), metadata.size (0 ));
569+ CHECK_EQ (metadata.size (1 ), metadata_dim_);
570+
571+ std::vector<folly::Future<folly::Unit>> futures;
572+ futures.reserve (dbs_.size ());
573+ for (auto shard = 0 ; shard < dbs_.size (); ++shard) {
574+ auto f =
575+ folly::via (executor_.get ())
576+ .thenValue ([=, this , &indices, &metadata](folly::Unit) {
577+ FBGEMM_DISPATCH_FLOAT_HALF_AND_BYTE (
578+ metadata.scalar_type (), " ssd_set_metadata" , [&] {
579+ using value_t = scalar_t ;
580+ FBGEMM_DISPATCH_INTEGRAL_TYPES (
581+ indices.scalar_type (), " ssd_set_metadata" , [&] {
582+ using index_t = scalar_t ;
583+ CHECK (indices.is_contiguous ());
584+ CHECK (metadata.is_contiguous ());
585+ auto indices_acc = indices.accessor <index_t , 1 >();
586+ auto D = metadata.size (1 );
587+ rocksdb::WriteBatch batch (
588+ ((count_ + dbs_.size () - 1 ) / dbs_.size ()) *
589+ (sizeof (index_t ) + sizeof (value_t ) * D));
590+ int64_t metadata_write_count = 0 ;
591+ for (auto i = 0 ; i < count_; ++i) {
592+ if (indices_acc[i] < 0 ) {
593+ continue ;
594+ }
595+ if (kv_db_utils::hash_shard (
596+ indices_acc[i], dbs_.size ()) != shard) {
597+ continue ;
598+ }
599+ batch.Put (
600+ metadata_cf_handles_[shard],
601+ rocksdb::Slice (
602+ reinterpret_cast <const char *>(
603+ &(indices.data_ptr <index_t >()[i])),
604+ sizeof (index_t )),
605+ rocksdb::Slice (
606+ reinterpret_cast <const char *>(&(
607+ metadata.data_ptr <value_t >()[i * D])),
608+ D * sizeof (value_t )));
609+ ++metadata_write_count;
610+ }
611+ if (metadata_write_count > 0 ) {
612+ auto s = dbs_[shard]->Write (wo_, &batch);
613+ CHECK (s.ok ()) << " Metadata CF write failed: "
614+ << s.ToString ();
615+ }
616+ });
617+ });
618+ });
619+ futures.emplace_back (std::move (f));
620+ }
621+ return folly::collect (std::move (futures));
622+ }
623+
530624 void set_embedding_cache_enrich_query_id_async (
531625 at::Tensor hashed_indices,
532626 at::Tensor unhashed_indices,
0 commit comments