diff --git a/.gitignore b/.gitignore index 295a048..4894675 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ .vscode/ lib build +*.DS_STORE diff --git a/CMDDOC-CN.md b/CMDDOC-CN.md index eb04a53..2e61390 100644 --- a/CMDDOC-CN.md +++ b/CMDDOC-CN.md @@ -7,7 +7,7 @@ 语法及复杂度: -> EXHSET key field value [EX time] [EXAT time] [PX time] [PXAT time] [NX/XX] [VER/ABS/GT version] [KEEPTTL] +> EXHSET key field value [EX time] [EXAT time] [PX time] [PXAT time] [NX/XX] [VER/ABS/GT version] [KEEPTTL] > 时间复杂度:O(1) @@ -22,22 +22,22 @@ 参数: -> key: 用于查找该TairHash的键 -> field: TairHash中的一个元素 -> value: TairHash中的一个元素对应的值 +> key: 用于查找该TairHash的键 +> field: TairHash中的一个元素 +> value: TairHash中的一个元素对应的值 > EX: 指定field的相对过期时间,单位为秒,0表示立刻过期 > EXAT: 指定field的绝对过期时间,单位为秒,0表示立刻过期 > PX: 指定field的相对过期时间,单位为毫秒,0表示立刻过期 > PXAT: 指定field的绝对过期时间,单位为毫秒 ,0表示立刻过期 -> NX/XX: NX表示当要插入的field不存在的时候才允许插入,XX表示只有当field存在的时候才允许插入 -> VER/ABS/GT: VER表示只有指定的版本和field当前的版本一致时才允许设置,如果VER指定的版本为0则表示不进行版本检查,ABS表示无论field当前的版本是多少都强制设置并修改版本号,GT表示只有指定的版本大于当前版本时才允许设置,ABS和GT指定的版本号不能为0 +> NX/XX: NX表示当要插入的field不存在的时候才允许插入,XX表示只有当field存在的时候才允许插入 +> VER/ABS/GT: VER表示只有指定的版本和field当前的版本一致时才允许设置,如果VER指定的版本为0则表示不进行版本检查,ABS表示无论field当前的版本是多少都强制设置并修改版本号,GT表示只有指定的版本大于当前版本时才允许设置,ABS和GT指定的版本号不能为0 > KEEPTTL: 当未指定EX/EXAT/PX/PXAT时保留field的过期时间 返回值: -> 成功:新创建field并成功为它设置值时,命令返回1,如果field已经存在并且成功覆盖旧值,那么命令返回0 ;如果指定了XX且field不存在则返回-1,如果指定了NX且field已经存在返回-1;如果指定了VER且版本和当前版本不匹配则返回异常信息"ERR update version is stale" -> 失败:返回相应异常信息 +> 成功:新创建field并成功为它设置值时,命令返回1,如果field已经存在并且成功覆盖旧值,那么命令返回0 ;如果指定了XX且field不存在则返回-1,如果指定了NX且field已经存在返回-1;如果指定了VER且版本和当前版本不匹配则返回异常信息"ERR update version is stale" +> 失败:返回相应异常信息 @@ -47,7 +47,7 @@ 语法及复杂度: -> EXHGET key field +> EXHGET key field > 时间复杂度:O(1) @@ -55,23 +55,23 @@ 命令描述: -> 获取key指定的TairHash一个field的值,如果TairHash不存在或者field不存在,则返回nil +> 获取key指定的TairHash一个field的值,如果TairHash不存在或者field不存在,则返回nil 参数: -> key: 用于查找该TairHash的键 -> field: +> key: 用于查找该TairHash的键 +> field: 返回值: -> 成功:当field存在时返回其对应的值,当TairHash不存在或者field不存在时返回nil -> 失败:返回相应异常信息 +> 成功:当field存在时返回其对应的值,当TairHash不存在或者field不存在时返回nil +> 失败:返回相应异常信息 @@ -81,32 +81,32 @@ 语法及复杂度: -> EXHMSET key field value [field value...] -> 时间复杂度:O(n) +> EXHMSET key field value [field value...] +> 时间复杂度:O(n) 命令描述: -> 同时向key指定的TairHash中插入多个field,如果TairHash不存在则自动创建一个,如果field已经存在则覆盖其值 +> 同时向key指定的TairHash中插入多个field,如果TairHash不存在则自动创建一个,如果field已经存在则覆盖其值 参数: - -> key: 用于查找该TairHash的键 -> field: TairHash中的一个元素 -> value: TairHash中的一个元素对应的值 + +> key: 用于查找该TairHash的键 +> field: TairHash中的一个元素 +> value: TairHash中的一个元素对应的值 返回值: -> 成功:返回OK -> 失败:返回相应异常信息 +> 成功:返回OK +> 失败:返回相应异常信息 @@ -116,8 +116,8 @@ 语法及复杂度: -> EXHPEXPIREAT key field milliseconds-timestamp [VER/ABS/GT version]  -> 时间复杂度:O(1) +> EXHPEXPIREAT key field milliseconds-timestamp [VER/ABS/GT version]  +> 时间复杂度:O(1) @@ -131,17 +131,17 @@ 参数: -> key: 用于查找该TairHash的键 -> field: TairHash中的一个元素 -> milliseconds-timestamp: 以毫秒为单位的时间戳,0表示立刻过期 +> key: 用于查找该TairHash的键 +> field: TairHash中的一个元素 +> milliseconds-timestamp: 以毫秒为单位的时间戳,0表示立刻过期 > VER/ABS/GT: VER表示只有指定的版本和field当前的版本一致时才允许设置,如果VER指定的版本为0则表示不进行版本检查,ABS表示无论field当前的版本是多少都强制设置并修改版本号,GT表示只有指定的版本大于当前版本时才允许设置,ABS和GT指定的版本号不能为0 返回值: -> 成功:当field存在时返回1,当field不存在时返回0 -> 失败:当版本校验失败时返回update version is stale错误,其他错误返回相应异常信息 +> 成功:当field存在时返回1,当field不存在时返回0 +> 失败:当版本校验失败时返回update version is stale错误,其他错误返回相应异常信息 @@ -151,8 +151,8 @@ 语法及复杂度: -> EXHPEXPIRE key field milliseconds [VER/ABS/GT version] -> 时间复杂度:O(1) +> EXHPEXPIRE key field milliseconds [VER/ABS/GT version] +> 时间复杂度:O(1) @@ -164,17 +164,17 @@ 参数: -> key: 用于查找该TairHash的键 -> field: TairHash中的一个元素 -> milliseconds: 以毫秒为单位的过期时间,0表示立刻过期 +> key: 用于查找该TairHash的键 +> field: TairHash中的一个元素 +> milliseconds: 以毫秒为单位的过期时间,0表示立刻过期 > VER/ABS/GT: VER表示只有指定的版本和field当前的版本一致时才允许设置,如果VER指定的版本为0则表示不进行版本检查,ABS表示无论field当前的版本是多少都强制设置并修改版本号,GT表示只有指定的版本大于当前版本时才允许设置,ABS和GT指定的版本号不能为0 返回值: -> 成功:当field存在时返回1,当field不存在时返回0 -> 失败:当版本校验失败时返回update version is stale错误,其他错误返回相应异常信息 +> 成功:当field存在时返回1,当field不存在时返回0 +> 失败:当版本校验失败时返回update version is stale错误,其他错误返回相应异常信息 @@ -184,8 +184,8 @@ 语法及复杂度: -> EXHEXPIREAT key field timestamp [VER/ABS/GT version] -> 时间复杂度:O(1) +> EXHEXPIREAT key field timestamp [VER/ABS/GT version] +> 时间复杂度:O(1) @@ -197,9 +197,9 @@ 参数: -> key: 用于查找该TairHash的键 -> field: TairHash中的一个元素 -> timestamp: 以秒为单位的时间戳,0表示立刻过期 +> key: 用于查找该TairHash的键 +> field: TairHash中的一个元素 +> timestamp: 以秒为单位的时间戳,0表示立刻过期 > VER/ABS/GT: VER表示只有指定的版本和field当前的版本一致时才允许设置,如果VER指定的版本为0则表示不进行版本检查,ABS表示无论field当前的版本是多少都强制设置并修改版本号,GT表示只有指定的版本大于当前版本时才允许设置,ABS和GT指定的版本号不能为0 @@ -207,8 +207,8 @@ 返回值: -> 成功:当field存在时返回1,当field不存在时返回0 -> 失败:当版本校验失败时返回update version is stale错误,其他错误返回相应异常信息 +> 成功:当field存在时返回1,当field不存在时返回0 +> 失败:当版本校验失败时返回update version is stale错误,其他错误返回相应异常信息 @@ -218,8 +218,8 @@ 语法及复杂度: -> EXHEXPIRE key field seconds [VER/ABS/GT version] -> 时间复杂度:O(1) +> EXHEXPIRE key field seconds [VER/ABS/GT version] +> 时间复杂度:O(1) @@ -233,9 +233,9 @@ 参数: -> key: 用于查找该TairHash的键 -> field: TairHash中的一个元素 -> seconds: 以秒为单位的过期时间,0表示立刻过期 +> key: 用于查找该TairHash的键 +> field: TairHash中的一个元素 +> seconds: 以秒为单位的过期时间,0表示立刻过期 > VER/ABS/GT: VER表示只有指定的版本和field当前的版本一致时才允许设置,如果VER指定的版本为0则表示不进行版本检查,ABS表示无论field当前的版本是多少都强制设置并修改版本号,GT表示只有指定的版本大于当前版本时才允许设置,ABS和GT指定的版本号不能为0 @@ -243,8 +243,8 @@ 返回值: -> 成功:当field存在时返回1,当field不存在时返回0 -> 失败:当版本校验失败时返回update version is stale错误,其他错误返回相应异常信息 +> 成功:当field存在时返回1,当field不存在时返回0 +> 失败:当版本校验失败时返回update version is stale错误,其他错误返回相应异常信息 #### EXHPERSIST @@ -253,7 +253,7 @@ > EXHEXPIRE key field -> 时间复杂度:O(1) +> 时间复杂度:O(1) @@ -267,8 +267,8 @@ 参数: -> key: 用于查找该TairHash的键 -> field: TairHash中的一个元素 +> key: 用于查找该TairHash的键 +> field: TairHash中的一个元素 @@ -286,31 +286,31 @@ 语法及复杂度: -> EXHPTTL key field -> 时间复杂度:O(1) +> EXHPTTL key field +> 时间复杂度:O(1) 命令描述: -> 查看key指定的TairHash中一个field的剩余过期时间,单位为毫秒 +> 查看key指定的TairHash中一个field的剩余过期时间,单位为毫秒 参数: -> key: 用于查找该TairHash的键 -> field: TairHash中的一个元素 +> key: 用于查找该TairHash的键 +> field: TairHash中的一个元素 返回值: -> 成功:当TairHash或者field不存在时返回-2,当field存在但是没有设置过期时间时返回-1,当field存在且设置过期时间时时返回对应过期时间,单位为毫秒 -> 失败:返回相应异常信息 +> 成功:当TairHash或者field不存在时返回-2,当field存在但是没有设置过期时间时返回-1,当field存在且设置过期时间时时返回对应过期时间,单位为毫秒 +> 失败:返回相应异常信息 @@ -320,31 +320,31 @@ 语法及复杂度: -> EXHTTL key field -> 时间复杂度:O(1) +> EXHTTL key field +> 时间复杂度:O(1) 命令描述: -> 查看key指定的TairHash中一个field的剩余过期时间,单位为秒 +> 查看key指定的TairHash中一个field的剩余过期时间,单位为秒 参数: -> key: 用于查找该TairHash的键 -> field: TairHash中的一个元素 - +> key: 用于查找该TairHash的键 +> field: TairHash中的一个元素 + 返回值: -> 成功:当TairHash或者field不存在时返回-2,当field存在但是没有设置过期时间时返回-1,当field存在且设置过期时间时时返回对应过期时间,单位为秒 -> 失败:返回相应异常信息 +> 成功:当TairHash或者field不存在时返回-2,当field存在但是没有设置过期时间时返回-1,当field存在且设置过期时间时时返回对应过期时间,单位为秒 +> 失败:返回相应异常信息 @@ -354,31 +354,31 @@ 语法及复杂度: -> EXHVER key field -> 时间复杂度:O(1) +> EXHVER key field +> 时间复杂度:O(1) 命令描述: -> 查看key指定的TairHash中一个field的当前版本号 +> 查看key指定的TairHash中一个field的当前版本号 参数: -> key: 用于查找该TairHash的键 -> field: TairHash中的一个元素 +> key: 用于查找该TairHash的键 +> field: TairHash中的一个元素 返回值: -> 成功:当TairHash不存在时返回-1,当field不存在时返回-2,否则返回field版本号 -> 失败:返回相应异常信息 +> 成功:当TairHash不存在时返回-1,当field不存在时返回-2,否则返回field版本号 +> 失败:返回相应异常信息 @@ -388,31 +388,31 @@ 语法及复杂度: -> EXHSETVER key field version -> 时间复杂度:O(1) +> EXHSETVER key field version +> 时间复杂度:O(1) 命令描述: -> 设置key指定的TairHash中一个field的版本号 +> 设置key指定的TairHash中一个field的版本号 参数: -> key: 用于查找该TairHash的键 -> field: TairHash中的一个元素 +> key: 用于查找该TairHash的键 +> field: TairHash中的一个元素 返回值: -> 成功:当TairHash或者field不存在则返回0,否则返回1 -> 失败:返回相应异常信息 +> 成功:当TairHash或者field不存在则返回0,否则返回1 +> 失败:返回相应异常信息 @@ -422,15 +422,15 @@ 语法及复杂度: -> EXHINCRBY key field value [EX time] [EXAT time] [PX time] [PXAT time] [VER/ABS/GT version] [MIN minval] [MAX maxval] [KEEPTTL] -> 时间复杂度:O(1) +> EXHINCRBY key field value [EX time] [EXAT time] [PX time] [PXAT time] [VER/ABS/GT version] [MIN minval] [MAX maxval] [KEEPTTL] +> 时间复杂度:O(1) 命令描述: -> 将key指定的TairHash中一个field的值加上整数value。如果TairHash不存在则自动新创建一个,如果指定的field不存在,则在加之前先将field的值初始化为0。同时还可以使用EX/EXAT/PX/PXAT为field设置过期时间。 +> 将key指定的TairHash中一个field的值加上整数value。如果TairHash不存在则自动新创建一个,如果指定的field不存在,则在加之前先将field的值初始化为0。同时还可以使用EX/EXAT/PX/PXAT为field设置过期时间。 > 如果指定了VER参数,则VER所携带的版本号必须和field当前版本号一致才可以设置成功,或者如果VER参数所携带的版本号为0,则不进行版本校验。ABS参数用于强制给field设置版本号,而不管field当前的版本号,总是可以设置成功,同时将field当前版本号设置为ABS指定的版本号,GT表示只有指定的版本大于当前版本时才允许设置,ABS和GT指定的版本号不能为0,MIN/MAX用户给field提供一个边界,只有本次incr操作后field的值还在此边界时incr才会被执行,否则返回overflow的错误 @@ -438,9 +438,9 @@ 参数: -> key: 用于查找该TairHash的键 -> field: TairHash中的一个元素 -> value: field对应的值 +> key: 用于查找该TairHash的键 +> field: TairHash中的一个元素 +> value: field对应的值 > EX: 指定field的相对过期时间,单位为秒 ,0表示立刻过期 > EXAT: 指定field的绝对过期时间,单位为秒 ,0表示立刻过期 > PX: 指定field的相对过期时间,单位为毫秒,0表示立刻过期 @@ -452,8 +452,8 @@ 返回值: -> 成功:返回相加之后的值 -> 失败:当版本校验失败时返回update version is stale错误,其他错误返回相应异常信息(如原来的field值不是浮点型) +> 成功:返回相加之后的值 +> 失败:当版本校验失败时返回update version is stale错误,其他错误返回相应异常信息(如原来的field值不是浮点型) @@ -463,15 +463,15 @@ 语法及复杂度: -> EXHINCRBYFLOAT key field value [EX time] [EXAT time] [PX time] [PXAT time] [VER/ABS/GT version] [MIN minval] [MAX maxval] [KEEPTTL] -> 时间复杂度:O(1) +> EXHINCRBYFLOAT key field value [EX time] [EXAT time] [PX time] [PXAT time] [VER/ABS/GT version] [MIN minval] [MAX maxval] [KEEPTTL] +> 时间复杂度:O(1) 命令描述: -> 将key指定的TairHash中一个field的值加上浮点型value。如果TairHash不存在则自动新创建一个,如果指定的field不存在,则在加之前先将field的值初始化为0。同时还可以使用EX/EXAT/PX/PXAT为field设置过期时间。 +> 将key指定的TairHash中一个field的值加上浮点型value。如果TairHash不存在则自动新创建一个,如果指定的field不存在,则在加之前先将field的值初始化为0。同时还可以使用EX/EXAT/PX/PXAT为field设置过期时间。 > 如果指定了VER参数,则VER所携带的版本号必须和field当前版本号一致才可以设置成功,或者如果VER参数所携带的版本号为0,则不进行版本校验。ABS参数用于强制给field设置版本号,而不管field当前的版本号,总是可以设置成功,同时将field当前版本号设置为ABS指定的版本号,GT表示只有指定的版本大于当前版本时才允许设置,ABS和GT指定的版本号不能为0,MIN/MAX用户给field提供一个边界,只有本次incr操作后field的值还在此边界时incr才会被执行,否则返回overflow的错误 @@ -479,9 +479,9 @@ 参数: -> key: 用于查找该TairHash的键 -> field: TairHash中的一个元素 -> value: field对应的值 +> key: 用于查找该TairHash的键 +> field: TairHash中的一个元素 +> value: field对应的值 > EX: 指定field的相对过期时间,单位为秒,0表示立刻过期 > EXAT: 指定field的绝对过期时间,单位为秒,0表示立刻过期 > PX: 指定field的相对过期时间,单位为毫秒,0表示立刻过期 @@ -493,8 +493,8 @@ 返回值: -> 成功:返回相加之后的值 -> 失败:当版本校验失败时返回update version is stale错误,其他错误返回相应异常信息(如原来的field值不是浮点型) +> 成功:返回相加之后的值 +> 失败:当版本校验失败时返回update version is stale错误,其他错误返回相应异常信息(如原来的field值不是浮点型) @@ -504,31 +504,31 @@ 语法及复杂度: -> EXHGETWITHVER key field -> 时间复杂度:O(1) +> EXHGETWITHVER key field +> 时间复杂度:O(1) 命令描述: -> 同时获取key指定的TairHash一个field的值和版本,如果TairHash不存在或者field不存在,则返回nil +> 同时获取key指定的TairHash一个field的值和版本,如果TairHash不存在或者field不存在,则返回nil 参数: -> key: 用于查找该TairHash的键 -> field: TairHash中的一个元素 +> key: 用于查找该TairHash的键 +> field: TairHash中的一个元素 返回值: -> 成功:如果TairHash不存在或者field不存在,则返回nil,否则返回field对应的值和版本 -> 失败:返回相应异常信息 +> 成功:如果TairHash不存在或者field不存在,则返回nil,否则返回field对应的值和版本 +> 失败:返回相应异常信息 @@ -538,31 +538,31 @@ 语法及复杂度: -> EXHMGET key field [field ...] -> 时间复杂度:O(n) +> EXHMGET key field [field ...] +> 时间复杂度:O(n) 命令描述: -> 同时获取key指定的TairHash多个field的值,如果TairHash不存在或者field不存在,则返回nil +> 同时获取key指定的TairHash多个field的值,如果TairHash不存在或者field不存在,则返回nil 参数: -> key: 用于查找该TairHash的键 -> field: TairHash中的一个元素 +> key: 用于查找该TairHash的键 +> field: TairHash中的一个元素 返回值: -> 成功:返回一个数组,数组的每一个元素对应一个field, 如果TairHash不存在或者field不存在,则为nil,否则为field对应的值 -> 失败:返回相应异常信息 +> 成功:返回一个数组,数组的每一个元素对应一个field, 如果TairHash不存在或者field不存在,则为nil,否则为field对应的值 +> 失败:返回相应异常信息 @@ -572,8 +572,8 @@ 语法及复杂度: -> EXHMGETWITHVER key field [field ...] -> 时间复杂度:O(n) +> EXHMGETWITHVER key field [field ...] +> 时间复杂度:O(n) @@ -587,16 +587,16 @@ 参数: -> key: 用于查找该TairHash的键 -> field: TairHash中的一个元素 +> key: 用于查找该TairHash的键 +> field: TairHash中的一个元素 返回值: -> 成功:返回一个数组,数组的每一个元素对应一个field, 如果TairHash不存在或者field不存在,则为nil,否则为field对应的值和版本 -> 失败:返回相应异常信息 +> 成功:返回一个数组,数组的每一个元素对应一个field, 如果TairHash不存在或者field不存在,则为nil,否则为field对应的值和版本 +> 失败:返回相应异常信息 @@ -606,8 +606,8 @@ 语法及复杂度: -> EXHDEL key field [field...] -> 时间复杂度:O(1) +> EXHDEL key field [field...] +> 时间复杂度:O(1) @@ -621,16 +621,16 @@ 参数: -> key: 用于查找该TairHash的键 -> field: TairHash中的一个元素 +> key: 用于查找该TairHash的键 +> field: TairHash中的一个元素 返回值: -> 成功:如果TairHash不存则返回0 ,成功怎返回成功删除的filed的个数 -> 失败:返回相应异常信息 +> 成功:如果TairHash不存则返回0 ,成功怎返回成功删除的filed的个数 +> 失败:返回相应异常信息 @@ -640,30 +640,30 @@ 语法及复杂度: -> EXHLEN key [noexp] -> 时间复杂度:不是noexp选项时是O(1),带noexp选项时是O(N) +> EXHLEN key [noexp] +> 时间复杂度:不是noexp选项时是O(1),带noexp选项时是O(N) 命令描述: -> 获取key指定的TairHash中field的个数,该命令默认不会触发对过期field的被动淘汰,也不会将其过滤掉,所以结果中可能包含已经过期但还未被删除的field。如果只想返回当前没有过期的field个数,那么可以最后带一个noexp参数,注意,带有该参数时,exhlen的RT将受到exhash大小的影响(因为要循环遍历),同时exhlen不会触发对field的淘汰,它只是把过期的field过滤了一下而已 +> 获取key指定的TairHash中field的个数,该命令默认不会触发对过期field的被动淘汰,也不会将其过滤掉,所以结果中可能包含已经过期但还未被删除的field。如果只想返回当前没有过期的field个数,那么可以最后带一个noexp参数,注意,带有该参数时,exhlen的RT将受到exhash大小的影响(因为要循环遍历),同时exhlen不会触发对field的淘汰,它只是把过期的field过滤了一下而已 参数: -> key: 用于查找该TairHash的键 +> key: 用于查找该TairHash的键 返回值: -> 成功:如果TairHash不存在或者field不存在则返回0 ,成功删除返回TairHash中field个数 -> 失败:返回相应异常信息 +> 成功:如果TairHash不存在或者field不存在则返回0 ,成功删除返回TairHash中field个数 +> 失败:返回相应异常信息 @@ -673,30 +673,30 @@ 语法及复杂度: -> EXHEXISTS key field -> 时间复杂度:O(1) +> EXHEXISTS key field +> 时间复杂度:O(1) 命令描述: -> 查询key指定的TairHash中是否存在对应的field +> 查询key指定的TairHash中是否存在对应的field 参数: -> key: 用于查找该TairHash的键 -> field: TairHash中的一个元素 +> key: 用于查找该TairHash的键 +> field: TairHash中的一个元素 返回值: -> 成功:如果TairHash不存在或者field不存在则返回0 ,如果field存在则返回1 +> 成功:如果TairHash不存在或者field不存在则返回0 ,如果field存在则返回1 > 失败:返回相应异常信息 @@ -707,8 +707,8 @@ 语法及复杂度: -> EXHSTRLEN key field -> 时间复杂度:O(1) +> EXHSTRLEN key field +> 时间复杂度:O(1) @@ -722,16 +722,16 @@ 参数: -> key: 用于查找该TairHash的键 -> field: TairHash中的一个元素 +> key: 用于查找该TairHash的键 +> field: TairHash中的一个元素 返回值: -> 成功:如果TairHash不存在或者field不存在则返回0 ,否则返回field对应值的长度 -> 失败:返回相应异常信息 +> 成功:如果TairHash不存在或者field不存在则返回0 ,否则返回field对应值的长度 +> 失败:返回相应异常信息 @@ -741,30 +741,30 @@ 语法及复杂度: -> EXHKEYS key -> 时间复杂度:O(n) +> EXHKEYS key +> 时间复杂度:O(n) 命令描述: -> 获取key指定的TairHash中所有field的键 +> 获取key指定的TairHash中所有field的键 参数: -> key: 用于查找该TairHash的键 +> key: 用于查找该TairHash的键 返回值: -> 成功:返回一个数组,数组的每一位对应TairHash中的每一个field,如果TairHash不存则返回空的数组 -> 失败:返回相应异常信息 +> 成功:返回一个数组,数组的每一位对应TairHash中的每一个field,如果TairHash不存则返回空的数组 +> 失败:返回相应异常信息 @@ -774,30 +774,30 @@ 语法及复杂度: -> EXHVALS key -> 时间复杂度:O(n) +> EXHVALS key +> 时间复杂度:O(n) 命令描述: -> 获取key指定的TairHash中所有field的值 +> 获取key指定的TairHash中所有field的值 参数: -> key: 用于查找该TairHash的键 +> key: 用于查找该TairHash的键 返回值: -> 成功:返回一个数组,数组的每一位对应TairHash中的每一个field的值,如果TairHash不存则返回空的数组 -> 失败:返回相应异常信息 +> 成功:返回一个数组,数组的每一位对应TairHash中的每一个field的值,如果TairHash不存则返回空的数组 +> 失败:返回相应异常信息 @@ -807,15 +807,15 @@ 语法及复杂度: -> EXHGETALL key -> 时间复杂度:O(n) +> EXHGETALL key +> 时间复杂度:O(n) 命令描述: -> 获取key指定的TairHash中所有field的键值对 +> 获取key指定的TairHash中所有field的键值对 @@ -829,8 +829,41 @@ 返回值: -> 成功:返回一个数组,数组的每一位对应TairHash中的每一个field的键值对,如果TairHash不存则返回空的数组 -> 失败:返回相应异常信息 +> 成功:返回一个数组,数组的每一位对应TairHash中的每一个field的键值对,如果TairHash不存则返回空的数组 +> 失败:返回相应异常信息 + + + +#### EXHGETALLWITHVER + + +语法及复杂度: + + +> EXHGETALLWITHVER key +> 时间复杂度:O(n) + + + +命令描述: + + +> 获取key指定的TairHash中所有field的键值对和版本 + + + +参数: + + +> key: 用于查找该TairHash的键 + + + +返回值: + + +> 成功:返回一个数组,数组的每一位对应TairHash中的每一个field的键值对和版本,如果TairHash不存则返回空的数组 +> 失败:返回相应异常信息 @@ -840,8 +873,8 @@ 语法及复杂度: -> EXHSCAN key cursor [MATCH pattern] [COUNT count] -> 时间复杂度:O(1)、O(N) +> EXHSCAN key cursor [MATCH pattern] [COUNT count] +> 时间复杂度:O(1)、O(N) @@ -855,23 +888,23 @@ 参数: -> key: 用于查找该TairHash的键 -> cursor: 扫描的游标,从0开始,每次扫描后会返回下一次扫描的cursor,直到返回0表示扫描结束 -> MATCH: 用于对扫描结果进行过滤的规则 -> COUNT: 用于规定单次扫描field的个数,注意,COUNT仅表示每次扫描TairHash的feild的个数,不代表最终一定会返回COUNT个field结果集,结果集的大小还要根据TairHash中当前field个数和是否指定MATCH进行过滤而定。COUNT默认值为10 +> key: 用于查找该TairHash的键 +> cursor: 扫描的游标,从0开始,每次扫描后会返回下一次扫描的cursor,直到返回0表示扫描结束 +> MATCH: 用于对扫描结果进行过滤的规则 +> COUNT: 用于规定单次扫描field的个数,注意,COUNT仅表示每次扫描TairHash的feild的个数,不代表最终一定会返回COUNT个field结果集,结果集的大小还要根据TairHash中当前field个数和是否指定MATCH进行过滤而定。COUNT默认值为10 返回值: -> 成功:返回一个具有两个元素的数组,数组第一个元素是下一次扫描需要使用的cursor,为0表示整个扫描结束。第二个数组元素还是一个数组,数组包含了所有本次被迭代的field/value。如果扫描到一个空的TairHash或者是TairHash不存在,那么这两个数组元素都为空。 -> 失败:返回相应异常信息 +> 成功:返回一个具有两个元素的数组,数组第一个元素是下一次扫描需要使用的cursor,为0表示整个扫描结束。第二个数组元素还是一个数组,数组包含了所有本次被迭代的field/value。如果扫描到一个空的TairHash或者是TairHash不存在,那么这两个数组元素都为空。 +> 失败:返回相应异常信息 **使用示例:** -1、如何使用渐进式扫描整个TairHash: +1、如何使用渐进式扫描整个TairHash: ``` 127.0.0.1:6379> exhmset exhashkey field1 val1 field2 val2 field3 val3 field4 val4 field5 val5 field6 val6 field7 val7 field8 val8 field9 val9 OK @@ -905,7 +938,7 @@ OK 2) "val1" ``` -2、如何使用MATCH对结果集进行过滤 +2、如何使用MATCH对结果集进行过滤 精确匹配: diff --git a/CMDDOC.md b/CMDDOC.md index bd49c46..24c1fc2 100644 --- a/CMDDOC.md +++ b/CMDDOC.md @@ -6,26 +6,26 @@ Grammar and complexity: -> EXHSET key field value [EX time] [EXAT time] [PX time] [PXAT time] [NX/XX] [VER/ABS/GT version] [KEEPTTL] -> time complexity:O(1) +> EXHSET key field value [EX time] [EXAT time] [PX time] [PXAT time] [NX/XX] [VER/ABS/GT version] [KEEPTTL] +> time complexity:O(1) -Command Description: -> Insert a field into the TairHash specified by the key. If TairHash does not exist, it will automatically create one, and if the field already exists, its value will be overwritten. When inserting, you can use EX/EXAT/PX/PXAT to set the expiration time for the field. When the field expires, it will be deleted actively (active expire) or passive (passivity expire). If the NX option is specified, the insertion will be successful only when the field does not exist. Similarly, if the XX option is specified, the insertion will be successful only when the field exists. If the VER parameter is specified, the version number carried by the VER must be consistent with the current version number of the field before it can be inserted successfully. If the field does not exist or the current version of the field is 0, no check is performed, and the insertion can always be successful. The ABS parameter is used to forcibly set the version number for the field, regardless of the current version number of the field, it can always be inserted successfully, GT means that the setting is only allowed when the specified version is greater than the current version of the field, the version specified by GT and ABS cannot be 0. This command will trigger the passive elimination check of the field +Command Description: +> Insert a field into the TairHash specified by the key. If TairHash does not exist, it will automatically create one, and if the field already exists, its value will be overwritten. When inserting, you can use EX/EXAT/PX/PXAT to set the expiration time for the field. When the field expires, it will be deleted actively (active expire) or passive (passivity expire). If the NX option is specified, the insertion will be successful only when the field does not exist. Similarly, if the XX option is specified, the insertion will be successful only when the field exists. If the VER parameter is specified, the version number carried by the VER must be consistent with the current version number of the field before it can be inserted successfully. If the field does not exist or the current version of the field is 0, no check is performed, and the insertion can always be successful. The ABS parameter is used to forcibly set the version number for the field, regardless of the current version number of the field, it can always be inserted successfully, GT means that the setting is only allowed when the specified version is greater than the current version of the field, the version specified by GT and ABS cannot be 0. This command will trigger the passive elimination check of the field parameter: -> key: The key used to find the TairHash -> field: An element in TairHash -> value: The value corresponding to an element in TairHash -> EX: The relative expiration time of the specified field, in seconds, 0 means expire immediately -> EXAT: Specify the absolute expiration time of the field, in seconds, 0 means expire immediately -> PX: The relative expiration time of the specified field, in milliseconds, 0 means expire immediately -> PXAT: Specify the absolute expiration time of the field, in milliseconds, 0 means expire immediately -> NX/XX: NX means inserting is allowed only when the field to be inserted does not exist, XX means inserting is allowed only when the field exists +> key: The key used to find the TairHash +> field: An element in TairHash +> value: The value corresponding to an element in TairHash +> EX: The relative expiration time of the specified field, in seconds, 0 means expire immediately +> EXAT: Specify the absolute expiration time of the field, in seconds, 0 means expire immediately +> PX: The relative expiration time of the specified field, in milliseconds, 0 means expire immediately +> PXAT: Specify the absolute expiration time of the field, in milliseconds, 0 means expire immediately +> NX/XX: NX means inserting is allowed only when the field to be inserted does not exist, XX means inserting is allowed only when the field exists > VER/ABS/GT: VER means that the setting is allowed only when the specified version is consistent with the current version of the field. If the version specified by VER is 0, it means that no version check will be performed. ABS means that the version number is forced to be set and modified regardless of the current version of the field, GT means that the setting is only allowed when the specified version is greater than the current version of the field, the version specified by GT and ABS cannot be 0. - -> KEEPTTL: Retain the time to live associated with the field. KEEPTTL cannot be used together with EX/EXAT/PX/PXAT + +> KEEPTTL: Retain the time to live associated with the field. KEEPTTL cannot be used together with EX/EXAT/PX/PXAT Return: @@ -37,8 +37,8 @@ Return: Grammar and complexity: -> EXHGET key field -> time complexity:O(1) +> EXHGET key field +> time complexity:O(1) @@ -52,8 +52,8 @@ Command Description: parameter: -> key: The key used to find the TairHash -> field: An element in TairHash +> key: The key used to find the TairHash +> field: An element in TairHash @@ -70,8 +70,8 @@ Return: Grammar and complexity: -> EXHMSET key field value [field value...] -> time complexity:O(n) +> EXHMSET key field value [field value...] +> time complexity:O(n) @@ -84,17 +84,17 @@ Command Description: parameter: - -> key: The key used to find the TairHash -> field: An element in TairHash -> value: The value corresponding to an element in TairHash + +> key: The key used to find the TairHash +> field: An element in TairHash +> value: The value corresponding to an element in TairHash Return: -> Return OK +> Return OK @@ -104,8 +104,8 @@ Return: Grammar and complexity: -> EXHPEXPIREAT key field milliseconds-timestamp [VER/ABS/GT version] -> time complexity: (1) +> EXHPEXPIREAT key field milliseconds-timestamp [VER/ABS/GT version] +> time complexity: (1) @@ -119,16 +119,16 @@ Command Description: Parameter: -> key: The key used to find the TairHash -> field: An element in TairHash -> milliseconds-timestamp: Timestamp in milliseconds, 0 means expire immediately +> key: The key used to find the TairHash +> field: An element in TairHash +> milliseconds-timestamp: Timestamp in milliseconds, 0 means expire immediately > VER/ABS/GT: VER means that the setting is allowed only when the specified version is consistent with the current version of the field. If the version specified by VER is 0, it means that no version check will be performed. ABS means that the version number is forced to be set and modified regardless of the current version of the field, GT means that the setting is only allowed when the specified version is greater than the current version of the field, the version specified by GT and ABS cannot be 0. Return: -> Success: return 1 when the field exists, and return 0 when the field does not exist +> Success: return 1 when the field exists, and return 0 when the field does not exist > When the version verification fails, the update version is stale error is returned @@ -139,24 +139,24 @@ Return: Grammar and complexity: -> EXHPEXPIRE key field milliseconds [VER/ABS/GT version] -> time complexity:O(1) +> EXHPEXPIRE key field milliseconds [VER/ABS/GT version] +> time complexity:O(1) Command Description: -> Set the relative expiration time for a field in the TairHash specified by the key, in milliseconds. When the expiration time is up, the field will be deleted actively. If the field does not exist, return 0 directly. If VER parameter is specified, the version number carried by VER must be consistent with the current version number of the field before it can be set successfully, or if the version number carried by VER parameter is 0, no version verification is performed. ABS parameter is used to force the field to set the version number, regardless of the current version number of the field, it can always be inserted successfully. At the same time, the current version number of the field is set to the version number specified by ABS, GT means that the setting is only allowed when the specified version is greater than the current version of the field, the version specified by GT and ABS cannot be 0. This command will trigger the passive elimination of the field +> Set the relative expiration time for a field in the TairHash specified by the key, in milliseconds. When the expiration time is up, the field will be deleted actively. If the field does not exist, return 0 directly. If VER parameter is specified, the version number carried by VER must be consistent with the current version number of the field before it can be set successfully, or if the version number carried by VER parameter is 0, no version verification is performed. ABS parameter is used to force the field to set the version number, regardless of the current version number of the field, it can always be inserted successfully. At the same time, the current version number of the field is set to the version number specified by ABS, GT means that the setting is only allowed when the specified version is greater than the current version of the field, the version specified by GT and ABS cannot be 0. This command will trigger the passive elimination of the field Parameter: -> key: The key used to find the TairHash -> field: An element in TairHash -> milliseconds: Expiration time in milliseconds, 0 means expire immediately +> key: The key used to find the TairHash +> field: An element in TairHash +> milliseconds: Expiration time in milliseconds, 0 means expire immediately > VER/ABS/GT: VER means that the setting is allowed only when the specified version is consistent with the current version of the field. If the version specified by VER is 0, it means that no version check will be performed. ABS means that the version number is forced to be set and modified regardless of the current version of the field, GT means that the setting is only allowed when the specified version is greater than the current version of the field, the version specified by GT and ABS cannot be 0. @@ -164,8 +164,8 @@ Parameter: Return: -> Return 1 when the field exists, and 0 when the field does not exist -> When the version verification fails, the update version is stale error will be returned +> Return 1 when the field exists, and 0 when the field does not exist +> When the version verification fails, the update version is stale error will be returned @@ -175,22 +175,22 @@ Return: Grammar and complexity: -> EXHEXPIREAT key field timestamp [VER/ABS/GT version] -> time complexity:O(1) +> EXHEXPIREAT key field timestamp [VER/ABS/GT version] +> time complexity:O(1) Command Description: -> Set the absolute expiration time for a field in the TairHash specified by the key, in seconds. When the expiration time expires, the field will be actively deleted. If the field does not exist, return 0 directly. If VER parameter is specified, the version number carried by VER must be consistent with the current version number of the field before it can be set successfully, or if the version number carried by VER parameter is 0, no version verification is performed. ABS parameter is used to force the field to set the version number, regardless of the current version number of the field, it can always be inserted successfully. At the same time, the current version number of the field is set to the version number specified by ABS, GT means that the setting is only allowed when the specified version is greater than the current version of the field, the version specified by GT and ABS cannot be 0. This command will trigger the passive elimination of the field +> Set the absolute expiration time for a field in the TairHash specified by the key, in seconds. When the expiration time expires, the field will be actively deleted. If the field does not exist, return 0 directly. If VER parameter is specified, the version number carried by VER must be consistent with the current version number of the field before it can be set successfully, or if the version number carried by VER parameter is 0, no version verification is performed. ABS parameter is used to force the field to set the version number, regardless of the current version number of the field, it can always be inserted successfully. At the same time, the current version number of the field is set to the version number specified by ABS, GT means that the setting is only allowed when the specified version is greater than the current version of the field, the version specified by GT and ABS cannot be 0. This command will trigger the passive elimination of the field Parameter: -> key: The key used to find the TairHash -> field: An element in TairHash -> timestamp: Timestamp in seconds,0 means expire immediately +> key: The key used to find the TairHash +> field: An element in TairHash +> timestamp: Timestamp in seconds,0 means expire immediately > VER/ABS/GT: VER means that the setting is allowed only when the specified version is consistent with the current version of the field. If the version specified by VER is 0, it means that no version check will be performed. ABS means that the version number is forced to be set and modified regardless of the current version of the field, GT means that the setting is only allowed when the specified version is greater than the current version of the field, the version specified by GT and ABS cannot be 0. @@ -198,8 +198,8 @@ Parameter: Return: -> Return 1 when the field exists, and 0 when the field does not exist -> When the version verification fails, the update version is stale error will be returned, and the corresponding exception information will be returned for other errors. +> Return 1 when the field exists, and 0 when the field does not exist +> When the version verification fails, the update version is stale error will be returned, and the corresponding exception information will be returned for other errors. @@ -209,8 +209,8 @@ Return: Grammar and complexity: -> EXHEXPIRE key field seconds [VER/ABS/GT version] -> time complexity:O(1) +> EXHEXPIRE key field seconds [VER/ABS/GT version] +> time complexity:O(1) @@ -224,9 +224,9 @@ Command Description: Parameter: -> key: The key used to find the TairHash -> field: An element in TairHash -> timestamp: Timestamp in seconds, 0 means expire immediately +> key: The key used to find the TairHash +> field: An element in TairHash +> timestamp: Timestamp in seconds, 0 means expire immediately > VER/ABS/GT: VER means that the setting is allowed only when the specified version is consistent with the current version of the field. If the version specified by VER is 0, it means that no version check will be performed. ABS means that the version number is forced to be set and modified regardless of the current version of the field, GT means that the setting is only allowed when the specified version is greater than the current version of the field, the version specified by GT and ABS cannot be 0. @@ -234,8 +234,8 @@ Parameter: Return: -> Return 1 when the field exists, and 0 when the field does not exist -> When the version verification fails, the update version is stale error will be returned, and the corresponding exception information will be returned for other errors. +> Return 1 when the field exists, and 0 when the field does not exist +> When the version verification fails, the update version is stale error will be returned, and the corresponding exception information will be returned for other errors. #### EXHPERSIST @@ -243,8 +243,8 @@ Return: Grammar and complexity: -> EXHEXPIRE key field -> time complexity:O(1) +> EXHEXPIRE key field +> time complexity:O(1) @@ -258,40 +258,40 @@ Command Description: Parameter: -> key: The key used to find the TairHash -> field: An element in TairHash +> key: The key used to find the TairHash +> field: An element in TairHash Return: -> 1:Successfully removed the expiration setting on the field -> 0:The key or field does not exist, or the field exists but does not have an expiration setting +> 1:Successfully removed the expiration setting on the field +> 0:The key or field does not exist, or the field exists but does not have an expiration setting #### EXHPTTL -Grammar and complexity: +Grammar and complexity: -> EXHPTTL key field -> time complexity:O(1) +> EXHPTTL key field +> time complexity:O(1) Command Description: -> View the remaining expiration time of a field in TaiHash specified by key, in milliseconds +> View the remaining expiration time of a field in TaiHash specified by key, in milliseconds Parameter: -> key: The key used to find the TairHash -> field: An element in TairHash +> key: The key used to find the TairHash +> field: An element in TairHash @@ -308,24 +308,24 @@ Return: Grammar and complexity: -> EXHTTL key field -> time complexity:O(1) +> EXHTTL key field +> time complexity:O(1) Command Description: -> View the remaining expiration time of a field in TaiHash specified by key, in seconds +> View the remaining expiration time of a field in TaiHash specified by key, in seconds Parameter: -> key: The key used to find the TairHash -> field: An element in TairHash - +> key: The key used to find the TairHash +> field: An element in TairHash + Return: @@ -341,23 +341,23 @@ Return: Grammar and complexity: -> EXHVER key field -> time complexity:O(1) +> EXHVER key field +> time complexity:O(1) Command Description: -> View the current version number of a field in TairHash specified by key +> View the current version number of a field in TairHash specified by key Parameter: -> key: The key used to find the TairHash -> field: An element in TairHash +> key: The key used to find the TairHash +> field: An element in TairHash @@ -373,32 +373,32 @@ Return: Grammar and complexity: -> EXHSETVER key field version -> time complexity:O(1) +> EXHSETVER key field version +> time complexity:O(1) Command Description: -> Set the version number of a field in TairHash specified by key +> Set the version number of a field in TairHash specified by key Parameter: -> key: The key used to find the TairHash -> field: An element in TairHash -> version: version number +> key: The key used to find the TairHash +> field: An element in TairHash +> version: version number Return: -> When TairHash or field does not exist, return 0, otherwise return 1 - +> When TairHash or field does not exist, return 0, otherwise return 1 + @@ -408,39 +408,39 @@ Return: Grammar and complexity: -> EXHINCRBY key field value [EX time] [EXAT time] [PX time] [PXAT time] [VER/ABS/GT version] [MIN minval] [MAX maxval] [KEEPTTL] -> time complexity:O(1) +> EXHINCRBY key field value [EX time] [EXAT time] [PX time] [PXAT time] [VER/ABS/GT version] [MIN minval] [MAX maxval] [KEEPTTL] +> time complexity:O(1) Command Description: -> Add the integer value to the value of a field in TairHash specified by key. If TairHash does not exist, it will automatically create a new one. If the specified field does not exist, initialize the value of the field to 0 before adding it. At the same time, you can also use EX/EXAT/PX/PXAT to set the expiration time for the field -> If VER is specified, the version number carried by VER must be consistent with the current version number of the field before it can be set successfully, or if the version number carried by VER parameter is 0, no version verification is performed. ABS parameter is used to forcibly set the version number for the field, regardless of the current version number of the field, it can always be set successfully. At the same time, the current version number of the field is set to the version number specified by ABS, GT means that the setting is only allowed when the specified version is greater than the current version of the field, the version specified by GT and ABS cannot be 0. MIN/MAX users provide a boundary for the field. Incr will be executed only when the value of the field is still on this boundary after this incr operation, otherwise an overflow error will be returned. This command will trigger the passive elimination check of the field +> Add the integer value to the value of a field in TairHash specified by key. If TairHash does not exist, it will automatically create a new one. If the specified field does not exist, initialize the value of the field to 0 before adding it. At the same time, you can also use EX/EXAT/PX/PXAT to set the expiration time for the field +> If VER is specified, the version number carried by VER must be consistent with the current version number of the field before it can be set successfully, or if the version number carried by VER parameter is 0, no version verification is performed. ABS parameter is used to forcibly set the version number for the field, regardless of the current version number of the field, it can always be set successfully. At the same time, the current version number of the field is set to the version number specified by ABS, GT means that the setting is only allowed when the specified version is greater than the current version of the field, the version specified by GT and ABS cannot be 0. MIN/MAX users provide a boundary for the field. Incr will be executed only when the value of the field is still on this boundary after this incr operation, otherwise an overflow error will be returned. This command will trigger the passive elimination check of the field Parameter: -> key: The key used to find the TairHash -> field: An element in TairHash -> value: The value to be increased -> EX: The relative expiration time of the specified field, in seconds, 0 means expire immediately -> EXAT: Specify the absolute expiration time of the field, in seconds, 0 means expire immediately -> PX: The relative expiration time of the specified field, in milliseconds, 0 means expire immediately -> PXAT: Specify the absolute expiration time of the field, in milliseconds, 0 means expire immediately +> key: The key used to find the TairHash +> field: An element in TairHash +> value: The value to be increased +> EX: The relative expiration time of the specified field, in seconds, 0 means expire immediately +> EXAT: Specify the absolute expiration time of the field, in seconds, 0 means expire immediately +> PX: The relative expiration time of the specified field, in milliseconds, 0 means expire immediately +> PXAT: Specify the absolute expiration time of the field, in milliseconds, 0 means expire immediately > VER/ABS/GT: VER means that the setting is allowed only when the specified version is consistent with the current version of the field. If the version specified by VER is 0, it means that no version check will be performed. ABS means that the version number is forced to be set and modified regardless of the current version of the field, GT means that the setting is only allowed when the specified version is greater than the current version of the field, the version specified by GT and ABS cannot be 0. -> MAX/MIN: Specify the boundary, incr will be executed only when the value of the field is still on this boundary after this incr operation,otherwise an overflow error will be returned +> MAX/MIN: Specify the boundary, incr will be executed only when the value of the field is still on this boundary after this incr operation,otherwise an overflow error will be returned > KEEPTTL: Retain the time to live associated with the field. KEEPTTL cannot be used together with EX/EXAT/PX/PXAT Return: -> Return the added value -> When the version verification fails, an update version is stale error is returned +> Return the added value +> When the version verification fails, an update version is stale error is returned @@ -450,37 +450,37 @@ Return: Grammar and complexity: -> EXHINCRBYFLOAT key field value [EX time] [EXAT time] [PX time] [PXAT time] [VER/ABS/GT version] [MIN minval] [MAX maxval] [KEEPTTL] -> time complexity:O(1) +> EXHINCRBYFLOAT key field value [EX time] [EXAT time] [PX time] [PXAT time] [VER/ABS/GT version] [MIN minval] [MAX maxval] [KEEPTTL] +> time complexity:O(1) Command Description: -> Add the floating-point value to the value of a field in TairHash specified by key. If TairHash does not exist, it will automatically create a new one. If the specified field does not exist, initialize the value of the field to 0 before adding it. At the same time, you can also use EX/EXAT/PX/PXAT to set the expiration time for the field -> If VER is specified, the version number carried by VER must be consistent with the current version number of the field before it can be set successfully, or if the version number carried by VER parameter is 0, no version verification is performed. ABS parameter is used to forcibly set the version number for the field, regardless of the current version number of the field, it can always be set successfully. At the same time, the current version number of the field is set to the version number specified by ABS, GT means that the setting is only allowed when the specified version is greater than the current version of the field, the version specified by GT and ABS cannot be 0. MIN/MAX users provide a boundary for the field. Incr will be executed only when the value of the field is still on this boundary after this incr operation, otherwise an overflow error will be returned. This command will trigger the passive elimination check of the field +> Add the floating-point value to the value of a field in TairHash specified by key. If TairHash does not exist, it will automatically create a new one. If the specified field does not exist, initialize the value of the field to 0 before adding it. At the same time, you can also use EX/EXAT/PX/PXAT to set the expiration time for the field +> If VER is specified, the version number carried by VER must be consistent with the current version number of the field before it can be set successfully, or if the version number carried by VER parameter is 0, no version verification is performed. ABS parameter is used to forcibly set the version number for the field, regardless of the current version number of the field, it can always be set successfully. At the same time, the current version number of the field is set to the version number specified by ABS, GT means that the setting is only allowed when the specified version is greater than the current version of the field, the version specified by GT and ABS cannot be 0. MIN/MAX users provide a boundary for the field. Incr will be executed only when the value of the field is still on this boundary after this incr operation, otherwise an overflow error will be returned. This command will trigger the passive elimination check of the field Parameter: -> key: The key used to find the TairHash -> field: An element in TairHash -> value: The value to be increased -> EX: The relative expiration time of the specified field, in seconds, 0 means expire immediately -> EXAT: Specify the absolute expiration time of the field, in seconds, 0 means expire immediately -> PX: The relative expiration time of the specified field, in milliseconds, 0 means expire immediately -> PXAT: Specify the absolute expiration time of the field, in milliseconds, 0 means expire immediately +> key: The key used to find the TairHash +> field: An element in TairHash +> value: The value to be increased +> EX: The relative expiration time of the specified field, in seconds, 0 means expire immediately +> EXAT: Specify the absolute expiration time of the field, in seconds, 0 means expire immediately +> PX: The relative expiration time of the specified field, in milliseconds, 0 means expire immediately +> PXAT: Specify the absolute expiration time of the field, in milliseconds, 0 means expire immediately > VER/ABS/GT: VER means that the setting is allowed only when the specified version is consistent with the current version of the field. If the version specified by VER is 0, it means that no version check will be performed. ABS means that the version number is forced to be set and modified regardless of the current version of the field., GT means that the setting is only allowed when the specified version is greater than the current version of the field, the version specified by GT and ABS cannot be 0. -> MAX/MIN: Specify the boundary, incr will be executed only when the value of the field is still on this boundary after this incr operation,otherwise an overflow error will be returned +> MAX/MIN: Specify the boundary, incr will be executed only when the value of the field is still on this boundary after this incr operation,otherwise an overflow error will be returned > KEEPTTL: Retain the time to live associated with the field. KEEPTTL cannot be used together with EX/EXAT/PX/PXAT Return: -> Return the added value +> Return the added value > When the version verification fails, the update version is stale error is returned, and the corresponding exception information is returned for other errors (for example, the original field value is not a floating point) @@ -491,8 +491,8 @@ Return: Grammar and complexity: -> EXHGETWITHVER key field -> time complexity:O(1) +> EXHGETWITHVER key field +> time complexity:O(1) @@ -506,8 +506,8 @@ Command Description: Parameter: -> key: The key used to find the TairHash -> field: An element in TairHash +> key: The key used to find the TairHash +> field: An element in TairHash @@ -524,8 +524,8 @@ Return: Grammar and complexity: -> EXHMGET key field [field ...] -> time complexity:O(n) +> EXHMGET key field [field ...] +> time complexity:O(n) @@ -539,15 +539,15 @@ Command Description: Parameter: -> key: The key used to find the TairHash -> field: An element in TairHash +> key: The key used to find the TairHash +> field: An element in TairHash Return: -> Returns an array, each element of the array corresponds to a field, if TairHash does not exist or the field does not exist, it is nil, otherwise it is the value corresponding to the field +> Returns an array, each element of the array corresponds to a field, if TairHash does not exist or the field does not exist, it is nil, otherwise it is the value corresponding to the field @@ -557,8 +557,8 @@ Return: Grammar and complexity: -> EXHMGETWITHVER key field [field ...] -> time complexity:O(n) +> EXHMGETWITHVER key field [field ...] +> time complexity:O(n) @@ -572,15 +572,15 @@ Command Description: Parameter: -> key: The key used to find the TairHash -> field: An element in TairHash +> key: The key used to find the TairHash +> field: An element in TairHash Return: -> Returns an array, each element of the array corresponds to a field, if TairHash does not exist or the field does not exist, it is nil, otherwise, the value and version corresponding to the field +> Returns an array, each element of the array corresponds to a field, if TairHash does not exist or the field does not exist, it is nil, otherwise, the value and version corresponding to the field @@ -590,8 +590,8 @@ Return: Grammar and complexity: -> EXHDEL key field [field...] -> time complexity:O(1) +> EXHDEL key field [field...] +> time complexity:O(1) @@ -605,15 +605,15 @@ Command Description: Parameter: -> key: The key used to find the TairHash -> field: An element in TairHash +> key: The key used to find the TairHash +> field: An element in TairHash Return: -> If TairHash does not exist, return 0. How to return the number of files deleted successfully? +> If TairHash does not exist, return 0. How to return the number of files deleted successfully? @@ -623,7 +623,7 @@ Return: Grammar and complexity: -> EXHLEN key [noexp] +> EXHLEN key [noexp] > time complexity:It is O(1) if it is not a noexp option, and O(N) if it is a noexp option @@ -655,8 +655,8 @@ Return: Grammar and complexity: -> EXHEXISTS key field -> time complexity:O(1) +> EXHEXISTS key field +> time complexity:O(1) @@ -670,15 +670,15 @@ Command Description: Parameter: -> key: The key used to find the TairHash -> field: An element in TairHash +> key: The key used to find the TairHash +> field: An element in TairHash Return: -> If TairHash does not exist or the field does not exist, return 0, if the field exists, return 1 +> If TairHash does not exist or the field does not exist, return 0, if the field exists, return 1 @@ -688,8 +688,8 @@ Return: Grammar and complexity: -> EXHSTRLEN key field -> time complexity:O(1) +> EXHSTRLEN key field +> time complexity:O(1) @@ -703,8 +703,8 @@ Command Description: Parameter: -> key: The key used to find the TairHash -> field: An element in TairHash +> key: The key used to find the TairHash +> field: An element in TairHash @@ -721,8 +721,8 @@ Return: Grammar and complexity: -> EXHKEYS key -> time complexity:O(n) +> EXHKEYS key +> time complexity:O(n) @@ -753,8 +753,8 @@ Return: Grammar and complexity: -> EXHVALS key -> time complexity:O(n) +> EXHVALS key +> time complexity:O(n) @@ -785,8 +785,8 @@ Return: Grammar and complexity: -> EXHGETALL key -> time complexity:O(n) +> EXHGETALL key +> time complexity:O(n) @@ -809,45 +809,98 @@ Return: > Returns an array, each bit of the array corresponds to the key-value pair of each field in TairHash, if TairHash does not exist, it returns an empty array +```sh +127.0.0.1:6379> EXHSET k0 f1 1 ABS 2 +(integer) 1 +127.0.0.1:6379> EXHSET k0 f2 2 ABS 1 +(integer) 1 +127.0.0.1:6379> EXHGETALL k0 +1) "f2" +2) "2" +3) "f1" +4) "1" +``` + +#### EXHGETALLWITHVER + + +Grammar and complexity: + + +> EXHGETALLWITHVER key +> time complexity:O(n) + +Command Description: + + +> Get the key-value-version tuples of all fields in TairHash specified by key + + + +Parameter: + + +> key: The key used to find the TairHash + + + +Return: + + +> Returns an array, each bit of the array corresponds to the key-value-version tuple of each field in TairHash, if TairHash does not exist, it returns an empty array + +```sh +127.0.0.1:6379> EXHSET k0 f1 1 ABS 2 +(integer) 1 +127.0.0.1:6379> EXHSET k0 f2 2 ABS 1 +(integer) 1 +127.0.0.1:6379> EXHGETALLWITHVER k0 +1) "f2" +2) "2" +3) (integer) 1 +4) "f1" +5) "1" +6) (integer) 2 +``` #### EXHSCAN Grammar and complexity: - -> EXHSCAN key cursor [MATCH pattern] [COUNT count] -> time complexity:O(1)、O(N) + +> EXHSCAN key cursor [MATCH pattern] [COUNT count] +> time complexity:O(1)、O(N) Command Description: -> Scan the TairHash specified by the key +> Scan the TairHash specified by the key Parameter: -> key: The key used to find the TairHash -> cursor: Scan cursor, starting from 0, after each scan, it will return to the next scan cursor, until it returns 0 to indicate the end of the scan -> MATCH: Rules for filtering scan results -> COUNT: It is used to specify the number of fields in a single scan. Note that COUNT only represents the number of feilds of TairHash scanned each time. It does not mean that COUNT field result sets will be returned in the end. The size of the result set depends on the current fields in TaiHash. The number and whether to specify MATCH for filtering depends. The default value of COUNT is 10 +> key: The key used to find the TairHash +> cursor: Scan cursor, starting from 0, after each scan, it will return to the next scan cursor, until it returns 0 to indicate the end of the scan +> MATCH: Rules for filtering scan results +> COUNT: It is used to specify the number of fields in a single scan. Note that COUNT only represents the number of feilds of TairHash scanned each time. It does not mean that COUNT field result sets will be returned in the end. The size of the result set depends on the current fields in TaiHash. The number and whether to specify MATCH for filtering depends. The default value of COUNT is 10 Return: -> Returns an array with two elements. The first element of the array is the cursor to be used in the next scan, and 0 means the end of the entire scan. The second array element is still an array, and the array contains all the field/values that are iterated this time. If an empty TairHash is found or TairHash does not exist, then both array elements are empty. - +> Returns an array with two elements. The first element of the array is the cursor to be used in the next scan, and 0 means the end of the entire scan. The second array element is still an array, and the array contains all the field/values that are iterated this time. If an empty TairHash is found or TairHash does not exist, then both array elements are empty. + **example:** -1、How to progressively scan the entire TaiHash: +1、How to progressively scan the entire TaiHash: ``` 127.0.0.1:6379> exhmset exhashkey field1 val1 field2 val2 field3 val3 field4 val4 field5 val5 field6 val6 field7 val7 field8 val8 field9 val9 OK diff --git a/CMakeLists.txt b/CMakeLists.txt index f448154..45037a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -W -Wall -g -ggdb -std=c99 -O2 -Wno-strict-a set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(CMAKE_C_VISIBILITY_PRESET hidden) -SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) +SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) option(SORT_MODE "Use two-level sort index to to implement active expire" OFF) diff --git a/Dockerfile b/Dockerfile index e097261..0230bea 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,12 +4,12 @@ ENV TAIRHASH_URL https://github.com/alibaba/TairHash.git RUN set -ex; \ \ BUILD_DEPS=' \ - ca-certificates \ - cmake \ - gcc \ - git \ - g++ \ - make \ + ca-certificates \ + cmake \ + gcc \ + git \ + g++ \ + make \ '; \ apt-get update; \ apt-get install -y $BUILD_DEPS --no-install-recommends; \ diff --git a/README-CN.md b/README-CN.md index 8743a95..5da68eb 100755 --- a/README-CN.md +++ b/README-CN.md @@ -22,7 +22,7 @@ - 支持field过期删除事件通知(基于pubsub) ## 数据结构 -![avatar](imgs/tairhash_index2.png) +![avatar](imgs/tairhash_index2.png) ## 主动过期 ### SORT_MODE(排序模式): @@ -37,7 +37,7 @@ - 排序中所有的key和field都是指针引用,无内存拷贝,无内存膨胀问题 **支持的redis版本**: redis >= 7.0 -**优点**:过期淘汰效率比较高 +**优点**:过期淘汰效率比较高 **缺点**:由于SORT_MODE实现依赖`unlink2`回调函数(见这个[PR](https://github.com/redis/redis/pull/8999)))同步释放索引结构,因此需要较高的redis版本支持。 **使用方式**:cmake的时候加上`-DSORT_MODE=yes`选项,并重新编译 @@ -48,13 +48,13 @@ - 每一次读写field,也会触发对这个field自身的过期淘汰操作 - 排序中所有的key和field都是指针引用,无内存拷贝,无内存膨胀问题 -**支持的redis版本**: redis >= 5.0 -**优点**:可以运行在低版本的redis中(redis >= 5.0 ) -**缺点**:过期淘汰效率较低(相对SORT模式而言) +**支持的redis版本**: redis >= 5.0 +**优点**:可以运行在低版本的redis中(redis >= 5.0 ) +**缺点**:过期淘汰效率较低(相对SORT模式而言) **使用方式**:cmake的时候加上`-DSORT_MODE=no`选项,并重新编译 -## 事件通知 +## 事件通知 tairhash在field发生过期时(由主动或被动过期触发)会发送一个事件通知,通知以pubsub方式发送,channel的格式为:`tairhash@@__:` , 目前只支持expired事件类型,因此 channel为:`tairhash@@__:expired`,消息内容为过期的field。 @@ -100,7 +100,7 @@ OK (integer) 0 127.0.0.1:6379> EXHVER k f (integer) 2 -``` +``` ## Docker ``` @@ -109,15 +109,15 @@ docker run -p 6379:6379 tairmodule/tairhash:latest ## 编译及使用 ``` -mkdir build -cd build +mkdir build +cd build cmake ../ && make -j ``` 编译成功后会在lib目录下产生tairhash_module.so库文件 ``` ./redis-server --loadmodule /path/to/tairhash_module.so -``` +``` ## 测试方法 1. 修改`tests`目录下tairhash.tcl文件中的路径为`set testmodule [file your_path/tairhash_module.so]` @@ -133,8 +133,8 @@ cmake ../ && make -j ## 我们的modules -[TairHash](https://github.com/alibaba/TairHash): 和redis hash类似,但是可以为field设置expire和version,支持高效的主动过期和被动过期 -[TairZset](https://github.com/alibaba/TairZset): 和redis zset类似,但是支持多(最大255)维排序,同时支持incrby语义,非常适合游戏排行榜场景 -[TairString](https://github.com/alibaba/TairString): 和redis string类似,但是支持设置expire和version,并提供CAS/CAD等实用命令,非常适用于分布式锁等场景 +[TairHash](https://github.com/alibaba/TairHash): 和redis hash类似,但是可以为field设置expire和version,支持高效的主动过期和被动过期 +[TairZset](https://github.com/alibaba/TairZset): 和redis zset类似,但是支持多(最大255)维排序,同时支持incrby语义,非常适合游戏排行榜场景 +[TairString](https://github.com/alibaba/TairString): 和redis string类似,但是支持设置expire和version,并提供CAS/CAD等实用命令,非常适用于分布式锁等场景 diff --git a/README.md b/README.md index 6c8076e..016da49 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@
- + ## Introduction [中文说明](README-CN.md)      TairHash is a hash data structure developed based on the redis module. TairHash not only has the same rich data interface and high performance as the native hash, but also can set the expiration and version for the field. TairHash provides an active expiration mechanism, even if the field is not accessed after expiration, it can be actively deleted to release the memory. @@ -23,7 +23,7 @@ - Support field expired event notification (based on pubsub) ## Data structure -![avatar](imgs/tairhash_index2.png) +![avatar](imgs/tairhash_index2.png) ## Active expiration ### SORT_MODE: - Use a two-level sort index, the first level sorts the main key of tairhash, and the second level sorts the fields inside each tairhash @@ -35,9 +35,9 @@ **Supported redis version**: redis >= 7.0 -**Advantages**: higher efficiency of expire elimination +**Advantages**: higher efficiency of expire elimination -**Disadvantages**: Because the SORT_MODE implementation relies on the `unlink2` callback function (see this [PR](https://github.com/redis/redis/pull/8999))) to release the index structure synchronously, So currently only supports redis >= 7.0 and unstable branch +**Disadvantages**: Because the SORT_MODE implementation relies on the `unlink2` callback function (see this [PR](https://github.com/redis/redis/pull/8999))) to release the index structure synchronously, So currently only supports redis >= 7.0 and unstable branch **Usag**e: cmake with `-DSORT_MODE=yes` option, and recompile @@ -50,13 +50,13 @@ **Supported redis version**: redis >= 5.0 -**Advantages**: can run in the low version of redis (redis >= 5.0) +**Advantages**: can run in the low version of redis (redis >= 5.0) -**Disadvantages**: low efficiency of expire elimination (compared with SORT mode) +**Disadvantages**: low efficiency of expire elimination (compared with SORT mode) **Usage**: cmake with `-DSORT_MODE=no` option, and recompile -## Event notification +## Event notification tairhash will send an event notification when the field expires (triggered by active or passive expiration). The notification is sent in pubsub mode. The format of the channel is: `tairhash@@__:` , currently only supports expired event type, so The channel is: `tairhash@@__:expired`, and the message content is the expired field. @@ -102,7 +102,7 @@ OK (integer) 0 127.0.0.1:6379> EXHVER k f (integer) 2 -``` +``` ## Docker ``` @@ -111,15 +111,15 @@ docker run -p 6379:6379 tairmodule/tairhash:latest ## BUILD ``` -mkdir build -cd build +mkdir build +cd build cmake ../ && make -j ``` then the tairhash_module.so library file will be generated in the lib directory ``` ./redis-server --loadmodule /path/to/tairhash_module.so -``` +``` ## TEST 1. Modify the path in the tairhash.tcl file in the `tests` directory to `set testmodule [file your_path/tairhash_module.so]` @@ -135,6 +135,6 @@ then the tairhash_module.so library file will be generated in the lib directory ### Our modules -[TairHash](https://github.com/alibaba/TairHash): A redis module, similar to redis hash, but you can set expire and version for the field -[TairZset](https://github.com/alibaba/TairZset): A redis module, similar to redis zset, but you can set multiple scores for each member to support multi-dimensional sorting -[TairString](https://github.com/alibaba/TairString): A redis module, similar to redis string, but you can set expire and version for the value. It also provides many very useful commands, such as cas/cad, etc. +[TairHash](https://github.com/alibaba/TairHash): A redis module, similar to redis hash, but you can set expire and version for the field +[TairZset](https://github.com/alibaba/TairZset): A redis module, similar to redis zset, but you can set multiple scores for each member to support multi-dimensional sorting +[TairString](https://github.com/alibaba/TairString): A redis module, similar to redis string, but you can set expire and version for the value. It also provides many very useful commands, such as cas/cad, etc. diff --git a/dep/skiplist.c b/dep/skiplist.c index f3b1323..e976f23 100644 --- a/dep/skiplist.c +++ b/dep/skiplist.c @@ -79,9 +79,7 @@ m_zskiplistNode *m_zslInsert(m_zskiplist *zsl, long long score, RedisModuleStrin for (i = zsl->level - 1; i >= 0; i--) { /* store rank that is crossed to reach the insert position */ rank[i] = i == (zsl->level - 1) ? 0 : rank[i + 1]; - while (x->level[i].forward && - (x->level[i].forward->score < score || - (x->level[i].forward->score == score && RedisModule_StringCompare(x->level[i].forward->member, member) < 0))) { + while (x->level[i].forward && (x->level[i].forward->score < score || (x->level[i].forward->score == score && RedisModule_StringCompare(x->level[i].forward->member, member) < 0))) { rank[i] += x->level[i].span; x = x->level[i].forward; } @@ -160,9 +158,7 @@ int m_zslDelete(m_zskiplist *zsl, long long score, RedisModuleString *member, m_ x = zsl->header; for (i = zsl->level - 1; i >= 0; i--) { - while (x->level[i].forward && - (x->level[i].forward->score < score || - (x->level[i].forward->score == score && RedisModule_StringCompare(x->level[i].forward->member, member) < 0))) { + while (x->level[i].forward && (x->level[i].forward->score < score || (x->level[i].forward->score == score && RedisModule_StringCompare(x->level[i].forward->member, member) < 0))) { x = x->level[i].forward; } update[i] = x; @@ -192,7 +188,7 @@ int m_zslDelete(m_zskiplist *zsl, long long score, RedisModuleString *member, m_ * element, which is more costly. * * The function returns the updated element skiplist node pointer. */ -m_zskiplistNode *m_zslUpdateScore(m_zskiplist *zsl, long long curscore, RedisModuleString *member, long long newscore) { +m_zskiplistNode *m_zslUpdateScore(m_zskiplist *zsl, long long curscore, RedisModuleString *member, long long newscore) { m_zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x; int i; @@ -200,9 +196,7 @@ m_zskiplistNode *m_zslUpdateScore(m_zskiplist *zsl, long long curscore, RedisMo * we'll have to update or remove it. */ x = zsl->header; for (i = zsl->level - 1; i >= 0; i--) { - while (x->level[i].forward && - (x->level[i].forward->score < curscore || - (x->level[i].forward->score == curscore && RedisModule_StringCompare(x->level[i].forward->member, member) < 0))) { + while (x->level[i].forward && (x->level[i].forward->score < curscore || (x->level[i].forward->score == curscore && RedisModule_StringCompare(x->level[i].forward->member, member) < 0))) { x = x->level[i].forward; } update[i] = x; @@ -368,15 +362,14 @@ unsigned long m_zslDeleteRangeByRank(m_zskiplist *zsl, unsigned int start, unsig return removed; } -m_zskiplistNode* m_zslGetElementByRank(m_zskiplist *zsl, unsigned long rank) { +m_zskiplistNode *m_zslGetElementByRank(m_zskiplist *zsl, unsigned long rank) { m_zskiplistNode *x; unsigned long traversed = 0; int i; x = zsl->header; - for (i = zsl->level-1; i >= 0; i--) { - while (x->level[i].forward && (traversed + x->level[i].span) <= rank) - { + for (i = zsl->level - 1; i >= 0; i--) { + while (x->level[i].forward && (traversed + x->level[i].span) <= rank) { traversed += x->level[i].span; x = x->level[i].forward; } diff --git a/dep/skiplist.h b/dep/skiplist.h index 4f41af2..deec088 100644 --- a/dep/skiplist.h +++ b/dep/skiplist.h @@ -11,7 +11,7 @@ typedef struct { } m_zrangespec; typedef struct m_zskiplistNode { - RedisModuleString *member; + RedisModuleString *member; long long score; struct m_zskiplistNode *backward; struct zskiplistLevel { @@ -35,6 +35,6 @@ m_zskiplistNode *m_zslLastInRange(m_zskiplist *zsl, m_zrangespec *range); int m_zslValueGteMin(long long value, m_zrangespec *spec); int m_zslValueLteMax(long long value, m_zrangespec *spec); void m_zslDeleteNode(m_zskiplist *zsl, m_zskiplistNode *x, m_zskiplistNode **update); -m_zskiplistNode *m_zslUpdateScore(m_zskiplist *zsl, long long curscore, RedisModuleString *member, long long newscore); -m_zskiplistNode* m_zslGetElementByRank(m_zskiplist *zsl, unsigned long rank); +m_zskiplistNode *m_zslUpdateScore(m_zskiplist *zsl, long long curscore, RedisModuleString *member, long long newscore); +m_zskiplistNode *m_zslGetElementByRank(m_zskiplist *zsl, unsigned long rank); unsigned long m_zslDeleteRangeByRank(m_zskiplist *zsl, unsigned int start, unsigned int end); \ No newline at end of file diff --git a/dep/util.h b/dep/util.h index 86bacbd..44dbb43 100755 --- a/dep/util.h +++ b/dep/util.h @@ -30,8 +30,8 @@ #ifndef __UTIL_H_ #define __UTIL_H_ -#include #include +#include /* The maximum number of characters needed to represent a long double * as a string (long double has a huge range). diff --git a/src/redismodule.h b/src/redismodule.h index 6f52818..94ff064 100755 --- a/src/redismodule.h +++ b/src/redismodule.h @@ -1,9 +1,9 @@ #ifndef REDISMODULE_H #define REDISMODULE_H -#include #include #include +#include /* ---------------- Defines common between core and modules --------------- */ @@ -14,17 +14,17 @@ /* API versions. */ #define REDISMODULE_APIVER_1 1 -/* Version of the RedisModuleTypeMethods structure. Once the RedisModuleTypeMethods +/* Version of the RedisModuleTypeMethods structure. Once the RedisModuleTypeMethods * structure is changed, this version number needs to be changed synchronistically. */ #define REDISMODULE_TYPE_METHOD_VERSION 4 /* API flags and constants */ -#define REDISMODULE_READ (1<<0) -#define REDISMODULE_WRITE (1<<1) +#define REDISMODULE_READ (1 << 0) +#define REDISMODULE_WRITE (1 << 1) /* RedisModule_OpenKey extra flags for the 'mode' argument. * Avoid touching the LRU/LFU of the key when opened. */ -#define REDISMODULE_OPEN_KEY_NOTOUCH (1<<16) +#define REDISMODULE_OPEN_KEY_NOTOUCH (1 << 16) #define REDISMODULE_LIST_HEAD 0 #define REDISMODULE_LIST_TAIL 1 @@ -54,21 +54,21 @@ #define REDISMODULE_NO_EXPIRE -1 /* Sorted set API flags. */ -#define REDISMODULE_ZADD_XX (1<<0) -#define REDISMODULE_ZADD_NX (1<<1) -#define REDISMODULE_ZADD_ADDED (1<<2) -#define REDISMODULE_ZADD_UPDATED (1<<3) -#define REDISMODULE_ZADD_NOP (1<<4) -#define REDISMODULE_ZADD_GT (1<<5) -#define REDISMODULE_ZADD_LT (1<<6) +#define REDISMODULE_ZADD_XX (1 << 0) +#define REDISMODULE_ZADD_NX (1 << 1) +#define REDISMODULE_ZADD_ADDED (1 << 2) +#define REDISMODULE_ZADD_UPDATED (1 << 3) +#define REDISMODULE_ZADD_NOP (1 << 4) +#define REDISMODULE_ZADD_GT (1 << 5) +#define REDISMODULE_ZADD_LT (1 << 6) /* Hash API flags. */ -#define REDISMODULE_HASH_NONE 0 -#define REDISMODULE_HASH_NX (1<<0) -#define REDISMODULE_HASH_XX (1<<1) -#define REDISMODULE_HASH_CFIELDS (1<<2) -#define REDISMODULE_HASH_EXISTS (1<<3) -#define REDISMODULE_HASH_COUNT_ALL (1<<4) +#define REDISMODULE_HASH_NONE 0 +#define REDISMODULE_HASH_NX (1 << 0) +#define REDISMODULE_HASH_XX (1 << 1) +#define REDISMODULE_HASH_CFIELDS (1 << 2) +#define REDISMODULE_HASH_EXISTS (1 << 3) +#define REDISMODULE_HASH_COUNT_ALL (1 << 4) /* StreamID type. */ typedef struct RedisModuleStreamID { @@ -77,122 +77,122 @@ typedef struct RedisModuleStreamID { } RedisModuleStreamID; /* StreamAdd() flags. */ -#define REDISMODULE_STREAM_ADD_AUTOID (1<<0) +#define REDISMODULE_STREAM_ADD_AUTOID (1 << 0) /* StreamIteratorStart() flags. */ -#define REDISMODULE_STREAM_ITERATOR_EXCLUSIVE (1<<0) -#define REDISMODULE_STREAM_ITERATOR_REVERSE (1<<1) +#define REDISMODULE_STREAM_ITERATOR_EXCLUSIVE (1 << 0) +#define REDISMODULE_STREAM_ITERATOR_REVERSE (1 << 1) /* StreamIteratorTrim*() flags. */ -#define REDISMODULE_STREAM_TRIM_APPROX (1<<0) +#define REDISMODULE_STREAM_TRIM_APPROX (1 << 0) /* Context Flags: Info about the current context returned by * RM_GetContextFlags(). */ /* The command is running in the context of a Lua script */ -#define REDISMODULE_CTX_FLAGS_LUA (1<<0) +#define REDISMODULE_CTX_FLAGS_LUA (1 << 0) /* The command is running inside a Redis transaction */ -#define REDISMODULE_CTX_FLAGS_MULTI (1<<1) +#define REDISMODULE_CTX_FLAGS_MULTI (1 << 1) /* The instance is a master */ -#define REDISMODULE_CTX_FLAGS_MASTER (1<<2) +#define REDISMODULE_CTX_FLAGS_MASTER (1 << 2) /* The instance is a slave */ -#define REDISMODULE_CTX_FLAGS_SLAVE (1<<3) +#define REDISMODULE_CTX_FLAGS_SLAVE (1 << 3) /* The instance is read-only (usually meaning it's a slave as well) */ -#define REDISMODULE_CTX_FLAGS_READONLY (1<<4) +#define REDISMODULE_CTX_FLAGS_READONLY (1 << 4) /* The instance is running in cluster mode */ -#define REDISMODULE_CTX_FLAGS_CLUSTER (1<<5) +#define REDISMODULE_CTX_FLAGS_CLUSTER (1 << 5) /* The instance has AOF enabled */ -#define REDISMODULE_CTX_FLAGS_AOF (1<<6) +#define REDISMODULE_CTX_FLAGS_AOF (1 << 6) /* The instance has RDB enabled */ -#define REDISMODULE_CTX_FLAGS_RDB (1<<7) +#define REDISMODULE_CTX_FLAGS_RDB (1 << 7) /* The instance has Maxmemory set */ -#define REDISMODULE_CTX_FLAGS_MAXMEMORY (1<<8) +#define REDISMODULE_CTX_FLAGS_MAXMEMORY (1 << 8) /* Maxmemory is set and has an eviction policy that may delete keys */ -#define REDISMODULE_CTX_FLAGS_EVICT (1<<9) +#define REDISMODULE_CTX_FLAGS_EVICT (1 << 9) /* Redis is out of memory according to the maxmemory flag. */ -#define REDISMODULE_CTX_FLAGS_OOM (1<<10) +#define REDISMODULE_CTX_FLAGS_OOM (1 << 10) /* Less than 25% of memory available according to maxmemory. */ -#define REDISMODULE_CTX_FLAGS_OOM_WARNING (1<<11) +#define REDISMODULE_CTX_FLAGS_OOM_WARNING (1 << 11) /* The command was sent over the replication link. */ -#define REDISMODULE_CTX_FLAGS_REPLICATED (1<<12) +#define REDISMODULE_CTX_FLAGS_REPLICATED (1 << 12) /* Redis is currently loading either from AOF or RDB. */ -#define REDISMODULE_CTX_FLAGS_LOADING (1<<13) +#define REDISMODULE_CTX_FLAGS_LOADING (1 << 13) /* The replica has no link with its master, note that * there is the inverse flag as well: * * REDISMODULE_CTX_FLAGS_REPLICA_IS_ONLINE * * The two flags are exclusive, one or the other can be set. */ -#define REDISMODULE_CTX_FLAGS_REPLICA_IS_STALE (1<<14) +#define REDISMODULE_CTX_FLAGS_REPLICA_IS_STALE (1 << 14) /* The replica is trying to connect with the master. * (REPL_STATE_CONNECT and REPL_STATE_CONNECTING states) */ -#define REDISMODULE_CTX_FLAGS_REPLICA_IS_CONNECTING (1<<15) +#define REDISMODULE_CTX_FLAGS_REPLICA_IS_CONNECTING (1 << 15) /* THe replica is receiving an RDB file from its master. */ -#define REDISMODULE_CTX_FLAGS_REPLICA_IS_TRANSFERRING (1<<16) +#define REDISMODULE_CTX_FLAGS_REPLICA_IS_TRANSFERRING (1 << 16) /* The replica is online, receiving updates from its master. */ -#define REDISMODULE_CTX_FLAGS_REPLICA_IS_ONLINE (1<<17) +#define REDISMODULE_CTX_FLAGS_REPLICA_IS_ONLINE (1 << 17) /* There is currently some background process active. */ -#define REDISMODULE_CTX_FLAGS_ACTIVE_CHILD (1<<18) +#define REDISMODULE_CTX_FLAGS_ACTIVE_CHILD (1 << 18) /* The next EXEC will fail due to dirty CAS (touched keys). */ -#define REDISMODULE_CTX_FLAGS_MULTI_DIRTY (1<<19) +#define REDISMODULE_CTX_FLAGS_MULTI_DIRTY (1 << 19) /* Redis is currently running inside background child process. */ -#define REDISMODULE_CTX_FLAGS_IS_CHILD (1<<20) +#define REDISMODULE_CTX_FLAGS_IS_CHILD (1 << 20) /* The current client does not allow blocking, either called from * within multi, lua, or from another module using RM_Call */ -#define REDISMODULE_CTX_FLAGS_DENY_BLOCKING (1<<21) +#define REDISMODULE_CTX_FLAGS_DENY_BLOCKING (1 << 21) /* Next context flag, must be updated when adding new flags above! This flag should not be used directly by the module. * Use RedisModule_GetContextFlagsAll instead. */ -#define _REDISMODULE_CTX_FLAGS_NEXT (1<<22) +#define _REDISMODULE_CTX_FLAGS_NEXT (1 << 22) /* Keyspace changes notification classes. Every class is associated with a * character for configuration purposes. * NOTE: These have to be in sync with NOTIFY_* in server.h */ -#define REDISMODULE_NOTIFY_KEYSPACE (1<<0) /* K */ -#define REDISMODULE_NOTIFY_KEYEVENT (1<<1) /* E */ -#define REDISMODULE_NOTIFY_GENERIC (1<<2) /* g */ -#define REDISMODULE_NOTIFY_STRING (1<<3) /* $ */ -#define REDISMODULE_NOTIFY_LIST (1<<4) /* l */ -#define REDISMODULE_NOTIFY_SET (1<<5) /* s */ -#define REDISMODULE_NOTIFY_HASH (1<<6) /* h */ -#define REDISMODULE_NOTIFY_ZSET (1<<7) /* z */ -#define REDISMODULE_NOTIFY_EXPIRED (1<<8) /* x */ -#define REDISMODULE_NOTIFY_EVICTED (1<<9) /* e */ -#define REDISMODULE_NOTIFY_STREAM (1<<10) /* t */ -#define REDISMODULE_NOTIFY_KEY_MISS (1<<11) /* m (Note: This one is excluded from REDISMODULE_NOTIFY_ALL on purpose) */ -#define REDISMODULE_NOTIFY_LOADED (1<<12) /* module only key space notification, indicate a key loaded from rdb */ -#define REDISMODULE_NOTIFY_MODULE (1<<13) /* d, module key space notification */ +#define REDISMODULE_NOTIFY_KEYSPACE (1 << 0) /* K */ +#define REDISMODULE_NOTIFY_KEYEVENT (1 << 1) /* E */ +#define REDISMODULE_NOTIFY_GENERIC (1 << 2) /* g */ +#define REDISMODULE_NOTIFY_STRING (1 << 3) /* $ */ +#define REDISMODULE_NOTIFY_LIST (1 << 4) /* l */ +#define REDISMODULE_NOTIFY_SET (1 << 5) /* s */ +#define REDISMODULE_NOTIFY_HASH (1 << 6) /* h */ +#define REDISMODULE_NOTIFY_ZSET (1 << 7) /* z */ +#define REDISMODULE_NOTIFY_EXPIRED (1 << 8) /* x */ +#define REDISMODULE_NOTIFY_EVICTED (1 << 9) /* e */ +#define REDISMODULE_NOTIFY_STREAM (1 << 10) /* t */ +#define REDISMODULE_NOTIFY_KEY_MISS (1 << 11) /* m (Note: This one is excluded from REDISMODULE_NOTIFY_ALL on purpose) */ +#define REDISMODULE_NOTIFY_LOADED (1 << 12) /* module only key space notification, indicate a key loaded from rdb */ +#define REDISMODULE_NOTIFY_MODULE (1 << 13) /* d, module key space notification */ /* Next notification flag, must be updated when adding new flags above! This flag should not be used directly by the module. * Use RedisModule_GetKeyspaceNotificationFlagsAll instead. */ -#define _REDISMODULE_NOTIFY_NEXT (1<<14) +#define _REDISMODULE_NOTIFY_NEXT (1 << 14) -#define REDISMODULE_NOTIFY_ALL (REDISMODULE_NOTIFY_GENERIC | REDISMODULE_NOTIFY_STRING | REDISMODULE_NOTIFY_LIST | REDISMODULE_NOTIFY_SET | REDISMODULE_NOTIFY_HASH | REDISMODULE_NOTIFY_ZSET | REDISMODULE_NOTIFY_EXPIRED | REDISMODULE_NOTIFY_EVICTED | REDISMODULE_NOTIFY_STREAM | REDISMODULE_NOTIFY_MODULE) /* A */ +#define REDISMODULE_NOTIFY_ALL (REDISMODULE_NOTIFY_GENERIC | REDISMODULE_NOTIFY_STRING | REDISMODULE_NOTIFY_LIST | REDISMODULE_NOTIFY_SET | REDISMODULE_NOTIFY_HASH | REDISMODULE_NOTIFY_ZSET | REDISMODULE_NOTIFY_EXPIRED | REDISMODULE_NOTIFY_EVICTED | REDISMODULE_NOTIFY_STREAM | REDISMODULE_NOTIFY_MODULE) /* A */ /* A special pointer that we can use between the core and the module to signal * field deletion, and that is impossible to be a valid pointer. */ -#define REDISMODULE_HASH_DELETE ((RedisModuleString*)(long)1) +#define REDISMODULE_HASH_DELETE ((RedisModuleString *)(long)1) /* Error messages. */ #define REDISMODULE_ERRORMSG_WRONGTYPE "WRONGTYPE Operation against a key holding the wrong kind of value" -#define REDISMODULE_POSITIVE_INFINITE (1.0/0.0) -#define REDISMODULE_NEGATIVE_INFINITE (-1.0/0.0) +#define REDISMODULE_POSITIVE_INFINITE (1.0 / 0.0) +#define REDISMODULE_NEGATIVE_INFINITE (-1.0 / 0.0) /* Cluster API defines. */ #define REDISMODULE_NODE_ID_LEN 40 -#define REDISMODULE_NODE_MYSELF (1<<0) -#define REDISMODULE_NODE_MASTER (1<<1) -#define REDISMODULE_NODE_SLAVE (1<<2) -#define REDISMODULE_NODE_PFAIL (1<<3) -#define REDISMODULE_NODE_FAIL (1<<4) -#define REDISMODULE_NODE_NOFAILOVER (1<<5) +#define REDISMODULE_NODE_MYSELF (1 << 0) +#define REDISMODULE_NODE_MASTER (1 << 1) +#define REDISMODULE_NODE_SLAVE (1 << 2) +#define REDISMODULE_NODE_PFAIL (1 << 3) +#define REDISMODULE_NODE_FAIL (1 << 4) +#define REDISMODULE_NODE_NOFAILOVER (1 << 5) #define REDISMODULE_CLUSTER_FLAG_NONE 0 -#define REDISMODULE_CLUSTER_FLAG_NO_FAILOVER (1<<1) -#define REDISMODULE_CLUSTER_FLAG_NO_REDIRECTION (1<<2) +#define REDISMODULE_CLUSTER_FLAG_NO_FAILOVER (1 << 1) +#define REDISMODULE_CLUSTER_FLAG_NO_REDIRECTION (1 << 2) -#define REDISMODULE_NOT_USED(V) ((void) V) +#define REDISMODULE_NOT_USED(V) ((void)V) /* Logging level strings */ #define REDISMODULE_LOGLEVEL_DEBUG "debug" @@ -201,8 +201,8 @@ This flag should not be used directly by the module. #define REDISMODULE_LOGLEVEL_WARNING "warning" /* Bit flags for aux_save_triggers and the aux_load and aux_save callbacks */ -#define REDISMODULE_AUX_BEFORE_RDB (1<<0) -#define REDISMODULE_AUX_AFTER_RDB (1<<1) +#define REDISMODULE_AUX_BEFORE_RDB (1 << 0) +#define REDISMODULE_AUX_AFTER_RDB (1 << 1) /* This type represents a timer handle, and is returned when a timer is * registered and used in order to invalidate a timer. It's just a 64 bit @@ -213,14 +213,14 @@ typedef uint64_t RedisModuleTimerID; /* CommandFilter Flags */ /* Do filter RedisModule_Call() commands initiated by module itself. */ -#define REDISMODULE_CMDFILTER_NOSELF (1<<0) +#define REDISMODULE_CMDFILTER_NOSELF (1 << 0) /* Declare that the module can handle errors with RedisModule_SetModuleOptions. */ -#define REDISMODULE_OPTIONS_HANDLE_IO_ERRORS (1<<0) +#define REDISMODULE_OPTIONS_HANDLE_IO_ERRORS (1 << 0) /* When set, Redis will not call RedisModule_SignalModifiedKey(), implicitly in * RedisModule_CloseKey, and the module needs to do that when manually when keys * are modified from the user's sperspective, to invalidate WATCH. */ -#define REDISMODULE_OPTION_NO_IMPLICIT_SIGNAL_MODIFIED (1<<1) +#define REDISMODULE_OPTION_NO_IMPLICIT_SIGNAL_MODIFIED (1 << 1) /* Server events definitions. * Those flags should not be used directly by the module, instead @@ -242,8 +242,8 @@ typedef uint64_t RedisModuleTimerID; #define _REDISMODULE_EVENT_NEXT 14 /* Next event flag, should be updated if a new event added. */ typedef struct RedisModuleEvent { - uint64_t id; /* REDISMODULE_EVENT_... defines. */ - uint64_t dataver; /* Version of the structure we pass as 'data'. */ + uint64_t id; /* REDISMODULE_EVENT_... defines. */ + uint64_t dataver; /* Version of the structure we pass as 'data'. */ } RedisModuleEvent; struct RedisModuleCtx; @@ -251,62 +251,11 @@ struct RedisModuleDefragCtx; typedef void (*RedisModuleEventCallback)(struct RedisModuleCtx *ctx, RedisModuleEvent eid, uint64_t subevent, void *data); static const RedisModuleEvent - RedisModuleEvent_ReplicationRoleChanged = { + RedisModuleEvent_ReplicationRoleChanged + = { REDISMODULE_EVENT_REPLICATION_ROLE_CHANGED, - 1 - }, - RedisModuleEvent_Persistence = { - REDISMODULE_EVENT_PERSISTENCE, - 1 - }, - RedisModuleEvent_FlushDB = { - REDISMODULE_EVENT_FLUSHDB, - 1 - }, - RedisModuleEvent_Loading = { - REDISMODULE_EVENT_LOADING, - 1 - }, - RedisModuleEvent_ClientChange = { - REDISMODULE_EVENT_CLIENT_CHANGE, - 1 - }, - RedisModuleEvent_Shutdown = { - REDISMODULE_EVENT_SHUTDOWN, - 1 - }, - RedisModuleEvent_ReplicaChange = { - REDISMODULE_EVENT_REPLICA_CHANGE, - 1 - }, - RedisModuleEvent_CronLoop = { - REDISMODULE_EVENT_CRON_LOOP, - 1 - }, - RedisModuleEvent_MasterLinkChange = { - REDISMODULE_EVENT_MASTER_LINK_CHANGE, - 1 - }, - RedisModuleEvent_ModuleChange = { - REDISMODULE_EVENT_MODULE_CHANGE, - 1 - }, - RedisModuleEvent_LoadingProgress = { - REDISMODULE_EVENT_LOADING_PROGRESS, - 1 - }, - RedisModuleEvent_SwapDB = { - REDISMODULE_EVENT_SWAPDB, - 1 - }, - RedisModuleEvent_ReplBackup = { - REDISMODULE_EVENT_REPL_BACKUP, - 1 - }, - RedisModuleEvent_ForkChild = { - REDISMODULE_EVENT_FORK_CHILD, - 1 - }; + 1}, + RedisModuleEvent_Persistence = {REDISMODULE_EVENT_PERSISTENCE, 1}, RedisModuleEvent_FlushDB = {REDISMODULE_EVENT_FLUSHDB, 1}, RedisModuleEvent_Loading = {REDISMODULE_EVENT_LOADING, 1}, RedisModuleEvent_ClientChange = {REDISMODULE_EVENT_CLIENT_CHANGE, 1}, RedisModuleEvent_Shutdown = {REDISMODULE_EVENT_SHUTDOWN, 1}, RedisModuleEvent_ReplicaChange = {REDISMODULE_EVENT_REPLICA_CHANGE, 1}, RedisModuleEvent_CronLoop = {REDISMODULE_EVENT_CRON_LOOP, 1}, RedisModuleEvent_MasterLinkChange = {REDISMODULE_EVENT_MASTER_LINK_CHANGE, 1}, RedisModuleEvent_ModuleChange = {REDISMODULE_EVENT_MODULE_CHANGE, 1}, RedisModuleEvent_LoadingProgress = {REDISMODULE_EVENT_LOADING_PROGRESS, 1}, RedisModuleEvent_SwapDB = {REDISMODULE_EVENT_SWAPDB, 1}, RedisModuleEvent_ReplBackup = {REDISMODULE_EVENT_REPL_BACKUP, 1}, RedisModuleEvent_ForkChild = {REDISMODULE_EVENT_FORK_CHILD, 1}; /* Those are values that are used for the 'subevent' callback argument. */ #define REDISMODULE_SUBEVENT_PERSISTENCE_RDB_START 0 @@ -365,12 +314,12 @@ static const RedisModuleEvent #define _REDISMODULE_SUBEVENT_SWAPDB_NEXT 0 /* RedisModuleClientInfo flags. */ -#define REDISMODULE_CLIENTINFO_FLAG_SSL (1<<0) -#define REDISMODULE_CLIENTINFO_FLAG_PUBSUB (1<<1) -#define REDISMODULE_CLIENTINFO_FLAG_BLOCKED (1<<2) -#define REDISMODULE_CLIENTINFO_FLAG_TRACKING (1<<3) -#define REDISMODULE_CLIENTINFO_FLAG_UNIXSOCKET (1<<4) -#define REDISMODULE_CLIENTINFO_FLAG_MULTI (1<<5) +#define REDISMODULE_CLIENTINFO_FLAG_SSL (1 << 0) +#define REDISMODULE_CLIENTINFO_FLAG_PUBSUB (1 << 1) +#define REDISMODULE_CLIENTINFO_FLAG_BLOCKED (1 << 2) +#define REDISMODULE_CLIENTINFO_FLAG_TRACKING (1 << 3) +#define REDISMODULE_CLIENTINFO_FLAG_UNIXSOCKET (1 << 4) +#define REDISMODULE_CLIENTINFO_FLAG_MULTI (1 << 5) /* Here we take all the structures that the module pass to the core * and the other way around. Notably the list here contains the structures @@ -389,83 +338,83 @@ static const RedisModuleEvent #define REDISMODULE_CLIENTINFO_VERSION 1 typedef struct RedisModuleClientInfo { - uint64_t version; /* Version of this structure for ABI compat. */ - uint64_t flags; /* REDISMODULE_CLIENTINFO_FLAG_* */ - uint64_t id; /* Client ID. */ - char addr[46]; /* IPv4 or IPv6 address. */ - uint16_t port; /* TCP port. */ - uint16_t db; /* Selected DB. */ + uint64_t version; /* Version of this structure for ABI compat. */ + uint64_t flags; /* REDISMODULE_CLIENTINFO_FLAG_* */ + uint64_t id; /* Client ID. */ + char addr[46]; /* IPv4 or IPv6 address. */ + uint16_t port; /* TCP port. */ + uint16_t db; /* Selected DB. */ } RedisModuleClientInfoV1; #define RedisModuleClientInfo RedisModuleClientInfoV1 #define REDISMODULE_REPLICATIONINFO_VERSION 1 typedef struct RedisModuleReplicationInfo { - uint64_t version; /* Not used since this structure is never passed - from the module to the core right now. Here - for future compatibility. */ - int master; /* true if master, false if replica */ - char *masterhost; /* master instance hostname for NOW_REPLICA */ - int masterport; /* master instance port for NOW_REPLICA */ - char *replid1; /* Main replication ID */ - char *replid2; /* Secondary replication ID */ - uint64_t repl1_offset; /* Main replication offset */ - uint64_t repl2_offset; /* Offset of replid2 validity */ + uint64_t version; /* Not used since this structure is never passed + from the module to the core right now. Here + for future compatibility. */ + int master; /* true if master, false if replica */ + char *masterhost; /* master instance hostname for NOW_REPLICA */ + int masterport; /* master instance port for NOW_REPLICA */ + char *replid1; /* Main replication ID */ + char *replid2; /* Secondary replication ID */ + uint64_t repl1_offset; /* Main replication offset */ + uint64_t repl2_offset; /* Offset of replid2 validity */ } RedisModuleReplicationInfoV1; #define RedisModuleReplicationInfo RedisModuleReplicationInfoV1 #define REDISMODULE_FLUSHINFO_VERSION 1 typedef struct RedisModuleFlushInfo { - uint64_t version; /* Not used since this structure is never passed - from the module to the core right now. Here - for future compatibility. */ - int32_t sync; /* Synchronous or threaded flush?. */ - int32_t dbnum; /* Flushed database number, -1 for ALL. */ + uint64_t version; /* Not used since this structure is never passed + from the module to the core right now. Here + for future compatibility. */ + int32_t sync; /* Synchronous or threaded flush?. */ + int32_t dbnum; /* Flushed database number, -1 for ALL. */ } RedisModuleFlushInfoV1; #define RedisModuleFlushInfo RedisModuleFlushInfoV1 #define REDISMODULE_MODULE_CHANGE_VERSION 1 typedef struct RedisModuleModuleChange { - uint64_t version; /* Not used since this structure is never passed - from the module to the core right now. Here - for future compatibility. */ - const char* module_name;/* Name of module loaded or unloaded. */ - int32_t module_version; /* Module version. */ + uint64_t version; /* Not used since this structure is never passed + from the module to the core right now. Here + for future compatibility. */ + const char *module_name; /* Name of module loaded or unloaded. */ + int32_t module_version; /* Module version. */ } RedisModuleModuleChangeV1; #define RedisModuleModuleChange RedisModuleModuleChangeV1 #define REDISMODULE_CRON_LOOP_VERSION 1 typedef struct RedisModuleCronLoopInfo { - uint64_t version; /* Not used since this structure is never passed - from the module to the core right now. Here - for future compatibility. */ - int32_t hz; /* Approximate number of events per second. */ + uint64_t version; /* Not used since this structure is never passed + from the module to the core right now. Here + for future compatibility. */ + int32_t hz; /* Approximate number of events per second. */ } RedisModuleCronLoopV1; #define RedisModuleCronLoop RedisModuleCronLoopV1 #define REDISMODULE_LOADING_PROGRESS_VERSION 1 typedef struct RedisModuleLoadingProgressInfo { - uint64_t version; /* Not used since this structure is never passed - from the module to the core right now. Here - for future compatibility. */ - int32_t hz; /* Approximate number of events per second. */ - int32_t progress; /* Approximate progress between 0 and 1024, or -1 - * if unknown. */ + uint64_t version; /* Not used since this structure is never passed + from the module to the core right now. Here + for future compatibility. */ + int32_t hz; /* Approximate number of events per second. */ + int32_t progress; /* Approximate progress between 0 and 1024, or -1 + * if unknown. */ } RedisModuleLoadingProgressV1; #define RedisModuleLoadingProgress RedisModuleLoadingProgressV1 #define REDISMODULE_SWAPDBINFO_VERSION 1 typedef struct RedisModuleSwapDbInfo { - uint64_t version; /* Not used since this structure is never passed - from the module to the core right now. Here - for future compatibility. */ - int32_t dbnum_first; /* Swap Db first dbnum */ - int32_t dbnum_second; /* Swap Db second dbnum */ + uint64_t version; /* Not used since this structure is never passed + from the module to the core right now. Here + for future compatibility. */ + int32_t dbnum_first; /* Swap Db first dbnum */ + int32_t dbnum_second; /* Swap Db second dbnum */ } RedisModuleSwapDbInfoV1; #define RedisModuleSwapDbInfo RedisModuleSwapDbInfoV1 @@ -478,27 +427,27 @@ typedef long long mstime_t; /* Macro definitions specific to individual compilers */ #ifndef REDISMODULE_ATTR_UNUSED -# ifdef __GNUC__ -# define REDISMODULE_ATTR_UNUSED __attribute__((unused)) -# else -# define REDISMODULE_ATTR_UNUSED -# endif +#ifdef __GNUC__ +#define REDISMODULE_ATTR_UNUSED __attribute__((unused)) +#else +#define REDISMODULE_ATTR_UNUSED +#endif #endif #ifndef REDISMODULE_ATTR_PRINTF -# ifdef __GNUC__ -# define REDISMODULE_ATTR_PRINTF(idx,cnt) __attribute__((format(printf,idx,cnt))) -# else -# define REDISMODULE_ATTR_PRINTF(idx,cnt) -# endif +#ifdef __GNUC__ +#define REDISMODULE_ATTR_PRINTF(idx, cnt) __attribute__((format(printf, idx, cnt))) +#else +#define REDISMODULE_ATTR_PRINTF(idx, cnt) +#endif #endif #ifndef REDISMODULE_ATTR_COMMON -# if defined(__GNUC__) && !defined(__clang__) -# define REDISMODULE_ATTR_COMMON __attribute__((__common__)) -# else -# define REDISMODULE_ATTR_COMMON -# endif +#if defined(__GNUC__) && !defined(__clang__) +#define REDISMODULE_ATTR_COMMON __attribute__((__common__)) +#else +#define REDISMODULE_ATTR_COMMON +#endif #endif /* Incomplete structures for compiler checks but opaque access. */ @@ -543,12 +492,12 @@ typedef void *(*RedisModuleTypeCopyFunc2)(RedisModuleKeyOptCtx *ctx, const void typedef int (*RedisModuleTypeDefragFunc)(RedisModuleDefragCtx *ctx, RedisModuleString *key, void **value); typedef void (*RedisModuleClusterMessageReceiver)(RedisModuleCtx *ctx, const char *sender_id, uint8_t type, const unsigned char *payload, uint32_t len); typedef void (*RedisModuleTimerProc)(RedisModuleCtx *ctx, void *data); -typedef void (*RedisModuleCommandFilterFunc) (RedisModuleCommandFilterCtx *filter); -typedef void (*RedisModuleForkDoneHandler) (int exitcode, int bysignal, void *user_data); +typedef void (*RedisModuleCommandFilterFunc)(RedisModuleCommandFilterCtx *filter); +typedef void (*RedisModuleForkDoneHandler)(int exitcode, int bysignal, void *user_data); typedef void (*RedisModuleInfoFunc)(RedisModuleInfoCtx *ctx, int for_crash_report); typedef void (*RedisModuleScanCB)(RedisModuleCtx *ctx, RedisModuleString *keyname, RedisModuleKey *key, void *privdata); typedef void (*RedisModuleScanKeyCB)(RedisModuleKey *key, RedisModuleString *field, RedisModuleString *value, void *privdata); -typedef void (*RedisModuleUserChangedFunc) (uint64_t client_id, void *privdata); +typedef void (*RedisModuleUserChangedFunc)(uint64_t client_id, void *privdata); typedef int (*RedisModuleDefragFunc)(RedisModuleDefragCtx *ctx); typedef struct RedisModuleTypeMethods { @@ -573,7 +522,7 @@ typedef struct RedisModuleTypeMethods { } RedisModuleTypeMethods; #define REDISMODULE_GET_API(name) \ - RedisModule_GetApi("RedisModule_" #name, ((void **)&RedisModule_ ## name)) + RedisModule_GetApi("RedisModule_" #name, ((void **)&RedisModule_##name)) /* Default API declaration prefix (not 'extern' for backwards compatibility) */ #ifndef REDISMODULE_API @@ -585,11 +534,11 @@ typedef struct RedisModuleTypeMethods { #define REDISMODULE_ATTR REDISMODULE_ATTR_COMMON #endif -REDISMODULE_API void * (*RedisModule_Alloc)(size_t bytes) REDISMODULE_ATTR; -REDISMODULE_API void * (*RedisModule_Realloc)(void *ptr, size_t bytes) REDISMODULE_ATTR; +REDISMODULE_API void *(*RedisModule_Alloc)(size_t bytes)REDISMODULE_ATTR; +REDISMODULE_API void *(*RedisModule_Realloc)(void *ptr, size_t bytes)REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_Free)(void *ptr) REDISMODULE_ATTR; -REDISMODULE_API void * (*RedisModule_Calloc)(size_t nmemb, size_t size) REDISMODULE_ATTR; -REDISMODULE_API char * (*RedisModule_Strdup)(const char *str) REDISMODULE_ATTR; +REDISMODULE_API void *(*RedisModule_Calloc)(size_t nmemb, size_t size)REDISMODULE_ATTR; +REDISMODULE_API char *(*RedisModule_Strdup)(const char *str)REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_GetApi)(const char *, void *) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_CreateCommand)(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc cmdfunc, const char *strflags, int firstkey, int lastkey, int keystep) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_SetModuleAttribs)(RedisModuleCtx *ctx, const char *name, int ver, int apiver) REDISMODULE_ATTR; @@ -598,28 +547,28 @@ REDISMODULE_API int (*RedisModule_WrongArity)(RedisModuleCtx *ctx) REDISMODULE_A REDISMODULE_API int (*RedisModule_ReplyWithLongLong)(RedisModuleCtx *ctx, long long ll) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_GetSelectedDb)(RedisModuleCtx *ctx) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_SelectDb)(RedisModuleCtx *ctx, int newid) REDISMODULE_ATTR; -REDISMODULE_API void * (*RedisModule_OpenKey)(RedisModuleCtx *ctx, RedisModuleString *keyname, int mode) REDISMODULE_ATTR; +REDISMODULE_API void *(*RedisModule_OpenKey)(RedisModuleCtx *ctx, RedisModuleString *keyname, int mode)REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_CloseKey)(RedisModuleKey *kp) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_KeyType)(RedisModuleKey *kp) REDISMODULE_ATTR; REDISMODULE_API size_t (*RedisModule_ValueLength)(RedisModuleKey *kp) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_ListPush)(RedisModuleKey *kp, int where, RedisModuleString *ele) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString * (*RedisModule_ListPop)(RedisModuleKey *key, int where) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleCallReply * (*RedisModule_Call)(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...) REDISMODULE_ATTR; -REDISMODULE_API const char * (*RedisModule_CallReplyProto)(RedisModuleCallReply *reply, size_t *len) REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_ListPop)(RedisModuleKey *key, int where)REDISMODULE_ATTR; +REDISMODULE_API RedisModuleCallReply *(*RedisModule_Call)(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...)REDISMODULE_ATTR; +REDISMODULE_API const char *(*RedisModule_CallReplyProto)(RedisModuleCallReply *reply, size_t *len)REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_FreeCallReply)(RedisModuleCallReply *reply) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_CallReplyType)(RedisModuleCallReply *reply) REDISMODULE_ATTR; REDISMODULE_API long long (*RedisModule_CallReplyInteger)(RedisModuleCallReply *reply) REDISMODULE_ATTR; REDISMODULE_API size_t (*RedisModule_CallReplyLength)(RedisModuleCallReply *reply) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleCallReply * (*RedisModule_CallReplyArrayElement)(RedisModuleCallReply *reply, size_t idx) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString * (*RedisModule_CreateString)(RedisModuleCtx *ctx, const char *ptr, size_t len) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString * (*RedisModule_CreateStringFromLongLong)(RedisModuleCtx *ctx, long long ll) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString * (*RedisModule_CreateStringFromDouble)(RedisModuleCtx *ctx, double d) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString * (*RedisModule_CreateStringFromLongDouble)(RedisModuleCtx *ctx, long double ld, int humanfriendly) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString * (*RedisModule_CreateStringFromString)(RedisModuleCtx *ctx, const RedisModuleString *str) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString * (*RedisModule_CreateStringFromStreamID)(RedisModuleCtx *ctx, const RedisModuleStreamID *id) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString * (*RedisModule_CreateStringPrintf)(RedisModuleCtx *ctx, const char *fmt, ...) REDISMODULE_ATTR_PRINTF(2,3) REDISMODULE_ATTR; +REDISMODULE_API RedisModuleCallReply *(*RedisModule_CallReplyArrayElement)(RedisModuleCallReply *reply, size_t idx)REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_CreateString)(RedisModuleCtx *ctx, const char *ptr, size_t len)REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_CreateStringFromLongLong)(RedisModuleCtx *ctx, long long ll)REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_CreateStringFromDouble)(RedisModuleCtx *ctx, double d)REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_CreateStringFromLongDouble)(RedisModuleCtx *ctx, long double ld, int humanfriendly)REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_CreateStringFromString)(RedisModuleCtx *ctx, const RedisModuleString *str)REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_CreateStringFromStreamID)(RedisModuleCtx *ctx, const RedisModuleStreamID *id)REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_CreateStringPrintf)(RedisModuleCtx *ctx, const char *fmt, ...)REDISMODULE_ATTR_PRINTF(2, 3) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_FreeString)(RedisModuleCtx *ctx, RedisModuleString *str) REDISMODULE_ATTR; -REDISMODULE_API const char * (*RedisModule_StringPtrLen)(const RedisModuleString *str, size_t *len) REDISMODULE_ATTR; +REDISMODULE_API const char *(*RedisModule_StringPtrLen)(const RedisModuleString *str, size_t *len)REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_ReplyWithError)(RedisModuleCtx *ctx, const char *err) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_ReplyWithSimpleString)(RedisModuleCtx *ctx, const char *msg) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_ReplyWithArray)(RedisModuleCtx *ctx, long len) REDISMODULE_ATTR; @@ -642,12 +591,12 @@ REDISMODULE_API int (*RedisModule_StringToStreamID)(const RedisModuleString *str REDISMODULE_API void (*RedisModule_AutoMemory)(RedisModuleCtx *ctx) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_Replicate)(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_ReplicateVerbatim)(RedisModuleCtx *ctx) REDISMODULE_ATTR; -REDISMODULE_API const char * (*RedisModule_CallReplyStringPtr)(RedisModuleCallReply *reply, size_t *len) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString * (*RedisModule_CreateStringFromCallReply)(RedisModuleCallReply *reply) REDISMODULE_ATTR; +REDISMODULE_API const char *(*RedisModule_CallReplyStringPtr)(RedisModuleCallReply *reply, size_t *len)REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_CreateStringFromCallReply)(RedisModuleCallReply *reply)REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_DeleteKey)(RedisModuleKey *key) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_UnlinkKey)(RedisModuleKey *key) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_StringSet)(RedisModuleKey *key, RedisModuleString *str) REDISMODULE_ATTR; -REDISMODULE_API char * (*RedisModule_StringDMA)(RedisModuleKey *key, size_t *len, int mode) REDISMODULE_ATTR; +REDISMODULE_API char *(*RedisModule_StringDMA)(RedisModuleKey *key, size_t *len, int mode)REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_StringTruncate)(RedisModuleKey *key, size_t newlen) REDISMODULE_ATTR; REDISMODULE_API mstime_t (*RedisModule_GetExpire)(RedisModuleKey *key) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_SetExpire)(RedisModuleKey *key, mstime_t expire) REDISMODULE_ATTR; @@ -655,7 +604,7 @@ REDISMODULE_API mstime_t (*RedisModule_GetAbsExpire)(RedisModuleKey *key) REDISM REDISMODULE_API int (*RedisModule_SetAbsExpire)(RedisModuleKey *key, mstime_t expire) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_ResetDataset)(int restart_aof, int async) REDISMODULE_ATTR; REDISMODULE_API unsigned long long (*RedisModule_DbSize)(RedisModuleCtx *ctx) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString * (*RedisModule_RandomKey)(RedisModuleCtx *ctx) REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_RandomKey)(RedisModuleCtx *ctx)REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_ZsetAdd)(RedisModuleKey *key, double score, RedisModuleString *ele, int *flagsptr) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_ZsetIncrby)(RedisModuleKey *key, double score, RedisModuleString *ele, int *flagsptr, double *newscore) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_ZsetScore)(RedisModuleKey *key, RedisModuleString *ele, double *score) REDISMODULE_ATTR; @@ -665,7 +614,7 @@ REDISMODULE_API int (*RedisModule_ZsetFirstInScoreRange)(RedisModuleKey *key, do REDISMODULE_API int (*RedisModule_ZsetLastInScoreRange)(RedisModuleKey *key, double min, double max, int minex, int maxex) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_ZsetFirstInLexRange)(RedisModuleKey *key, RedisModuleString *min, RedisModuleString *max) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_ZsetLastInLexRange)(RedisModuleKey *key, RedisModuleString *min, RedisModuleString *max) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString * (*RedisModule_ZsetRangeCurrentElement)(RedisModuleKey *key, double *score) REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_ZsetRangeCurrentElement)(RedisModuleKey *key, double *score)REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_ZsetRangeNext)(RedisModuleKey *key) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_ZsetRangePrev)(RedisModuleKey *key) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_ZsetRangeEndReached)(RedisModuleKey *key) REDISMODULE_ATTR; @@ -683,17 +632,17 @@ REDISMODULE_API long long (*RedisModule_StreamTrimByID)(RedisModuleKey *key, int REDISMODULE_API int (*RedisModule_IsKeysPositionRequest)(RedisModuleCtx *ctx) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_KeyAtPos)(RedisModuleCtx *ctx, int pos) REDISMODULE_ATTR; REDISMODULE_API unsigned long long (*RedisModule_GetClientId)(RedisModuleCtx *ctx) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString * (*RedisModule_GetClientUserNameById)(RedisModuleCtx *ctx, uint64_t id) REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_GetClientUserNameById)(RedisModuleCtx *ctx, uint64_t id)REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_GetClientInfoById)(void *ci, uint64_t id) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_PublishMessage)(RedisModuleCtx *ctx, RedisModuleString *channel, RedisModuleString *message) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_GetContextFlags)(RedisModuleCtx *ctx) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_AvoidReplicaTraffic)() REDISMODULE_ATTR; -REDISMODULE_API void * (*RedisModule_PoolAlloc)(RedisModuleCtx *ctx, size_t bytes) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleType * (*RedisModule_CreateDataType)(RedisModuleCtx *ctx, const char *name, int encver, RedisModuleTypeMethods *typemethods) REDISMODULE_ATTR; +REDISMODULE_API void *(*RedisModule_PoolAlloc)(RedisModuleCtx *ctx, size_t bytes)REDISMODULE_ATTR; +REDISMODULE_API RedisModuleType *(*RedisModule_CreateDataType)(RedisModuleCtx *ctx, const char *name, int encver, RedisModuleTypeMethods *typemethods)REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_ModuleTypeSetValue)(RedisModuleKey *key, RedisModuleType *mt, void *value) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_ModuleTypeReplaceValue)(RedisModuleKey *key, RedisModuleType *mt, void *new_value, void **old_value) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleType * (*RedisModule_ModuleTypeGetType)(RedisModuleKey *key) REDISMODULE_ATTR; -REDISMODULE_API void * (*RedisModule_ModuleTypeGetValue)(RedisModuleKey *key) REDISMODULE_ATTR; +REDISMODULE_API RedisModuleType *(*RedisModule_ModuleTypeGetType)(RedisModuleKey *key)REDISMODULE_ATTR; +REDISMODULE_API void *(*RedisModule_ModuleTypeGetValue)(RedisModuleKey *key)REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_IsIOError)(RedisModuleIO *io) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_SetModuleOptions)(RedisModuleCtx *ctx, int options) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_SignalModifiedKey)(RedisModuleCtx *ctx, RedisModuleString *keyname) REDISMODULE_ATTR; @@ -704,59 +653,59 @@ REDISMODULE_API int64_t (*RedisModule_LoadSigned)(RedisModuleIO *io) REDISMODULE REDISMODULE_API void (*RedisModule_EmitAOF)(RedisModuleIO *io, const char *cmdname, const char *fmt, ...) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_SaveString)(RedisModuleIO *io, RedisModuleString *s) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_SaveStringBuffer)(RedisModuleIO *io, const char *str, size_t len) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString * (*RedisModule_LoadString)(RedisModuleIO *io) REDISMODULE_ATTR; -REDISMODULE_API char * (*RedisModule_LoadStringBuffer)(RedisModuleIO *io, size_t *lenptr) REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_LoadString)(RedisModuleIO *io)REDISMODULE_ATTR; +REDISMODULE_API char *(*RedisModule_LoadStringBuffer)(RedisModuleIO *io, size_t *lenptr)REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_SaveDouble)(RedisModuleIO *io, double value) REDISMODULE_ATTR; REDISMODULE_API double (*RedisModule_LoadDouble)(RedisModuleIO *io) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_SaveFloat)(RedisModuleIO *io, float value) REDISMODULE_ATTR; REDISMODULE_API float (*RedisModule_LoadFloat)(RedisModuleIO *io) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_SaveLongDouble)(RedisModuleIO *io, long double value) REDISMODULE_ATTR; REDISMODULE_API long double (*RedisModule_LoadLongDouble)(RedisModuleIO *io) REDISMODULE_ATTR; -REDISMODULE_API void * (*RedisModule_LoadDataTypeFromString)(const RedisModuleString *str, const RedisModuleType *mt) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString * (*RedisModule_SaveDataTypeToString)(RedisModuleCtx *ctx, void *data, const RedisModuleType *mt) REDISMODULE_ATTR; -REDISMODULE_API void (*RedisModule_Log)(RedisModuleCtx *ctx, const char *level, const char *fmt, ...) REDISMODULE_ATTR REDISMODULE_ATTR_PRINTF(3,4); -REDISMODULE_API void (*RedisModule_LogIOError)(RedisModuleIO *io, const char *levelstr, const char *fmt, ...) REDISMODULE_ATTR REDISMODULE_ATTR_PRINTF(3,4); +REDISMODULE_API void *(*RedisModule_LoadDataTypeFromString)(const RedisModuleString *str, const RedisModuleType *mt)REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_SaveDataTypeToString)(RedisModuleCtx *ctx, void *data, const RedisModuleType *mt)REDISMODULE_ATTR; +REDISMODULE_API void (*RedisModule_Log)(RedisModuleCtx *ctx, const char *level, const char *fmt, ...) REDISMODULE_ATTR REDISMODULE_ATTR_PRINTF(3, 4); +REDISMODULE_API void (*RedisModule_LogIOError)(RedisModuleIO *io, const char *levelstr, const char *fmt, ...) REDISMODULE_ATTR REDISMODULE_ATTR_PRINTF(3, 4); REDISMODULE_API void (*RedisModule__Assert)(const char *estr, const char *file, int line) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_LatencyAddSample)(const char *event, mstime_t latency) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_StringAppendBuffer)(RedisModuleCtx *ctx, RedisModuleString *str, const char *buf, size_t len) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_RetainString)(RedisModuleCtx *ctx, RedisModuleString *str) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString * (*RedisModule_HoldString)(RedisModuleCtx *ctx, RedisModuleString *str) REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_HoldString)(RedisModuleCtx *ctx, RedisModuleString *str)REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_StringCompare)(RedisModuleString *a, RedisModuleString *b) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleCtx * (*RedisModule_GetContextFromIO)(RedisModuleIO *io) REDISMODULE_ATTR; -REDISMODULE_API const RedisModuleString * (*RedisModule_GetKeyNameFromIO)(RedisModuleIO *io) REDISMODULE_ATTR; -REDISMODULE_API const RedisModuleString * (*RedisModule_GetKeyNameFromModuleKey)(RedisModuleKey *key) REDISMODULE_ATTR; +REDISMODULE_API RedisModuleCtx *(*RedisModule_GetContextFromIO)(RedisModuleIO *io)REDISMODULE_ATTR; +REDISMODULE_API const RedisModuleString *(*RedisModule_GetKeyNameFromIO)(RedisModuleIO *io)REDISMODULE_ATTR; +REDISMODULE_API const RedisModuleString *(*RedisModule_GetKeyNameFromModuleKey)(RedisModuleKey *key)REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_GetDbIdFromModuleKey)(RedisModuleKey *key) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_GetDbIdFromIO)(RedisModuleIO *io) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_GetDbIdFromOptCtx)(RedisModuleKeyOptCtx *ctx) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_GetToDbIdFromOptCtx)(RedisModuleKeyOptCtx *ctx) REDISMODULE_ATTR; -REDISMODULE_API const RedisModuleString * (*RedisModule_GetKeyNameFromOptCtx)(RedisModuleKeyOptCtx *ctx) REDISMODULE_ATTR; -REDISMODULE_API const RedisModuleString * (*RedisModule_GetToKeyNameFromOptCtx)(RedisModuleKeyOptCtx *ctx) REDISMODULE_ATTR; +REDISMODULE_API const RedisModuleString *(*RedisModule_GetKeyNameFromOptCtx)(RedisModuleKeyOptCtx *ctx)REDISMODULE_ATTR; +REDISMODULE_API const RedisModuleString *(*RedisModule_GetToKeyNameFromOptCtx)(RedisModuleKeyOptCtx *ctx)REDISMODULE_ATTR; REDISMODULE_API long long (*RedisModule_Milliseconds)(void) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_DigestAddStringBuffer)(RedisModuleDigest *md, unsigned char *ele, size_t len) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_DigestAddLongLong)(RedisModuleDigest *md, long long ele) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_DigestEndSequence)(RedisModuleDigest *md) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_GetDbIdFromDigest)(RedisModuleDigest *dig) REDISMODULE_ATTR; -REDISMODULE_API const RedisModuleString * (*RedisModule_GetKeyNameFromDigest)(RedisModuleDigest *dig) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleDict * (*RedisModule_CreateDict)(RedisModuleCtx *ctx) REDISMODULE_ATTR; +REDISMODULE_API const RedisModuleString *(*RedisModule_GetKeyNameFromDigest)(RedisModuleDigest *dig)REDISMODULE_ATTR; +REDISMODULE_API RedisModuleDict *(*RedisModule_CreateDict)(RedisModuleCtx *ctx)REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_FreeDict)(RedisModuleCtx *ctx, RedisModuleDict *d) REDISMODULE_ATTR; REDISMODULE_API uint64_t (*RedisModule_DictSize)(RedisModuleDict *d) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_DictSetC)(RedisModuleDict *d, void *key, size_t keylen, void *ptr) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_DictReplaceC)(RedisModuleDict *d, void *key, size_t keylen, void *ptr) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_DictSet)(RedisModuleDict *d, RedisModuleString *key, void *ptr) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_DictReplace)(RedisModuleDict *d, RedisModuleString *key, void *ptr) REDISMODULE_ATTR; -REDISMODULE_API void * (*RedisModule_DictGetC)(RedisModuleDict *d, void *key, size_t keylen, int *nokey) REDISMODULE_ATTR; -REDISMODULE_API void * (*RedisModule_DictGet)(RedisModuleDict *d, RedisModuleString *key, int *nokey) REDISMODULE_ATTR; +REDISMODULE_API void *(*RedisModule_DictGetC)(RedisModuleDict *d, void *key, size_t keylen, int *nokey)REDISMODULE_ATTR; +REDISMODULE_API void *(*RedisModule_DictGet)(RedisModuleDict *d, RedisModuleString *key, int *nokey)REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_DictDelC)(RedisModuleDict *d, void *key, size_t keylen, void *oldval) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_DictDel)(RedisModuleDict *d, RedisModuleString *key, void *oldval) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleDictIter * (*RedisModule_DictIteratorStartC)(RedisModuleDict *d, const char *op, void *key, size_t keylen) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleDictIter * (*RedisModule_DictIteratorStart)(RedisModuleDict *d, const char *op, RedisModuleString *key) REDISMODULE_ATTR; +REDISMODULE_API RedisModuleDictIter *(*RedisModule_DictIteratorStartC)(RedisModuleDict *d, const char *op, void *key, size_t keylen)REDISMODULE_ATTR; +REDISMODULE_API RedisModuleDictIter *(*RedisModule_DictIteratorStart)(RedisModuleDict *d, const char *op, RedisModuleString *key)REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_DictIteratorStop)(RedisModuleDictIter *di) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_DictIteratorReseekC)(RedisModuleDictIter *di, const char *op, void *key, size_t keylen) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_DictIteratorReseek)(RedisModuleDictIter *di, const char *op, RedisModuleString *key) REDISMODULE_ATTR; -REDISMODULE_API void * (*RedisModule_DictNextC)(RedisModuleDictIter *di, size_t *keylen, void **dataptr) REDISMODULE_ATTR; -REDISMODULE_API void * (*RedisModule_DictPrevC)(RedisModuleDictIter *di, size_t *keylen, void **dataptr) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString * (*RedisModule_DictNext)(RedisModuleCtx *ctx, RedisModuleDictIter *di, void **dataptr) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString * (*RedisModule_DictPrev)(RedisModuleCtx *ctx, RedisModuleDictIter *di, void **dataptr) REDISMODULE_ATTR; +REDISMODULE_API void *(*RedisModule_DictNextC)(RedisModuleDictIter *di, size_t *keylen, void **dataptr)REDISMODULE_ATTR; +REDISMODULE_API void *(*RedisModule_DictPrevC)(RedisModuleDictIter *di, size_t *keylen, void **dataptr)REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_DictNext)(RedisModuleCtx *ctx, RedisModuleDictIter *di, void **dataptr)REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_DictPrev)(RedisModuleCtx *ctx, RedisModuleDictIter *di, void **dataptr)REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_DictCompareC)(RedisModuleDictIter *di, const char *op, void *key, size_t keylen) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_DictCompare)(RedisModuleDictIter *di, const char *op, RedisModuleString *key) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_RegisterInfoFunc)(RedisModuleCtx *ctx, RedisModuleInfoFunc cb) REDISMODULE_ATTR; @@ -768,22 +717,22 @@ REDISMODULE_API int (*RedisModule_InfoAddFieldCString)(RedisModuleInfoCtx *ctx, REDISMODULE_API int (*RedisModule_InfoAddFieldDouble)(RedisModuleInfoCtx *ctx, char *field, double value) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_InfoAddFieldLongLong)(RedisModuleInfoCtx *ctx, char *field, long long value) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_InfoAddFieldULongLong)(RedisModuleInfoCtx *ctx, char *field, unsigned long long value) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleServerInfoData * (*RedisModule_GetServerInfo)(RedisModuleCtx *ctx, const char *section) REDISMODULE_ATTR; +REDISMODULE_API RedisModuleServerInfoData *(*RedisModule_GetServerInfo)(RedisModuleCtx *ctx, const char *section)REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_FreeServerInfo)(RedisModuleCtx *ctx, RedisModuleServerInfoData *data) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString * (*RedisModule_ServerInfoGetField)(RedisModuleCtx *ctx, RedisModuleServerInfoData *data, const char* field) REDISMODULE_ATTR; -REDISMODULE_API const char * (*RedisModule_ServerInfoGetFieldC)(RedisModuleServerInfoData *data, const char* field) REDISMODULE_ATTR; -REDISMODULE_API long long (*RedisModule_ServerInfoGetFieldSigned)(RedisModuleServerInfoData *data, const char* field, int *out_err) REDISMODULE_ATTR; -REDISMODULE_API unsigned long long (*RedisModule_ServerInfoGetFieldUnsigned)(RedisModuleServerInfoData *data, const char* field, int *out_err) REDISMODULE_ATTR; -REDISMODULE_API double (*RedisModule_ServerInfoGetFieldDouble)(RedisModuleServerInfoData *data, const char* field, int *out_err) REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_ServerInfoGetField)(RedisModuleCtx *ctx, RedisModuleServerInfoData *data, const char *field)REDISMODULE_ATTR; +REDISMODULE_API const char *(*RedisModule_ServerInfoGetFieldC)(RedisModuleServerInfoData *data, const char *field)REDISMODULE_ATTR; +REDISMODULE_API long long (*RedisModule_ServerInfoGetFieldSigned)(RedisModuleServerInfoData *data, const char *field, int *out_err) REDISMODULE_ATTR; +REDISMODULE_API unsigned long long (*RedisModule_ServerInfoGetFieldUnsigned)(RedisModuleServerInfoData *data, const char *field, int *out_err) REDISMODULE_ATTR; +REDISMODULE_API double (*RedisModule_ServerInfoGetFieldDouble)(RedisModuleServerInfoData *data, const char *field, int *out_err) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_SubscribeToServerEvent)(RedisModuleCtx *ctx, RedisModuleEvent event, RedisModuleEventCallback callback) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_SetLRU)(RedisModuleKey *key, mstime_t lru_idle) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_GetLRU)(RedisModuleKey *key, mstime_t *lru_idle) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_SetLFU)(RedisModuleKey *key, long long lfu_freq) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_GetLFU)(RedisModuleKey *key, long long *lfu_freq) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleBlockedClient * (*RedisModule_BlockClientOnKeys)(RedisModuleCtx *ctx, RedisModuleCmdFunc reply_callback, RedisModuleCmdFunc timeout_callback, void (*free_privdata)(RedisModuleCtx*,void*), long long timeout_ms, RedisModuleString **keys, int numkeys, void *privdata) REDISMODULE_ATTR; +REDISMODULE_API RedisModuleBlockedClient *(*RedisModule_BlockClientOnKeys)(RedisModuleCtx *ctx, RedisModuleCmdFunc reply_callback, RedisModuleCmdFunc timeout_callback, void (*free_privdata)(RedisModuleCtx *, void *), long long timeout_ms, RedisModuleString **keys, int numkeys, void *privdata)REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_SignalKeyAsReady)(RedisModuleCtx *ctx, RedisModuleString *key) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString * (*RedisModule_GetBlockedClientReadyKey)(RedisModuleCtx *ctx) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleScanCursor * (*RedisModule_ScanCursorCreate)() REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_GetBlockedClientReadyKey)(RedisModuleCtx *ctx)REDISMODULE_ATTR; +REDISMODULE_API RedisModuleScanCursor *(*RedisModule_ScanCursorCreate)() REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_ScanCursorRestart)(RedisModuleScanCursor *cursor) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_ScanCursorDestroy)(RedisModuleScanCursor *cursor) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_Scan)(RedisModuleCtx *ctx, RedisModuleScanCursor *cursor, RedisModuleScanCB fn, void *privdata) REDISMODULE_ATTR; @@ -797,17 +746,17 @@ REDISMODULE_API int (*RedisModule_GetTypeMethodVersion)() REDISMODULE_ATTR; /* Experimental APIs */ #ifdef REDISMODULE_EXPERIMENTAL_API #define REDISMODULE_EXPERIMENTAL_API_VERSION 3 -REDISMODULE_API RedisModuleBlockedClient * (*RedisModule_BlockClient)(RedisModuleCtx *ctx, RedisModuleCmdFunc reply_callback, RedisModuleCmdFunc timeout_callback, void (*free_privdata)(RedisModuleCtx*,void*), long long timeout_ms) REDISMODULE_ATTR; +REDISMODULE_API RedisModuleBlockedClient *(*RedisModule_BlockClient)(RedisModuleCtx *ctx, RedisModuleCmdFunc reply_callback, RedisModuleCmdFunc timeout_callback, void (*free_privdata)(RedisModuleCtx *, void *), long long timeout_ms)REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_UnblockClient)(RedisModuleBlockedClient *bc, void *privdata) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_IsBlockedReplyRequest)(RedisModuleCtx *ctx) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_IsBlockedTimeoutRequest)(RedisModuleCtx *ctx) REDISMODULE_ATTR; -REDISMODULE_API void * (*RedisModule_GetBlockedClientPrivateData)(RedisModuleCtx *ctx) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleBlockedClient * (*RedisModule_GetBlockedClientHandle)(RedisModuleCtx *ctx) REDISMODULE_ATTR; +REDISMODULE_API void *(*RedisModule_GetBlockedClientPrivateData)(RedisModuleCtx *ctx)REDISMODULE_ATTR; +REDISMODULE_API RedisModuleBlockedClient *(*RedisModule_GetBlockedClientHandle)(RedisModuleCtx *ctx)REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_AbortBlock)(RedisModuleBlockedClient *bc) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_BlockedClientMeasureTimeStart)(RedisModuleBlockedClient *bc) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_BlockedClientMeasureTimeEnd)(RedisModuleBlockedClient *bc) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleCtx * (*RedisModule_GetThreadSafeContext)(RedisModuleBlockedClient *bc) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleCtx * (*RedisModule_GetDetachedThreadSafeContext)(RedisModuleCtx *ctx) REDISMODULE_ATTR; +REDISMODULE_API RedisModuleCtx *(*RedisModule_GetThreadSafeContext)(RedisModuleBlockedClient *bc)REDISMODULE_ATTR; +REDISMODULE_API RedisModuleCtx *(*RedisModule_GetDetachedThreadSafeContext)(RedisModuleCtx *ctx)REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_FreeThreadSafeContext)(RedisModuleCtx *ctx) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_ThreadSafeContextLock)(RedisModuleCtx *ctx) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_ThreadSafeContextTryLock)(RedisModuleCtx *ctx) REDISMODULE_ATTR; @@ -819,23 +768,23 @@ REDISMODULE_API int (*RedisModule_BlockedClientDisconnected)(RedisModuleCtx *ctx REDISMODULE_API void (*RedisModule_RegisterClusterMessageReceiver)(RedisModuleCtx *ctx, uint8_t type, RedisModuleClusterMessageReceiver callback) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_SendClusterMessage)(RedisModuleCtx *ctx, char *target_id, uint8_t type, unsigned char *msg, uint32_t len) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_GetClusterNodeInfo)(RedisModuleCtx *ctx, const char *id, char *ip, char *master_id, int *port, int *flags) REDISMODULE_ATTR; -REDISMODULE_API char ** (*RedisModule_GetClusterNodesList)(RedisModuleCtx *ctx, size_t *numnodes) REDISMODULE_ATTR; +REDISMODULE_API char **(*RedisModule_GetClusterNodesList)(RedisModuleCtx *ctx, size_t *numnodes)REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_FreeClusterNodesList)(char **ids) REDISMODULE_ATTR; REDISMODULE_API RedisModuleTimerID (*RedisModule_CreateTimer)(RedisModuleCtx *ctx, mstime_t period, RedisModuleTimerProc callback, void *data) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_StopTimer)(RedisModuleCtx *ctx, RedisModuleTimerID id, void **data) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_GetTimerInfo)(RedisModuleCtx *ctx, RedisModuleTimerID id, uint64_t *remaining, void **data) REDISMODULE_ATTR; -REDISMODULE_API const char * (*RedisModule_GetMyClusterID)(void) REDISMODULE_ATTR; +REDISMODULE_API const char *(*RedisModule_GetMyClusterID)(void)REDISMODULE_ATTR; REDISMODULE_API size_t (*RedisModule_GetClusterSize)(void) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_GetRandomBytes)(unsigned char *dst, size_t len) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_GetRandomHexChars)(char *dst, size_t len) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_SetDisconnectCallback)(RedisModuleBlockedClient *bc, RedisModuleDisconnectFunc callback) REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_SetClusterFlags)(RedisModuleCtx *ctx, uint64_t flags) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_ExportSharedAPI)(RedisModuleCtx *ctx, const char *apiname, void *func) REDISMODULE_ATTR; -REDISMODULE_API void * (*RedisModule_GetSharedAPI)(RedisModuleCtx *ctx, const char *apiname) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleCommandFilter * (*RedisModule_RegisterCommandFilter)(RedisModuleCtx *ctx, RedisModuleCommandFilterFunc cb, int flags) REDISMODULE_ATTR; +REDISMODULE_API void *(*RedisModule_GetSharedAPI)(RedisModuleCtx *ctx, const char *apiname)REDISMODULE_ATTR; +REDISMODULE_API RedisModuleCommandFilter *(*RedisModule_RegisterCommandFilter)(RedisModuleCtx *ctx, RedisModuleCommandFilterFunc cb, int flags)REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_UnregisterCommandFilter)(RedisModuleCtx *ctx, RedisModuleCommandFilter *filter) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_CommandFilterArgsCount)(RedisModuleCommandFilterCtx *fctx) REDISMODULE_ATTR; -REDISMODULE_API const RedisModuleString * (*RedisModule_CommandFilterArgGet)(RedisModuleCommandFilterCtx *fctx, int pos) REDISMODULE_ATTR; +REDISMODULE_API const RedisModuleString *(*RedisModule_CommandFilterArgGet)(RedisModuleCommandFilterCtx *fctx, int pos)REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_CommandFilterArgInsert)(RedisModuleCommandFilterCtx *fctx, int pos, RedisModuleString *arg) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_CommandFilterArgReplace)(RedisModuleCommandFilterCtx *fctx, int pos, RedisModuleString *arg) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_CommandFilterArgDelete)(RedisModuleCommandFilterCtx *fctx, int pos) REDISMODULE_ATTR; @@ -844,24 +793,24 @@ REDISMODULE_API void (*RedisModule_SendChildHeartbeat)(double progress) REDISMOD REDISMODULE_API int (*RedisModule_ExitFromChild)(int retcode) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_KillForkChild)(int child_pid) REDISMODULE_ATTR; REDISMODULE_API float (*RedisModule_GetUsedMemoryRatio)() REDISMODULE_ATTR; -REDISMODULE_API size_t (*RedisModule_MallocSize)(void* ptr) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleUser * (*RedisModule_CreateModuleUser)(const char *name) REDISMODULE_ATTR; +REDISMODULE_API size_t (*RedisModule_MallocSize)(void *ptr) REDISMODULE_ATTR; +REDISMODULE_API RedisModuleUser *(*RedisModule_CreateModuleUser)(const char *name)REDISMODULE_ATTR; REDISMODULE_API void (*RedisModule_FreeModuleUser)(RedisModuleUser *user) REDISMODULE_ATTR; -REDISMODULE_API int (*RedisModule_SetModuleUserACL)(RedisModuleUser *user, const char* acl) REDISMODULE_ATTR; +REDISMODULE_API int (*RedisModule_SetModuleUserACL)(RedisModuleUser *user, const char *acl) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_AuthenticateClientWithACLUser)(RedisModuleCtx *ctx, const char *name, size_t len, RedisModuleUserChangedFunc callback, void *privdata, uint64_t *client_id) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_AuthenticateClientWithUser)(RedisModuleCtx *ctx, RedisModuleUser *user, RedisModuleUserChangedFunc callback, void *privdata, uint64_t *client_id) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_DeauthenticateAndCloseClient)(RedisModuleCtx *ctx, uint64_t client_id) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString * (*RedisModule_GetClientCertificate)(RedisModuleCtx *ctx, uint64_t id) REDISMODULE_ATTR; -REDISMODULE_API int *(*RedisModule_GetCommandKeys)(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, int *num_keys) REDISMODULE_ATTR; -REDISMODULE_API const char *(*RedisModule_GetCurrentCommandName)(RedisModuleCtx *ctx) REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_GetClientCertificate)(RedisModuleCtx *ctx, uint64_t id)REDISMODULE_ATTR; +REDISMODULE_API int *(*RedisModule_GetCommandKeys)(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, int *num_keys)REDISMODULE_ATTR; +REDISMODULE_API const char *(*RedisModule_GetCurrentCommandName)(RedisModuleCtx *ctx)REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_RegisterDefragFunc)(RedisModuleCtx *ctx, RedisModuleDefragFunc func) REDISMODULE_ATTR; -REDISMODULE_API void *(*RedisModule_DefragAlloc)(RedisModuleDefragCtx *ctx, void *ptr) REDISMODULE_ATTR; -REDISMODULE_API RedisModuleString *(*RedisModule_DefragRedisModuleString)(RedisModuleDefragCtx *ctx, RedisModuleString *str) REDISMODULE_ATTR; +REDISMODULE_API void *(*RedisModule_DefragAlloc)(RedisModuleDefragCtx *ctx, void *ptr)REDISMODULE_ATTR; +REDISMODULE_API RedisModuleString *(*RedisModule_DefragRedisModuleString)(RedisModuleDefragCtx *ctx, RedisModuleString *str)REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_DefragShouldStop)(RedisModuleDefragCtx *ctx) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_DefragCursorSet)(RedisModuleDefragCtx *ctx, unsigned long cursor) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_DefragCursorGet)(RedisModuleDefragCtx *ctx, unsigned long *cursor) REDISMODULE_ATTR; REDISMODULE_API int (*RedisModule_GetDbIdFromDefragCtx)(RedisModuleDefragCtx *ctx) REDISMODULE_ATTR; -REDISMODULE_API const RedisModuleString * (*RedisModule_GetKeyNameFromDefragCtx)(RedisModuleDefragCtx *ctx) REDISMODULE_ATTR; +REDISMODULE_API const RedisModuleString *(*RedisModule_GetKeyNameFromDefragCtx)(RedisModuleDefragCtx *ctx)REDISMODULE_ATTR; #endif #define RedisModule_IsAOFClient(id) ((id) == UINT64_MAX) @@ -869,8 +818,8 @@ REDISMODULE_API const RedisModuleString * (*RedisModule_GetKeyNameFromDefragCtx) /* This is included inline inside each Redis module. */ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int apiver) REDISMODULE_ATTR_UNUSED; static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int apiver) { - void *getapifuncptr = ((void**)ctx)[0]; - RedisModule_GetApi = (int (*)(const char *, void *)) (unsigned long)getapifuncptr; + void *getapifuncptr = ((void **)ctx)[0]; + RedisModule_GetApi = (int (*)(const char *, void *))(unsigned long)getapifuncptr; REDISMODULE_GET_API(Alloc); REDISMODULE_GET_API(Calloc); REDISMODULE_GET_API(Free); @@ -1148,11 +1097,11 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int #endif if (RedisModule_IsModuleNameBusy && RedisModule_IsModuleNameBusy(name)) return REDISMODULE_ERR; - RedisModule_SetModuleAttribs(ctx,name,ver,apiver); + RedisModule_SetModuleAttribs(ctx, name, ver, apiver); return REDISMODULE_OK; } -#define RedisModule_Assert(_e) ((_e)?(void)0 : (RedisModule__Assert(#_e,__FILE__,__LINE__),exit(1))) +#define RedisModule_Assert(_e) ((_e) ? (void)0 : (RedisModule__Assert(#_e, __FILE__, __LINE__), exit(1))) #define RMAPI_FUNC_SUPPORTED(func) (func != NULL) diff --git a/src/tairhash.c b/src/tairhash.c index 2fd1785..03cb361 100755 --- a/src/tairhash.c +++ b/src/tairhash.c @@ -605,7 +605,7 @@ void activeExpireTimerHandler(RedisModuleCtx *ctx, void *data) { // clang-format off stat_last_active_expire_time_msec = RedisModule_Milliseconds() - start; - stat_max_active_expire_time_msec = stat_max_active_expire_time_msec < stat_last_active_expire_time_msec ? + stat_max_active_expire_time_msec = stat_max_active_expire_time_msec < stat_last_active_expire_time_msec ? stat_last_active_expire_time_msec : stat_max_active_expire_time_msec; total_expire_time += stat_last_active_expire_time_msec; ++loop_cnt; @@ -946,7 +946,7 @@ int tairHashExpireGenericFunc(RedisModuleCtx *ctx, RedisModuleString **argv, int ex_flags |= TAIR_HASH_SET_WITH_VER; version_p = next; j++; - } else if (!mstrcasecmp(argv[4], "abs") && !(ex_flags & TAIR_HASH_SET_WITH_VER) && !(ex_flags & TAIR_HASH_SET_WITH_GT_VER) && next) { + } else if (!mstrcasecmp(argv[4], "abs") && !(ex_flags & TAIR_HASH_SET_WITH_VER) && !(ex_flags & TAIR_HASH_SET_WITH_GT_VER) && next) { ex_flags |= TAIR_HASH_SET_WITH_ABS_VER; version_p = next; j++; @@ -1037,7 +1037,7 @@ int tairHashExpireGenericFunc(RedisModuleCtx *ctx, RedisModuleString **argv, int if (ex_flags & (TAIR_HASH_SET_WITH_ABS_VER | TAIR_HASH_SET_WITH_GT_VER)) { tair_hash_val->version = version; } else { - tair_hash_val->version += 1; + tair_hash_val->version += 1; } size_t vlen = 0, VSIZE_MAX = 5; @@ -1789,7 +1789,7 @@ int TairHashTypeHincrBy_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **ar ex_flags |= TAIR_HASH_SET_ABS_EXPIRE; expire_p = next; j++; - } else if (!mstrcasecmp(argv[j], "ver") && !(ex_flags & TAIR_HASH_SET_WITH_ABS_VER) && !(ex_flags & TAIR_HASH_SET_WITH_GT_VER) && next) { + } else if (!mstrcasecmp(argv[j], "ver") && !(ex_flags & TAIR_HASH_SET_WITH_ABS_VER) && !(ex_flags & TAIR_HASH_SET_WITH_GT_VER) && next) { ex_flags |= TAIR_HASH_SET_WITH_VER; version_p = next; j++; @@ -1797,7 +1797,7 @@ int TairHashTypeHincrBy_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **ar ex_flags |= TAIR_HASH_SET_WITH_ABS_VER; version_p = next; j++; - } else if (!mstrcasecmp(argv[j], "gt") && !(ex_flags & TAIR_HASH_SET_WITH_VER) && !(ex_flags & TAIR_HASH_SET_WITH_ABS_VER) && next) { + } else if (!mstrcasecmp(argv[j], "gt") && !(ex_flags & TAIR_HASH_SET_WITH_VER) && !(ex_flags & TAIR_HASH_SET_WITH_ABS_VER) && next) { ex_flags |= TAIR_HASH_SET_WITH_GT_VER; version_p = next; j++; @@ -1893,7 +1893,7 @@ int TairHashTypeHincrBy_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **ar if (version != 0 && version != tair_hash_val->version) { RedisModule_ReplyWithError(ctx, TAIRHASH_ERRORMSG_VERSION); return REDISMODULE_ERR; - } + } } else if (ex_flags & TAIR_HASH_SET_WITH_GT_VER) { if (version <= tair_hash_val->version) { RedisModule_ReplyWithError(ctx, TAIRHASH_ERRORMSG_VERSION); @@ -2019,7 +2019,7 @@ int TairHashTypeHincrByFloat_RedisCommand(RedisModuleCtx *ctx, RedisModuleString ex_flags |= TAIR_HASH_SET_ABS_EXPIRE; expire_p = next; j++; - } else if (!mstrcasecmp(argv[j], "ver") && !(ex_flags & TAIR_HASH_SET_WITH_ABS_VER) && !(ex_flags & TAIR_HASH_SET_WITH_GT_VER) && next) { + } else if (!mstrcasecmp(argv[j], "ver") && !(ex_flags & TAIR_HASH_SET_WITH_ABS_VER) && !(ex_flags & TAIR_HASH_SET_WITH_GT_VER) && next) { ex_flags |= TAIR_HASH_SET_WITH_VER; version_p = next; j++; @@ -2027,7 +2027,7 @@ int TairHashTypeHincrByFloat_RedisCommand(RedisModuleCtx *ctx, RedisModuleString ex_flags |= TAIR_HASH_SET_WITH_ABS_VER; version_p = next; j++; - } else if (!mstrcasecmp(argv[j], "gt") && !(ex_flags & TAIR_HASH_SET_WITH_VER) && !(ex_flags & TAIR_HASH_SET_WITH_ABS_VER) && next) { + } else if (!mstrcasecmp(argv[j], "gt") && !(ex_flags & TAIR_HASH_SET_WITH_VER) && !(ex_flags & TAIR_HASH_SET_WITH_ABS_VER) && next) { ex_flags |= TAIR_HASH_SET_WITH_GT_VER; version_p = next; j++; @@ -2887,8 +2887,7 @@ int TairHashTypeHvals_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv return REDISMODULE_OK; } -/* EXHGETALL key */ -int TairHashTypeHgetAll_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { +int tairHashGetAllGenericFunc(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, int returnVer) { RedisModule_AutoMemory(ctx); if (argc != 2) { @@ -2947,6 +2946,10 @@ int TairHashTypeHgetAll_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **ar cn++; RedisModule_ReplyWithString(ctx, data->value); cn++; + if (returnVer > 0) { + RedisModule_ReplyWithLongLong(ctx, data->version); + cn++; + } } m_dictReleaseIterator(di); @@ -2957,6 +2960,16 @@ int TairHashTypeHgetAll_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **ar return REDISMODULE_OK; } +/* EXHGETALL key */ +int TairHashTypeHgetAll_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { + return tairHashGetAllGenericFunc(ctx, argv, argc, 0); +} + +/* EXHGETALLWITHVER key */ +int TairHashTypeHgetAllWithVer_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { + return tairHashGetAllGenericFunc(ctx, argv, argc, 1); +} + static int parseScanCursor(RedisModuleString *cs, unsigned long *cursor) { char *eptr; @@ -3395,6 +3408,7 @@ int Module_CreateCommands(RedisModuleCtx *ctx) { CREATE_ROCMD("exhkeys", TairHashTypeHkeys_RedisCommand) CREATE_ROCMD("exhvals", TairHashTypeHvals_RedisCommand) CREATE_ROCMD("exhgetall", TairHashTypeHgetAll_RedisCommand) + CREATE_ROCMD("exhgetallwithver", TairHashTypeHgetAllWithVer_RedisCommand) CREATE_ROCMD("exhmget", TairHashTypeHmget_RedisCommand) CREATE_ROCMD("exhmgetwithver", TairHashTypeHmgetWithVer_RedisCommand) CREATE_ROCMD("exhscan", TairHashTypeHscan_RedisCommand) diff --git a/tests/tairhash.tcl b/tests/tairhash.tcl index 79e00f2..680dbea 100755 --- a/tests/tairhash.tcl +++ b/tests/tairhash.tcl @@ -425,7 +425,7 @@ start_server {tags {"tairhash"} overrides {bind 0.0.0.0}} { create_big_tairhash_with_expire k2 10000 100 create_big_tairhash_with_expire k3 10000 100 - r flushall async + r flushall async assert_equal 0 [r dbsize] @@ -461,7 +461,7 @@ start_server {tags {"tairhash"} overrides {bind 0.0.0.0}} { r rename exk2 exk2_2 after 3000 - assert_equal 0 [r dbsize] + assert_equal 0 [r dbsize] } test {Move with active expire} { @@ -482,9 +482,9 @@ start_server {tags {"tairhash"} overrides {bind 0.0.0.0}} { assert_equal 2 [r dbsize] after 3000 - assert_equal 0 [r dbsize] - r select 8 - assert_equal 0 [r dbsize] + assert_equal 0 [r dbsize] + r select 8 + assert_equal 0 [r dbsize] } test {Active expire rdb} { @@ -516,7 +516,7 @@ start_server {tags {"tairhash"} overrides {bind 0.0.0.0}} { set ret_val [r exhget tairhashkey field1] assert_equal val $ret_val - + r bgsave waitForBgsave r r debug reload @@ -560,9 +560,9 @@ start_server {tags {"tairhash"} overrides {bind 0.0.0.0}} { # r select 7 # r del tairhashkey # create_big_tairhash_with_expire tairhashkey 10 2 - + # r swapdb 7 13 - # r swapdb 13 14 + # r swapdb 13 14 # r select 14 # assert_equal 1 [r dbsize] @@ -1066,7 +1066,7 @@ start_server {tags {"tairhash"} overrides {bind 0.0.0.0}} { lappend rv [string match "ERR*not*float*" $bigerr] } {1 1} - test {Exhkeys / exhvals / exhgetall basic} { + test {Exhkeys / exhvals / exhgetall / exhgetallwithver basic} { r del tairhashkey array set tairhashkeyh {} @@ -1090,9 +1090,10 @@ start_server {tags {"tairhash"} overrides {bind 0.0.0.0}} { assert_equal [lsort [r exhvals tairhashkey]] [lsort $expected_vals] assert_equal [lsort [r exhgetall tairhashkey]] [lsort [array get tairhashkey]] assert_equal [] [r exhgetall tairhashkey_noexists] + assert_equal [] [r exhgetallwithver tairhashkey_noexists] } - test {Exhkeys / exhvals / exhgetall while expired fields exist} { + test {Exhkeys / exhvals / exhgetall / exhgetallwithver while expired fields exist} { r del tairhashkey assert_equal 1 [r exhset tairhashkey field1 val1 PX 100] assert_equal 1 [r exhset tairhashkey field2 val2 PX 200] @@ -1101,12 +1102,14 @@ start_server {tags {"tairhash"} overrides {bind 0.0.0.0}} { assert_equal [lsort [r exhvals tairhashkey]] [lsort {val1 val2 val3}] assert_equal [lsort [r exhkeys tairhashkey]] [lsort {field1 field2 field3}] assert_equal [lsort [r exhgetall tairhashkey]] [lsort {field1 val1 field2 val2 field3 val3}] + assert_equal [lsort [r exhgetallwithver tairhashkey]] [lsort {field1 val1 1 field2 val2 1 field3 val3 1}] after 300 assert_equal [lsort [r exhvals tairhashkey]] [lsort {val3}] assert_equal [lsort [r exhkeys tairhashkey]] [lsort {field3}] assert_equal [lsort [r exhgetall tairhashkey]] [lsort {field3 val3}] + assert_equal [lsort [r exhgetallwithver tairhashkey]] [lsort {field3 val3 1}] } test {Exhmget} { @@ -1277,7 +1280,7 @@ start_server {tags {"tairhash"} overrides {bind 0.0.0.0}} { # r select 11 # assert_equal 3 [r dbsize] # after 3000 - # assert_equal 0 [r dbsize] + # assert_equal 0 [r dbsize] # set info [r exhexpireinfo] # assert { [string match "*db: 11, active_expired_fields: 30*" $info] } @@ -1292,7 +1295,7 @@ start_server {tags {"tairhash"} overrides {bind 0.0.0.0}} { # r swapdb 12 10 # after 3000 - # assert_equal 0 [r dbsize] + # assert_equal 0 [r dbsize] # set info [r exhexpireinfo] # assert { [string match "*db: 10, active_expired_fields: 60*db: 12, active_expired_fields: 30*" $info] } # } @@ -1423,7 +1426,7 @@ start_server {tags {"tairhash"} overrides {bind 0.0.0.0}} { assert_equal 1 [r exhset tairhashkey field1 val1 EX 1] assert_equal 1 [r exhset tairhashkey field2 val2 EX 1] - + assert_equal 1 [r exhpersist tairhashkey field1] after 3000 @@ -1577,7 +1580,7 @@ start_server {tags {"tairhash"} overrides {bind 0.0.0.0}} { assert_equal -1 [r exhttl exhashkey field] r del exhashkey - + assert_equal 1 [r exhset exhashkey field val ex 3] assert_equal 0 [r exhset exhashkey field val keepttl] set ttl [r exhttl exhashkey field] @@ -1600,7 +1603,7 @@ start_server {tags {"tairhash"} overrides {bind 0.0.0.0}} { assert_equal -1 [r exhttl exhashkey field] r del exhashkey - + assert_equal 1 [r exhincrby exhashkey field 1 ex 3] assert_equal 2 [r exhincrby exhashkey field 1 keepttl] set ttl [r exhttl exhashkey field] @@ -1623,7 +1626,7 @@ start_server {tags {"tairhash"} overrides {bind 0.0.0.0}} { assert_equal -1 [r exhttl exhashkey field] r del exhashkey - + assert_equal 1 [r exhincrbyfloat exhashkey field 1 ex 3] assert_equal 2 [r exhincrbyfloat exhashkey field 1 keepttl] set ttl [r exhttl exhashkey field] @@ -1659,7 +1662,7 @@ start_server {tags {"tairhash"} overrides {bind 0.0.0.0}} { r del exhashkey r select 1 r del exhashkey2 - + set rd1 [redis_deferring_client] set rd2 [redis_deferring_client] @@ -1671,7 +1674,7 @@ start_server {tags {"tairhash"} overrides {bind 0.0.0.0}} { r select 1 assert_equal 1 [r exhset exhashkey2 foo bar ex 1] - + after 2000 assert_equal {pmessage tairhash* tairhash@0@exhashkey__:expired foo} [$rd1 read] assert_equal {pmessage tairhash* tairhash@1@exhashkey2__:expired foo} [$rd1 read] @@ -1720,7 +1723,7 @@ start_server {tags {"tairhash"} overrides {bind 0.0.0.0}} { assert_equal {} [r exhget tairhashkey field] assert_equal -1 [r exhver tairhashkey field] } - + start_server {tags {"tairhash repl"} overrides {bind 0.0.0.0}} { r module load $testmodule set slave [srv 0 client] @@ -1794,7 +1797,7 @@ start_server {tags {"tairhash"} overrides {bind 0.0.0.0}} { assert_equal 10 [$slave exhver tairhashkey field] } - test {Exhgetall master-slave} { + test {Exhgetall / exhgetallwithver master-slave} { $master del tairhashkey assert_equal 1 [$master exhset tairhashkey field1 val1 PX 100] @@ -1806,12 +1809,14 @@ start_server {tags {"tairhash"} overrides {bind 0.0.0.0}} { assert_equal [lsort [$slave exhvals tairhashkey]] [lsort {val1 val2 val3}] assert_equal [lsort [$slave exhkeys tairhashkey]] [lsort {field1 field2 field3}] assert_equal [lsort [$slave exhgetall tairhashkey]] [lsort {field1 val1 field2 val2 field3 val3}] + assert_equal [lsort [$slave exhgetallwithver tairhashkey]] [lsort {field1 val1 1 field2 val2 1 field3 val3 1}] after 500 assert_equal [lsort [$slave exhvals tairhashkey]] [lsort {val3}] assert_equal [lsort [$slave exhkeys tairhashkey]] [lsort {field3}] assert_equal [lsort [$slave exhgetall tairhashkey]] [lsort {field3 val3}] + assert_equal [lsort [$slave exhgetallwithver tairhashkey]] [lsort {field3 val3 1}] } test {Active expire master-slave} { @@ -2054,8 +2059,8 @@ start_server {tags {"tairhash"} overrides {bind 0.0.0.0}} { # assert_equal 3 [$slave dbsize] # after 3000 - # assert_equal 0 [$master dbsize] - # assert_equal 0 [$slave dbsize] + # assert_equal 0 [$master dbsize] + # assert_equal 0 [$slave dbsize] # } } }