@@ -973,6 +973,7 @@ Status Redis::RPushx(const Slice& key, const std::vector<std::string>& values, u
973
973
}
974
974
975
975
Status Redis::ListsRename (const Slice& key, Redis* new_inst, const Slice& newkey) {
976
+ auto batch = Batch::CreateBatch (this );
976
977
std::string meta_value;
977
978
uint32_t statistic = 0 ;
978
979
const std::vector<std::string> keys = {key.ToString (), newkey.ToString ()};
@@ -994,18 +995,45 @@ Status Redis::ListsRename(const Slice& key, Redis* new_inst, const Slice& newkey
994
995
// copy a new list with newkey
995
996
ParsedListsMetaValue parsed_lists_meta_value (&meta_value);
996
997
statistic = parsed_lists_meta_value.Count ();
997
- s = new_inst->GetDB ()->Put (default_write_options_, handles_[kMetaCF ], base_meta_newkey.Encode (), meta_value);
998
+
999
+ // todo if value is too many, will slow to rename
1000
+ uint32_t version = parsed_lists_meta_value.Version ();
1001
+ uint64_t index = parsed_lists_meta_value.LeftIndex () + 1 ;
1002
+ uint64_t right_index = parsed_lists_meta_value.RightIndex () - 1 ;
1003
+ ListsDataKey base_lists_data_key (key, version, index );
1004
+ std::vector<std::string> list_nodes;
1005
+ rocksdb::Iterator* iter = db_->NewIterator (default_read_options_, handles_[kListsDataCF ]);
1006
+ uint64_t current_index = index ;
1007
+ for (iter->Seek (base_lists_data_key.Encode ()); iter->Valid () && current_index <= right_index;
1008
+ iter->Next (), current_index++) {
1009
+ ParsedBaseDataValue parsed_value (iter->value ());
1010
+ list_nodes.push_back (parsed_value.UserValue ().ToString ());
1011
+ }
1012
+ delete iter;
1013
+
1014
+ // write new data value
1015
+ current_index = index ;
1016
+ for (const auto & node : list_nodes) {
1017
+ ListsDataKey new_lists_data_key (newkey, version, current_index++);
1018
+ BaseDataValue n_val (node);
1019
+ batch->Put (kListsDataCF , new_lists_data_key.Encode (), n_val.Encode ());
1020
+ }
1021
+ // write new meta_key
1022
+ batch->Put (kMetaCF , base_meta_newkey.Encode (), meta_value);
998
1023
new_inst->UpdateSpecificKeyStatistics (DataType::kLists , newkey.ToString (), statistic);
999
1024
1000
1025
// ListsDel key
1001
1026
parsed_lists_meta_value.InitialMetaValue ();
1002
1027
s = db_->Put (default_write_options_, handles_[kMetaCF ], base_meta_key.Encode (), meta_value);
1028
+ batch->Delete (kListsDataCF , base_meta_key.Encode ());
1003
1029
UpdateSpecificKeyStatistics (DataType::kLists , key.ToString (), statistic);
1004
1030
1005
- return s ;
1031
+ return batch-> Commit () ;
1006
1032
}
1007
1033
1008
1034
Status Redis::ListsRenamenx (const Slice& key, Redis* new_inst, const Slice& newkey) {
1035
+ auto batch = Batch::CreateBatch (this );
1036
+
1009
1037
std::string meta_value;
1010
1038
uint32_t statistic = 0 ;
1011
1039
const std::vector<std::string> keys = {key.ToString (), newkey.ToString ()};
@@ -1029,22 +1057,48 @@ Status Redis::ListsRenamenx(const Slice& key, Redis* new_inst, const Slice& newk
1029
1057
ParsedListsMetaValue parsed_lists_meta_value (&meta_value);
1030
1058
s = new_inst->GetDB ()->Get (default_read_options_, handles_[kMetaCF ], base_meta_newkey.Encode (), &new_meta_value);
1031
1059
if (s.ok ()) {
1032
- if (IsStale (new_meta_value)) {
1060
+ ParsedListsMetaValue parsed_lists_new_meta_value (new_meta_value);
1061
+ if (parsed_lists_new_meta_value.Count () != 0 || parsed_lists_new_meta_value.IsStale ()) {
1033
1062
return Status::Corruption (); // newkey already exists.
1034
1063
}
1035
1064
}
1036
- ParsedSetsMetaValue parsed_lists_new_meta_value (&new_meta_value);
1065
+ // ParsedListsMetaValue parsed_lists_new_meta_value(&new_meta_value);
1037
1066
// copy a new list with newkey
1038
1067
statistic = parsed_lists_meta_value.Count ();
1039
- s = new_inst->GetDB ()->Put (default_write_options_, handles_[kMetaCF ], base_meta_newkey.Encode (), meta_value);
1068
+
1069
+ // todo if value is too many, will slow to rename
1070
+ uint32_t version = parsed_lists_meta_value.Version ();
1071
+ uint64_t index = parsed_lists_meta_value.LeftIndex () + 1 ;
1072
+ uint64_t right_index = parsed_lists_meta_value.RightIndex () - 1 ;
1073
+ ListsDataKey base_lists_data_key (key, version, index );
1074
+ std::vector<std::string> list_nodes;
1075
+ rocksdb::Iterator* iter = db_->NewIterator (default_read_options_, handles_[kListsDataCF ]);
1076
+ uint64_t current_index = index ;
1077
+ for (iter->Seek (base_lists_data_key.Encode ()); iter->Valid () && current_index <= right_index;
1078
+ iter->Next (), current_index++) {
1079
+ ParsedBaseDataValue parsed_value (iter->value ());
1080
+ list_nodes.push_back (parsed_value.UserValue ().ToString ());
1081
+ }
1082
+ delete iter;
1083
+
1084
+ // write new data value
1085
+ current_index = index ;
1086
+ for (const auto & node : list_nodes) {
1087
+ ListsDataKey new_lists_data_key (newkey, version, current_index++);
1088
+ BaseDataValue n_val (node);
1089
+ batch->Put (kListsDataCF , new_lists_data_key.Encode (), n_val.Encode ());
1090
+ }
1091
+ // write new meta_key
1092
+ batch->Put (kMetaCF , base_meta_newkey.Encode (), meta_value);
1040
1093
new_inst->UpdateSpecificKeyStatistics (DataType::kLists , newkey.ToString (), statistic);
1041
1094
1042
1095
// ListsDel key
1043
1096
parsed_lists_meta_value.InitialMetaValue ();
1044
1097
s = db_->Put (default_write_options_, handles_[kMetaCF ], base_meta_key.Encode (), meta_value);
1098
+ batch->Delete (kListsDataCF , base_meta_key.Encode ());
1045
1099
UpdateSpecificKeyStatistics (DataType::kLists , key.ToString (), statistic);
1046
1100
1047
- return s ;
1101
+ return batch-> Commit () ;
1048
1102
}
1049
1103
1050
1104
void Redis::ScanLists () {
0 commit comments