feat: support RDB_TYPE_HASH_* and related cmds from Redis 7.4 (#970)
This commit is contained in:
parent
efcd939d44
commit
307a284aeb
|
@ -4740,4 +4740,166 @@ var redisCommands = map[string]redisCommand{
|
|||
},
|
||||
},
|
||||
},
|
||||
"HPEXPIREAT": {
|
||||
"HASH",
|
||||
[]keySpec{
|
||||
{
|
||||
"index",
|
||||
1,
|
||||
"",
|
||||
0,
|
||||
"range",
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
},
|
||||
},
|
||||
"HEXPIREAT": {
|
||||
"HASH",
|
||||
[]keySpec{
|
||||
{
|
||||
"index",
|
||||
1,
|
||||
"",
|
||||
0,
|
||||
"range",
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
},
|
||||
},
|
||||
"HEXPIRE": {
|
||||
"HASH",
|
||||
[]keySpec{
|
||||
{
|
||||
"index",
|
||||
1,
|
||||
"",
|
||||
0,
|
||||
"range",
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
},
|
||||
},
|
||||
"HPEXPIRE": {
|
||||
"HASH",
|
||||
[]keySpec{
|
||||
{
|
||||
"index",
|
||||
1,
|
||||
"",
|
||||
0,
|
||||
"range",
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
},
|
||||
},
|
||||
"HPERSIST": {
|
||||
"HASH",
|
||||
[]keySpec{
|
||||
{
|
||||
"index",
|
||||
1,
|
||||
"",
|
||||
0,
|
||||
"range",
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
},
|
||||
},
|
||||
"HEXPIRETIME": {
|
||||
"HASH",
|
||||
[]keySpec{
|
||||
{
|
||||
"index",
|
||||
1,
|
||||
"",
|
||||
0,
|
||||
"range",
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
},
|
||||
},
|
||||
"HPEXPIRETIME": {
|
||||
"HASH",
|
||||
[]keySpec{
|
||||
{
|
||||
"index",
|
||||
1,
|
||||
"",
|
||||
0,
|
||||
"range",
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
},
|
||||
},
|
||||
"HTTL": {
|
||||
"HASH",
|
||||
[]keySpec{
|
||||
{
|
||||
"index",
|
||||
1,
|
||||
"",
|
||||
0,
|
||||
"range",
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
},
|
||||
},
|
||||
"HPTTL": {
|
||||
"HASH",
|
||||
[]keySpec{
|
||||
{
|
||||
"index",
|
||||
1,
|
||||
"",
|
||||
0,
|
||||
"range",
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package types
|
|||
|
||||
import (
|
||||
"io"
|
||||
"strconv"
|
||||
|
||||
"RedisShake/internal/log"
|
||||
"RedisShake/internal/rdb/structure"
|
||||
|
@ -34,6 +35,14 @@ func (o *HashObject) Rewrite() <-chan RedisCmd {
|
|||
o.readHashZiplist()
|
||||
case rdbTypeHashListpack:
|
||||
o.readHashListpack()
|
||||
case rdbTypeHashMetadataPreGa:
|
||||
o.readHashTtl(true)
|
||||
case rdbTypeHashListpackExPre:
|
||||
o.readHashListpackTtl(true)
|
||||
case rdbTypeHashMetadata:
|
||||
o.readHashTtl(false)
|
||||
case rdbTypeHashListpackEx:
|
||||
o.readHashListpackTtl(false)
|
||||
default:
|
||||
log.Panicf("unknown hash type. typeByte=[%d]", o.typeByte)
|
||||
}
|
||||
|
@ -76,3 +85,56 @@ func (o *HashObject) readHashListpack() {
|
|||
o.cmdC <- RedisCmd{"hset", o.key, key, value}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (o *HashObject) readHashListpackTtl(isPre bool) {
|
||||
rd := o.rd
|
||||
if !isPre {
|
||||
// read minExpire
|
||||
_ = int64(structure.ReadUint64(rd))
|
||||
}
|
||||
list := structure.ReadListpack(rd)
|
||||
size := len(list)
|
||||
for i := 0; i < size; i += 3 {
|
||||
key := list[i]
|
||||
value := list[i+1]
|
||||
|
||||
expireAt,err := strconv.ParseInt(list[i+2], 10, 64)
|
||||
if err != nil{
|
||||
log.Panicf("readHashListpackTtl parsing expireAt %s error", list[i])
|
||||
return
|
||||
}
|
||||
o.cmdC <- RedisCmd{"hset", o.key, key, value}
|
||||
if expireAt != 0{
|
||||
o.cmdC <- RedisCmd{"hpexpireat", o.key, strconv.FormatInt(expireAt, 10), "fields", "1", key}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (o *HashObject) readHashTtl(isPre bool){
|
||||
rd := o.rd
|
||||
var minExpire int64
|
||||
if !isPre {
|
||||
minExpire = int64(structure.ReadUint64(rd))
|
||||
log.Debugf("%s minExpire is %d", o.key, minExpire)
|
||||
}
|
||||
|
||||
size := int(structure.ReadLength(rd))
|
||||
for i := 0; i < size; i++ {
|
||||
expireAt := int64(structure.ReadLength(rd))
|
||||
if !isPre{
|
||||
if expireAt != 0{
|
||||
expireAt = expireAt + minExpire - 1
|
||||
}
|
||||
}
|
||||
key := structure.ReadString(rd)
|
||||
value := structure.ReadString(rd)
|
||||
//HPEXPIREAT key unix-time-seconds [NX | XX | GT | LT] FIELDS numfields
|
||||
o.cmdC <- RedisCmd{"hset", o.key, key, value}
|
||||
if expireAt != 0{
|
||||
o.cmdC <- RedisCmd{"hpexpireat", o.key, strconv.FormatInt(expireAt, 10), "fields", "1", key}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -49,6 +49,12 @@ const (
|
|||
rdbTypeSetListpack = 20 // RDB_TYPE_SET_LISTPACK
|
||||
rdbTypeStreamListpacks3 = 21 // RDB_TYPE_STREAM_LISTPACKS_3
|
||||
|
||||
// https://github.com/redis/redis/pull/13391
|
||||
rdbTypeHashMetadataPreGa = 22 // RDB_TYPE_HASH_METADATA_PRE_GA
|
||||
rdbTypeHashListpackExPre = 23 // RDB_TYPE_HASH_LISTPACK_EX_PRE_GA
|
||||
rdbTypeHashMetadata = 24 // RDB_TYPE_HASH_METADATA
|
||||
rdbTypeHashListpackEx = 25 // RDB_TYPE_HASH_LISTPACK_EX
|
||||
|
||||
moduleTypeNameCharSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
|
||||
|
||||
rdbModuleOpcodeEOF = 0 // End of module value.
|
||||
|
@ -85,7 +91,8 @@ func ParseObject(rd io.Reader, typeByte byte, key string) RedisObject {
|
|||
o := new(ZsetObject)
|
||||
o.LoadFromBuffer(rd, key, typeByte)
|
||||
return o
|
||||
case rdbTypeHash, rdbTypeHashZipmap, rdbTypeHashZiplist, rdbTypeHashListpack: // hash
|
||||
case rdbTypeHash, rdbTypeHashZipmap, rdbTypeHashZiplist, rdbTypeHashListpack,
|
||||
rdbTypeHashMetadataPreGa, rdbTypeHashListpackExPre, rdbTypeHashMetadata, rdbTypeHashListpackEx: // hash
|
||||
o := new(HashObject)
|
||||
o.LoadFromBuffer(rd, key, typeByte)
|
||||
return o
|
||||
|
|
Loading…
Reference in New Issue