@@ -24,6 +24,7 @@ extern "C" {
2424#include " base/endian.h"
2525#include " base/flags.h"
2626#include " base/logging.h"
27+ #include " core/string_map.h"
2728#include " core/string_set.h"
2829#include " server/engine_shard_set.h"
2930#include " server/error.h"
@@ -534,8 +535,6 @@ void RdbLoaderBase::OpaqueObjLoader::CreateHMap(const LoadTrace* ltrace) {
534535 }
535536 }
536537
537- robj* res = nullptr ;
538-
539538 if (keep_lp) {
540539 uint8_t * lp = lpNew (lp_size);
541540
@@ -554,44 +553,30 @@ void RdbLoaderBase::OpaqueObjLoader::CreateHMap(const LoadTrace* ltrace) {
554553 }
555554
556555 lp = lpShrinkToFit (lp);
557- res = createObject (OBJ_HASH, lp);
558- res->encoding = OBJ_ENCODING_LISTPACK;
556+ pv_->InitRobj (OBJ_HASH, kEncodingListPack , lp);
559557 } else {
560- dict* hmap = dictCreate (&hashDictType);
561-
562- auto cleanup = absl::MakeCleanup ([&] { dictRelease (hmap); });
563-
564- if (len > DICT_HT_INITIAL_SIZE) {
565- if (dictTryExpand (hmap, len) != DICT_OK) {
566- LOG (ERROR) << " OOM in dictTryExpand " << len;
567- ec_ = RdbError (errc::out_of_memory);
568- return ;
569- }
570- }
558+ StringMap* string_map = new StringMap;
571559
560+ auto cleanup = absl::MakeCleanup ([&] { delete string_map; });
561+ string_map->Reserve (len);
572562 for (size_t i = 0 ; i < len; ++i) {
573- sds key = ToSds (ltrace->arr [i * 2 ].rdb_var );
574- sds val = ToSds (ltrace->arr [i * 2 + 1 ].rdb_var );
563+ // ToSV may reference an internal buffer, therefore we can use only before the
564+ // next call to ToSV. To workaround, I copy the key to string.
565+ string key (ToSV (ltrace->arr [i * 2 ].rdb_var ));
566+ string_view val = ToSV (ltrace->arr [i * 2 + 1 ].rdb_var );
575567
576- if (!key || !val )
568+ if (ec_ )
577569 return ;
578570
579- /* Add pair to hash table */
580- int ret = dictAdd (hmap, key, val);
581- if (ret == DICT_ERR) {
571+ if (!string_map->AddOrSkip (key, val)) {
582572 LOG (ERROR) << " Duplicate hash fields detected" ;
583573 ec_ = RdbError (errc::rdb_file_corrupted);
584574 return ;
585575 }
586576 }
587-
588- res = createObject (OBJ_HASH, hmap);
589- res->encoding = OBJ_ENCODING_HT;
577+ pv_->InitRobj (OBJ_HASH, kEncodingStrMap2 , string_map);
590578 std::move (cleanup).Cancel ();
591579 }
592-
593- DCHECK (res);
594- pv_->ImportRObj (res);
595580}
596581
597582void RdbLoaderBase::OpaqueObjLoader::CreateList (const LoadTrace* ltrace) {
@@ -871,13 +856,15 @@ void RdbLoaderBase::OpaqueObjLoader::HandleBlob(string_view blob) {
871856 return ;
872857 }
873858
874- res = createObject (OBJ_HASH, lp);
875- res->encoding = OBJ_ENCODING_LISTPACK;
876-
877- if (lpBytes (lp) > HSetFamily::MaxListPackLen ())
878- hashTypeConvert (res, OBJ_ENCODING_HT);
879- else
880- res->ptr = lpShrinkToFit ((uint8_t *)res->ptr );
859+ if (lpBytes (lp) > HSetFamily::MaxListPackLen ()) {
860+ StringMap* sm = HSetFamily::ConvertToStrMap (lp);
861+ lpFree (lp);
862+ pv_->InitRobj (OBJ_HASH, kEncodingStrMap2 , sm);
863+ } else {
864+ lp = lpShrinkToFit (lp);
865+ pv_->InitRobj (OBJ_HASH, kEncodingListPack , lp);
866+ }
867+ return ;
881868 } else if (rdb_type_ == RDB_TYPE_ZSET_ZIPLIST) {
882869 unsigned char * lp = lpNew (blob.size ());
883870 if (!ziplistPairsConvertAndValidateIntegrity ((uint8_t *)blob.data (), blob.size (), &lp)) {
0 commit comments