diff --git a/README.md b/README.md
index 357803a..8665183 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,13 @@
# Nodis
+
![GitHub top language](https://img.shields.io/github/languages/top/diiyw/nodis) ![GitHub Release](https://img.shields.io/github/v/release/diiyw/nodis)
+
-
English | [简体中文](https://github.com/diiyw/nodis/blob/main/README_zh-cn.md)
Nodis is a Redis implementation using the Golang programming language. This implementation provides a simple way to embed Redis functionality directly into your application or run it as a standalone server. The supported commands are compatible with the original Redis protocol, allowing you to use existing Redis clients like goredis for testing and integration.
@@ -21,6 +22,7 @@ Nodis is a Redis implementation using the Golang programming language. This impl
- Sorted Set
## Key Features
+
- **Fast and Embeddable**: The Golang-based implementation is designed to be fast and easily embeddable within your applications.
- **Low Memory Usage**: The system only stores hot data in memory, minimizing the overall memory footprint.
- **Snapshot and WAL for Data Storage**: This Redis implementation supports snapshot and write-ahead logging (WAL) mechanisms for reliable data storage.
@@ -30,33 +32,39 @@ Nodis is a Redis implementation using the Golang programming language. This impl
- **Redis Protocol Compatibility**: As of version 1.5.0, this Redis implementation fully supports the original Redis protocol, ensuring seamless integration with existing Redis clients.
## Supported Commands
+
| **Client Handling** | **Configuration** | **Key Commands** | **String Commands** | **Set Commands** | **Hash Commands** | **List Commands** | **Sorted Set Commands** |
-|---------------------|-----------------|-----------------|---------------------|-----------------|-----------------|------------------|----------------|
-| CLIENT | FLUSHALL | DEL | GET | SADD | HSET | LPUSH | ZADD |
-| PING | FLUSHDB | EXISTS | SET | SSCAN | HGET | RPUSH | ZCARD |
-| QUIT | SAVE | EXPIRE | INCR | SCARD | HDEL | LPOP | ZRANK |
-| ECHO | INFO | EXPIREAT | DECR | SPOP | HLEN | RPOP | ZREVRANK |
-| DBSIZE | | KEYS | SETBIT | SDIFF | HKEYS | LLEN | ZSCORE |
-| MULTI | | TTL | GETBIT | SINTER | HEXISTS | LINDEX | ZINCRBY |
-| DISCARD | | RENAME | INCR | SISMEMBER | HGETALL | LINSERT | ZRANGE |
-| EXEC | | TYPE | DESR | SMEMBERS | HINCRBY | LPUSHX | ZREVRANGE |
-| | | SCAN | SETEX | SREM | HICRBYFLOAT | RPUSHX | ZRANGEBYSCORE |
-| | | RANDOMKEY | INCRBY | SMOVE | HSETNX | LREM | ZREVRANGEBYSCORE |
-| | | RENAMEEX | DECRBY | SRANDMEMBER | HMGET | LSET | ZREM |
-| | | PERSIST | SETNX | SINTERSTORE | HMSET | LRANGE | ZREMRANGEBYRANK |
-| | | | INCRBYFLOAT | SUNIONSTORE | HCLEAR | LPOPRPUSH | ZREMRANGEBYSCORE |
-| | | | APPEND | | HSCAN | RPOPLPUSH | ZCLEAR |
-| | | | GETRANGE | | HVALS | BLPOP | ZEXISTS |
-| | | | STRLEN | | HSTRLEN | BRPOP | ZUNIONSTORE |
-| | | | SETRANGE | | | | ZINTERSTORE |
+| ------------------- | ----------------- | ---------------- | ------------------- | ---------------- | ----------------- | ----------------- | ----------------------- |
+| CLIENT | FLUSHALL | DEL | GET | SADD | HSET | LPUSH | ZADD |
+| PING | FLUSHDB | EXISTS | SET | SSCAN | HGET | RPUSH | ZCARD |
+| QUIT | SAVE | EXPIRE | INCR | SCARD | HDEL | LPOP | ZRANK |
+| ECHO | INFO | EXPIREAT | DECR | SPOP | HLEN | RPOP | ZREVRANK |
+| DBSIZE | | KEYS | SETBIT | SDIFF | HKEYS | LLEN | ZSCORE |
+| MULTI | | TTL | GETBIT | SINTER | HEXISTS | LINDEX | ZINCRBY |
+| DISCARD | | RENAME | INCR | SISMEMBER | HGETALL | LINSERT | ZRANGE |
+| EXEC | | TYPE | DESR | SMEMBERS | HINCRBY | LPUSHX | ZREVRANGE |
+| | | SCAN | SETEX | SREM | HICRBYFLOAT | RPUSHX | ZRANGEBYSCORE |
+| | | RANDOMKEY | INCRBY | SMOVE | HSETNX | LREM | ZREVRANGEBYSCORE |
+| | | RENAMEEX | DECRBY | SRANDMEMBER | HMGET | LSET | ZREM |
+| | | PERSIST | SETNX | SINTERSTORE | HMSET | LRANGE | ZREMRANGEBYRANK |
+| | | PTTL | INCRBYFLOAT | SUNIONSTORE | HCLEAR | LPOPRPUSH | ZREMRANGEBYSCORE |
+| | | | APPEND | | HSCAN | RPOPLPUSH | ZCLEAR |
+| | | | GETRANGE | | HVALS | BLPOP | ZEXISTS |
+| | | | STRLEN | | HSTRLEN | BRPOP | ZUNIONSTORE |
+| | | | SETRANGE | | | | ZINTERSTORE |
+
## Get Started
+
```bash
go get github.com/diiyw/nodis@latest
```
+
Or use test version
+
```bash
go get github.com/diiyw/nodis@main
```
+
```go
package main
@@ -68,16 +76,18 @@ func main() {
n := nodis.Open(opt)
defer n.Close()
// Set a key-value pair
- n.Set("key", []byte("value"))
+ n.Set("key", []byte("value"),false)
n.LPush("list", []byte("value1"))
}
```
+
## Examples
Watch changes
-Server:
+Server:
+
```go
package main
@@ -108,11 +118,13 @@ func main() {
}
}
```
+
- Browser client built with WebAssembly
```bash
GOOS=js GOARCH=wasm go build -o test.wasm
```
+
```go
package main
@@ -139,11 +151,12 @@ func main() {
select {}
}
```
+
Simple Redis Server
-```go
+```go
package main
import (
@@ -161,6 +174,7 @@ func main() {
}
}
```
+
You can use redis-cli to connect to the server.
```bash
@@ -171,6 +185,7 @@ redis-cli -p 6380
## Benchmark
+
Embed benchmark
@@ -197,7 +212,7 @@ Linux VM: 4C/8GB
```bash
goos: linux
goarch: amd64
-pkg: github.com/diiyw/nodis/bench
+pkg: github.com/diiyw/nodis/bench
BenchmarkSet-4 806912 1658 ns/op 543 B/op 7 allocs/op
BenchmarkGet-4 5941904 190.6 ns/op 7 B/op 0 allocs/op
BenchmarkLPush-4 852932 1757 ns/op 615 B/op 9 allocs/op
@@ -215,7 +230,7 @@ BenchmarkHGet-4 4442625 243.4 ns/op 7 B/op 0 allocs
Redis benchmark tool
```bash
-redis-benchmark -p 6380 -t set,get,lpush,lpop,sadd,smembers,zadd,zrank,hset,hget -n 100000 -q
+redis-benchmark -p 6380 -t set,get,lpush,lpop,sadd,smembers,zadd,zrank,hset,hget -n 100000 -q
```
```
@@ -226,7 +241,9 @@ LPOP: 92165.90 requests per second
SADD: 91911.76 requests per second
HSET: 93023.25 requests per second
```
+
## Note
+
If you want to persist data, please make sure to call the `Close()` method when your application exits.
diff --git a/README_zh-cn.md b/README_zh-cn.md
index 34e1162..b323107 100644
--- a/README_zh-cn.md
+++ b/README_zh-cn.md
@@ -1,60 +1,70 @@
# Nodis
+
![GitHub top language](https://img.shields.io/github/languages/top/diiyw/nodis) ![GitHub Release](https://img.shields.io/github/v/release/diiyw/nodis)
+
-
English | [简体中文](https://github.com/diiyw/nodis/blob/main/README_zh-cn.md)
Nodis 是一个使用 Golang 编程语言实现的 Redis。这个实现提供了一种将 Redis 功能直接嵌入到应用程序中或作为独立服务器运行的简单方法。支持的命令与原始 Redis 协议兼容,允许您使用现有的 Redis 客户端(如 goredis)进行测试和集成。
## 支持的数据类型
+
Bitmap
String
List
Hash
Set
Sorted Set
+
## 主要特性
+
- **快速和可嵌入**: Golang 实现的设计目标是快速和易于嵌入到您的应用程序中。
- **低内存使用**: 该系统只在内存中存储热数据,将整体内存占用降到最低。
- **快照和 WAL 用于数据存储**: 这个 Redis 实现支持快照和预写日志(WAL)机制,用于可靠的数据存储。
- **自定义数据存储后端**: 您可以集成自定义的数据存储后端,如 Amazon S3、浏览器存储等。
-使用 WebAssembly 支持浏览器: 从 1.2.0 版本开始,这个 Redis 实现可以直接在浏览器中使用 WebAssembly 运行。
+ 使用 WebAssembly 支持浏览器: 从 1.2.0 版本开始,这个 Redis 实现可以直接在浏览器中使用 WebAssembly 运行。
- **远程变更监控**: 从 1.2.0 版本开始,该系统支持监视来自远程源的变更。
- **Redis 协议兼容性**: 从 1.5.0 版本开始,这个 Redis 实现完全支持原始的 Redis 协议,确保与现有的 Redis 客户端无缝集成。
-## 支持的Redis命令
+## 支持的 Redis 命令
+
| **Client Handling** | **Configuration** | **Key Commands** | **String Commands** | **Set Commands** | **Hash Commands** | **List Commands** | **Sorted Set Commands** |
-|---------------------|-----------------|-----------------|---------------------|-----------------|-----------------|------------------|----------------|
-| CLIENT | FLUSHALL | DEL | GET | SADD | HSET | LPUSH | ZADD |
-| PING | FLUSHDB | EXISTS | SET | SSCAN | HGET | RPUSH | ZCARD |
-| QUIT | SAVE | EXPIRE | INCR | SCARD | HDEL | LPOP | ZRANK |
-| ECHO | INFO | EXPIREAT | DECR | SPOP | HLEN | RPOP | ZREVRANK |
-| DBSIZE | | KEYS | SETBIT | SDIFF | HKEYS | LLEN | ZSCORE |
-| MULTI | | TTL | GETBIT | SINTER | HEXISTS | LINDEX | ZINCRBY |
-| DISCARD | | RENAME | INCR | SISMEMBER | HGETALL | LINSERT | ZRANGE |
-| EXEC | | TYPE | DESR | SMEMBERS | HINCRBY | LPUSHX | ZREVRANGE |
-| | | SCAN | SETEX | SREM | HICRBYFLOAT | RPUSHX | ZRANGEBYSCORE |
-| | | RANDOMKEY | INCRBY | SMOVE | HSETNX | LREM | ZREVRANGEBYSCORE |
-| | | RENAMEEX | DECRBY | SRANDMEMBER | HMGET | LSET | ZREM |
-| | | PERSIST | SETNX | SINTERSTORE | HMSET | LRANGE | ZREMRANGEBYRANK |
-| | | | INCRBYFLOAT | SUNIONSTORE | HCLEAR | LPOPRPUSH | ZREMRANGEBYSCORE |
-| | | | APPEND | | HSCAN | RPOPLPUSH | ZCLEAR |
-| | | | GETRANGE | | HVALS | BLPOP | ZEXISTS |
-| | | | STRLEN | | HSTRLEN | BRPOP | ZUNIONSTORE |
-| | | | SETRANGE | | | | ZINTERSTORE |
+| ------------------- | ----------------- | ---------------- | ------------------- | ---------------- | ----------------- | ----------------- | ----------------------- |
+| CLIENT | FLUSHALL | DEL | GET | SADD | HSET | LPUSH | ZADD |
+| PING | FLUSHDB | EXISTS | SET | SSCAN | HGET | RPUSH | ZCARD |
+| QUIT | SAVE | EXPIRE | INCR | SCARD | HDEL | LPOP | ZRANK |
+| ECHO | INFO | EXPIREAT | DECR | SPOP | HLEN | RPOP | ZREVRANK |
+| DBSIZE | | KEYS | SETBIT | SDIFF | HKEYS | LLEN | ZSCORE |
+| MULTI | | TTL | GETBIT | SINTER | HEXISTS | LINDEX | ZINCRBY |
+| DISCARD | | RENAME | INCR | SISMEMBER | HGETALL | LINSERT | ZRANGE |
+| EXEC | | TYPE | DESR | SMEMBERS | HINCRBY | LPUSHX | ZREVRANGE |
+| | | SCAN | SETEX | SREM | HICRBYFLOAT | RPUSHX | ZRANGEBYSCORE |
+| | | RANDOMKEY | INCRBY | SMOVE | HSETNX | LREM | ZREVRANGEBYSCORE |
+| | | RENAMEEX | DECRBY | SRANDMEMBER | HMGET | LSET | ZREM |
+| | | PERSIST | SETNX | SINTERSTORE | HMSET | LRANGE | ZREMRANGEBYRANK |
+| | | | INCRBYFLOAT | SUNIONSTORE | HCLEAR | LPOPRPUSH | ZREMRANGEBYSCORE |
+| | | | APPEND | | HSCAN | RPOPLPUSH | ZCLEAR |
+| | | | GETRANGE | | HVALS | BLPOP | ZEXISTS |
+| | | | STRLEN | | HSTRLEN | BRPOP | ZUNIONSTORE |
+| | | | SETRANGE | | | | ZINTERSTORE |
+
## Get Started
+
```bash
go get github.com/diiyw/nodis@v1.5.0
```
+
Or use test version
+
```bash
go get github.com/diiyw/nodis@main
```
+
```go
package main
@@ -66,16 +76,18 @@ func main() {
n := nodis.Open(opt)
defer n.Close()
// Set a key-value pair
- n.Set("key", []byte("value"))
+ n.Set("key", []byte("value"), false)
n.LPush("list", []byte("value1"))
}
```
+
## Examples
Watch changes
-Server:
+Server:
+
```go
package main
@@ -106,11 +118,13 @@ func main() {
}
}
```
+
- Browser client built with WebAssembly
```bash
GOOS=js GOARCH=wasm go build -o test.wasm
```
+
```go
package main
@@ -137,9 +151,11 @@ func main() {
select {}
}
```
+
## Benchmark
+
Embed benchmark
Windows 11: 12C/32G
@@ -165,7 +181,7 @@ Linux VM: 4C/8GB
```bash
goos: linux
goarch: amd64
-pkg: github.com/diiyw/nodis/bench
+pkg: github.com/diiyw/nodis/bench
BenchmarkSet-4 806912 1658 ns/op 543 B/op 7 allocs/op
BenchmarkGet-4 5941904 190.6 ns/op 7 B/op 0 allocs/op
BenchmarkLPush-4 852932 1757 ns/op 615 B/op 9 allocs/op
diff --git a/bench/nodis_test.go b/bench/nodis_test.go
index 12c1227..da34b46 100644
--- a/bench/nodis_test.go
+++ b/bench/nodis_test.go
@@ -16,7 +16,7 @@ func BenchmarkSet(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
id := strconv.Itoa(i)
- n.Set(id, []byte("value"+id))
+ n.Set(id, []byte("value"+id), false)
}
}
@@ -27,7 +27,7 @@ func BenchmarkGet(b *testing.B) {
})
for i := 0; i < 100000; i++ {
id := strconv.Itoa(i)
- n.Set(id, []byte("value"+id))
+ n.Set(id, []byte("value"+id), false)
}
b.ResetTimer()
b.ReportAllocs()
diff --git a/examples/hello/main.go b/examples/hello/main.go
index fa33626..9663822 100644
--- a/examples/hello/main.go
+++ b/examples/hello/main.go
@@ -12,6 +12,6 @@ func main() {
n := nodis.Open(opt)
defer n.Close()
// Set a key-value pair
- n.Set("echo", []byte("hello world"))
+ n.Set("echo", []byte("hello world"), false)
fmt.Println("Set key-value pair: ", string(n.Get("echo")))
}
diff --git a/handler.go b/handler.go
index 9ae28cd..1780f9f 100644
--- a/handler.go
+++ b/handler.go
@@ -77,6 +77,8 @@ func getCommand(name string) func(n *Nodis, conn *redis.Conn, cmd redis.Command)
return randomKey
case "TTL":
return ttl
+ case "PTTL":
+ return pTtl
case "PERSIST":
return Persist
case "RENAME":
@@ -557,6 +559,25 @@ func ttl(n *Nodis, conn *redis.Conn, cmd redis.Command) {
})
}
+func pTtl(n *Nodis, conn *redis.Conn, cmd redis.Command) {
+ if len(cmd.Args) == 0 {
+ conn.WriteError("PTTL requires at least one argument")
+ return
+ }
+ execCommand(conn, func() {
+ v := n.PTTL(cmd.Args[0])
+ if v == -1 {
+ conn.WriteInteger(-1)
+ return
+ }
+ if v == -2 {
+ conn.WriteInteger(-2)
+ return
+ }
+ conn.WriteInteger(v)
+ })
+}
+
func Persist(n *Nodis, conn *redis.Conn, cmd redis.Command) {
if len(cmd.Args) == 0 {
conn.WriteError("PERSIST requires at least one argument")
@@ -675,11 +696,17 @@ func setString(n *Nodis, conn *redis.Conn, cmd redis.Command) {
get = n.Get(key)
}
if cmd.Options.NX > 1 {
- n.SetNX(key, value)
+ if !n.SetNX(key, value, cmd.Options.KEEPTTL > 1) {
+ conn.WriteBulkNull()
+ return
+ }
} else if cmd.Options.XX > 1 {
- n.SetXX(key, value)
+ if !n.SetXX(key, value, cmd.Options.KEEPTTL > 1) {
+ conn.WriteBulkNull()
+ return
+ }
} else {
- n.Set(key, value)
+ n.Set(key, value, cmd.Options.KEEPTTL > 1)
}
if cmd.Options.EX > 1 {
seconds, _ := strconv.ParseInt(cmd.Args[cmd.Options.EX], 10, 64)
@@ -689,13 +716,19 @@ func setString(n *Nodis, conn *redis.Conn, cmd redis.Command) {
}
if cmd.Options.PX > 1 {
milliseconds, _ := strconv.ParseInt(cmd.Args[cmd.Options.PX], 10, 64)
- n.ExpirePX(key, milliseconds)
+ if n.ExpirePX(key, milliseconds) == 0 {
+ conn.WriteBulkNull()
+ return
+ }
conn.WriteOK()
return
}
if cmd.Options.EXAT > 1 {
seconds, _ := strconv.ParseInt(cmd.Args[cmd.Options.EXAT], 10, 64)
- n.ExpireAt(key, time.Unix(seconds, 0))
+ if n.ExpireAt(key, time.Unix(seconds, 0)) == 0 {
+ conn.WriteBulkNull()
+ return
+ }
conn.WriteOK()
return
}
@@ -722,7 +755,7 @@ func mSet(n *Nodis, conn *redis.Conn, cmd redis.Command) {
}
execCommand(conn, func() {
for i := 0; i < len(cmd.Args); i += 2 {
- n.Set(cmd.Args[i], []byte(cmd.Args[i+1]))
+ n.Set(cmd.Args[i], []byte(cmd.Args[i+1]), false)
}
conn.WriteOK()
})
@@ -762,7 +795,7 @@ func setnx(n *Nodis, conn *redis.Conn, cmd redis.Command) {
execCommand(conn, func() {
key := cmd.Args[0]
value := []byte(cmd.Args[1])
- if n.SetNX(key, value) {
+ if n.SetNX(key, value, false) {
conn.WriteInteger(1)
return
}
diff --git a/key.go b/key.go
index b3575a7..090cd06 100644
--- a/key.go
+++ b/key.go
@@ -66,9 +66,7 @@ func (n *Nodis) Expire(key string, seconds int64) int64 {
v = 0
return nil
}
- if meta.expiration == 0 {
- meta.expiration = time.Now().UnixMilli()
- }
+ meta.expiration = time.Now().UnixMilli()
meta.expiration += seconds * 1000
n.signalModifiedKey(key, meta)
n.notify(pb.NewOp(pb.OpType_Expire, key).Expiration(meta.expiration))
@@ -401,6 +399,25 @@ func (n *Nodis) TTL(key string) time.Duration {
return v
}
+// PTTL gets the TTL in milliseconds
+func (n *Nodis) PTTL(key string) int64 {
+ var v int64
+ _ = n.exec(func(tx *Tx) error {
+ meta := tx.readKey(key)
+ if !meta.isOk() {
+ v = -2
+ return nil
+ }
+ if meta.expiration == 0 {
+ v = -1
+ return nil
+ }
+ v = meta.expiration - time.Now().UnixMilli()
+ return nil
+ })
+ return v
+}
+
// Rename a key
func (n *Nodis) Rename(key, dstKey string) error {
return n.exec(func(tx *Tx) error {
diff --git a/key_test.go b/key_test.go
index afefaa0..657f6cb 100644
--- a/key_test.go
+++ b/key_test.go
@@ -15,7 +15,7 @@ func TestKey_Expire(t *testing.T) {
Path: "testdata",
TidyDuration: 60 * time.Second,
})
- n.Set("test", []byte("test1"))
+ n.Set("test", []byte("test1"), false)
n.Expire("test", 2)
time.Sleep(time.Second * 2)
if n.TTL("test") > 0 {
@@ -28,7 +28,7 @@ func TestKey_ExpireXX(t *testing.T) {
n := Open(&Options{
Path: "testdata",
})
- n.Set("test", []byte("test1"))
+ n.Set("test", []byte("test1"), false)
n.ExpireXX("test", 3)
if n.TTL("test") != -1 {
t.Errorf("TTL() = %v, want %v", 0, n.TTL("test"))
@@ -46,7 +46,7 @@ func TestKey_ExpireNX(t *testing.T) {
Path: "testdata",
TidyDuration: 60 * time.Second,
})
- n.Set("test", []byte("test1"))
+ n.Set("test", []byte("test1"), false)
n.ExpireNX("test", 2)
if int64(n.TTL("test").Seconds()) == 0 {
t.Errorf("TTL() = %v, want %vs", n.TTL("test"), 0)
@@ -64,7 +64,7 @@ func TestKey_ExpireLT(t *testing.T) {
Path: "testdata",
TidyDuration: 60 * time.Second,
})
- n.Set("test", []byte("test1"))
+ n.Set("test", []byte("test1"), false)
v := n.ExpireLT("test", 2)
if v != 0 {
t.Errorf("ExpireLT() = %v, want %v", v, 0)
@@ -82,7 +82,7 @@ func TestKey_ExpireGT(t *testing.T) {
Path: "testdata",
TidyDuration: 60 * time.Second,
})
- n.Set("test", []byte("test1"))
+ n.Set("test", []byte("test1"), false)
v := n.ExpireGT("test", 2)
if v == 0 {
t.Errorf("ExpireGT() = %v, want not %v", v, 0)
@@ -100,7 +100,7 @@ func TestKey_ExpireAt(t *testing.T) {
Path: "testdata",
TidyDuration: 60 * time.Second,
})
- n.Set("test", []byte("test1"))
+ n.Set("test", []byte("test1"), false)
n.ExpireAt("test", time.Now().Add(2*time.Second))
time.Sleep(2 * time.Second)
v := n.Get("test")
@@ -115,7 +115,7 @@ func TestKey_TTL(t *testing.T) {
Path: "testdata",
TidyDuration: 60 * time.Second,
})
- n.Set("test", []byte("test1"))
+ n.Set("test", []byte("test1"), false)
n.Expire("test", 300)
v := n.TTL("test")
if v < 299 {
@@ -134,7 +134,7 @@ func TestKey_Rename(t *testing.T) {
Path: "testdata",
TidyDuration: 60 * time.Second,
})
- n.Set("test", []byte("test1"))
+ n.Set("test", []byte("test1"), false)
n.Rename("test", "test2")
v := n.Get("test")
if v != nil {
@@ -151,8 +151,8 @@ func TestKey_RenameNX(t *testing.T) {
n := Open(&Options{
Path: "testdata",
})
- n.Set("test", []byte("test1"))
- n.Set("test2", []byte("test2"))
+ n.Set("test", []byte("test1"), false)
+ n.Set("test2", []byte("test2"), false)
err := n.RenameNX("test", "test2")
if err == nil {
t.Errorf("RenameNX() = %v, want %v", err, "key exists")
@@ -169,9 +169,9 @@ func TestKey_Keys(t *testing.T) {
Path: "testdata",
TidyDuration: 60 * time.Second,
})
- n.Set("test1", []byte("test1"))
- n.Set("test2", []byte("test2"))
- n.Set("test3", []byte("test3"))
+ n.Set("test1", []byte("test1"), false)
+ n.Set("test2", []byte("test2"), false)
+ n.Set("test3", []byte("test3"), false)
keys := n.Keys("test*")
if len(keys) != 3 {
t.Errorf("Keys() = %v, want %v", len(keys), 3)
@@ -185,7 +185,7 @@ func TestKey_Type(t *testing.T) {
TidyDuration: 60 * time.Second,
Filesystem: &fs.Disk{},
})
- n.Set("test1", []byte("test1"))
+ n.Set("test1", []byte("test1"), false)
n.LPush("test2", []byte("test2"))
n.ZAdd("test3", "test3", 10)
n.SAdd("test4", "test4")
@@ -237,37 +237,37 @@ func TestKey_Scan(t *testing.T) {
Path: "testdata",
TidyDuration: 60 * time.Second,
})
- n.Set("test1", []byte("test1"))
- n.Set("test2", []byte("test2"))
- n.Set("test3", []byte("test3"))
- n.Set("test4", []byte("test4"))
- n.Set("test5", []byte("test5"))
- n.Set("test6", []byte("test6"))
- n.Set("test7", []byte("test7"))
- n.Set("test8", []byte("test8"))
- n.Set("test9", []byte("test9"))
- n.Set("test10", []byte("test10"))
- n.Set("test11", []byte("test11"))
- n.Set("test12", []byte("test12"))
- n.Set("test13", []byte("test13"))
- n.Set("test14", []byte("test14"))
- n.Set("test15", []byte("test15"))
- n.Set("test16", []byte("test16"))
- n.Set("test17", []byte("test17"))
- n.Set("test18", []byte("test18"))
- n.Set("test19", []byte("test19"))
- n.Set("test20", []byte("test20"))
- n.Set("test21", []byte("test21"))
- n.Set("test22", []byte("test22"))
- n.Set("test23", []byte("test23"))
- n.Set("test24", []byte("test24"))
- n.Set("test25", []byte("test25"))
- n.Set("test26", []byte("test26"))
- n.Set("test27", []byte("test27"))
- n.Set("test28", []byte("test28"))
- n.Set("test29", []byte("test29"))
- n.Set("test30", []byte("test30"))
- n.Set("test31", []byte("test31"))
+ n.Set("test1", []byte("test1"), false)
+ n.Set("test2", []byte("test2"), false)
+ n.Set("test3", []byte("test3"), false)
+ n.Set("test4", []byte("test4"), false)
+ n.Set("test5", []byte("test5"), false)
+ n.Set("test6", []byte("test6"), false)
+ n.Set("test7", []byte("test7"), false)
+ n.Set("test8", []byte("test8"), false)
+ n.Set("test9", []byte("test9"), false)
+ n.Set("test10", []byte("test10"), false)
+ n.Set("test11", []byte("test11"), false)
+ n.Set("test12", []byte("test12"), false)
+ n.Set("test13", []byte("test13"), false)
+ n.Set("test14", []byte("test14"), false)
+ n.Set("test15", []byte("test15"), false)
+ n.Set("test16", []byte("test16"), false)
+ n.Set("test17", []byte("test17"), false)
+ n.Set("test18", []byte("test18"), false)
+ n.Set("test19", []byte("test19"), false)
+ n.Set("test20", []byte("test20"), false)
+ n.Set("test21", []byte("test21"), false)
+ n.Set("test22", []byte("test22"), false)
+ n.Set("test23", []byte("test23"), false)
+ n.Set("test24", []byte("test24"), false)
+ n.Set("test25", []byte("test25"), false)
+ n.Set("test26", []byte("test26"), false)
+ n.Set("test27", []byte("test27"), false)
+ n.Set("test28", []byte("test28"), false)
+ n.Set("test29", []byte("test29"), false)
+ n.Set("test30", []byte("test30"), false)
+ n.Set("test31", []byte("test31"), false)
_, result := n.Scan(0, "test*", 10, ds.String)
if len(result) != 10 {
t.Errorf("Scan() = %v, want %v", len(result), 10)
@@ -296,7 +296,7 @@ func TestKey_Exists(t *testing.T) {
Path: "testdata",
TidyDuration: 60 * time.Second,
})
- n.Set("test", []byte("test1"))
+ n.Set("test", []byte("test1"), false)
if n.Exists("test") != 1 {
t.Errorf("Exists() = %v, want %v", n.Exists("test"), true)
}
diff --git a/nodis.go b/nodis.go
index 97ca20b..a511d4f 100644
--- a/nodis.go
+++ b/nodis.go
@@ -198,7 +198,7 @@ func (n *Nodis) patch(op *pb.Op) error {
case pb.OpType_SRem:
n.SRem(op.Key, op.Operation.Members...)
case pb.OpType_Set:
- n.Set(op.Key, op.Operation.Value)
+ n.Set(op.Key, op.Operation.Value, op.Operation.KeepTTL)
case pb.OpType_ZAdd:
n.ZAdd(op.Key, op.Operation.Member, op.Operation.Score)
case pb.OpType_ZClear:
diff --git a/nodis_test.go b/nodis_test.go
index 4b29ef0..3588879 100644
--- a/nodis_test.go
+++ b/nodis_test.go
@@ -31,7 +31,7 @@ func TestNodis_OpenAndCloseBigdata10000(t *testing.T) {
n := Open(&opt)
for i := 0; i < 10000; i++ {
is := strconv.Itoa(i)
- n.Set(is, []byte(is))
+ n.Set(is, []byte(is), false)
}
for i := 10000; i < 20000; i++ {
n.ZAdd("zset", strconv.Itoa(i), float64(i))
@@ -81,7 +81,7 @@ func TestNodis_Snapshot(t *testing.T) {
Path: "testdata",
}
n := Open(opt)
- n.Set("test", []byte("test"))
+ n.Set("test", []byte("test"), false)
n.Snapshot("testdata")
_ = n.Close()
}
@@ -92,10 +92,10 @@ func TestNodis_SnapshotChanged(t *testing.T) {
Path: "testdata",
}
n := Open(opt)
- n.Set("test", []byte("test"))
+ n.Set("test", []byte("test"), false)
n.Snapshot(opt.Path)
time.Sleep(time.Second)
- n.Set("test", []byte("test_new"))
+ n.Set("test", []byte("test_new"), false)
n.Snapshot(opt.Path)
_ = n.Close()
}
@@ -129,7 +129,7 @@ func TestNodis_Clear(t *testing.T) {
Path: "testdata",
}
n := Open(opt)
- n.Set("test", []byte("test"))
+ n.Set("test", []byte("test"), false)
n.Clear()
v := n.Get("test")
if v != nil {
@@ -212,7 +212,7 @@ func TestNodis_SetEntity(t *testing.T) {
Path: "testdata",
}
n := Open(opt)
- n.Set("test", []byte("test"))
+ n.Set("test", []byte("test"), false)
data := n.GetEntry("test")
n.Clear()
v := n.Get("test")
@@ -236,13 +236,13 @@ func TestNodis_Stick(t *testing.T) {
Path: "testdata",
}
n := Open(opt)
- n.Set("test", []byte("test"))
+ n.Set("test", []byte("test"), false)
n.Stick([]string{"test"}, func(op *pb.Operation) {
if op == nil || string(op.Value) != "test_new" {
t.Errorf("Stick() = %v, want %v", op, "test_new")
}
})
- n.Set("test", []byte("test_new"))
+ n.Set("test", []byte("test_new"), false)
time.Sleep(time.Second)
}
@@ -252,14 +252,14 @@ func TestNodis_UnStick(t *testing.T) {
Path: "testdata",
}
n := Open(opt)
- n.Set("test", []byte("test"))
+ n.Set("test", []byte("test"), false)
id := n.Stick([]string{"test"}, func(op *pb.Operation) {
if op == nil || string(op.Value) != "test_new" {
t.Errorf("Stick() = %v, want %v", op, "test_new")
}
})
n.UnStick(id)
- n.Set("test", []byte("test_new"))
+ n.Set("test", []byte("test_new"), false)
time.Sleep(time.Second)
}
@@ -269,7 +269,7 @@ func TestNodis_OpenAndClose(t *testing.T) {
Path: "testdata",
}
n := Open(opt)
- n.Set("str", []byte("set"))
+ n.Set("str", []byte("set"), false)
n.ZAdd("zset", "zset", 1)
n.HSet("hset", "hset", []byte("hset"))
n.LPush("lpush", []byte("lpush"))
diff --git a/pb/nodis.pb.go b/pb/nodis.pb.go
index f6286d6..0d4bff0 100644
--- a/pb/nodis.pb.go
+++ b/pb/nodis.pb.go
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.26.0
-// protoc v3.9.1
+// protoc-gen-go v1.34.0
+// protoc v3.6.1
// source: nodis.proto
package pb
@@ -201,6 +201,7 @@ type Operation struct {
Weights []float64 `protobuf:"fixed64,23,rep,packed,name=weights,proto3" json:"weights,omitempty"`
Aggregate string `protobuf:"bytes,24,opt,name=aggregate,proto3" json:"aggregate,omitempty"`
Mode int64 `protobuf:"varint,25,opt,name=Mode,proto3" json:"Mode,omitempty"`
+ KeepTTL bool `protobuf:"varint,26,opt,name=KeepTTL,proto3" json:"KeepTTL,omitempty"`
}
func (x *Operation) Reset() {
@@ -410,6 +411,13 @@ func (x *Operation) GetMode() int64 {
return 0
}
+func (x *Operation) GetKeepTTL() bool {
+ if x != nil {
+ return x.KeepTTL
+ }
+ return false
+}
+
type KeyScore struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -1008,7 +1016,7 @@ var File_nodis_proto protoreflect.FileDescriptor
var file_nodis_proto_rawDesc = []byte{
0x0a, 0x0b, 0x6e, 0x6f, 0x64, 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70,
- 0x62, 0x22, 0xd9, 0x04, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12,
+ 0x62, 0x22, 0xf3, 0x04, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12,
0x1e, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0a, 0x2e,
0x70, 0x62, 0x2e, 0x4f, 0x70, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12,
0x10, 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x4b, 0x65,
@@ -1045,85 +1053,87 @@ var file_nodis_proto_rawDesc = []byte{
0x28, 0x01, 0x52, 0x07, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x61,
0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x18, 0x18, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4d, 0x6f, 0x64,
- 0x65, 0x18, 0x19, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x38, 0x0a,
- 0x08, 0x4b, 0x65, 0x79, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x4d, 0x65, 0x6d,
- 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4d, 0x65, 0x6d, 0x62, 0x65,
- 0x72, 0x12, 0x14, 0x0a, 0x05, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01,
- 0x52, 0x05, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x22, 0x31, 0x0a, 0x09, 0x5a, 0x53, 0x65, 0x74, 0x56,
- 0x61, 0x6c, 0x75, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02,
- 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x62, 0x2e, 0x4b, 0x65, 0x79, 0x53, 0x63, 0x6f,
- 0x72, 0x65, 0x52, 0x06, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x23, 0x0a, 0x09, 0x4c, 0x69,
- 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x56, 0x61, 0x6c, 0x75, 0x65,
- 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22,
- 0x23, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14,
- 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x56,
- 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3b, 0x0a, 0x0b, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x42, 0x79,
- 0x74, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x06, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x56,
- 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75,
- 0x65, 0x22, 0x22, 0x0a, 0x08, 0x53, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a,
- 0x06, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x56,
- 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x34, 0x0a, 0x09, 0x48, 0x61, 0x73, 0x68, 0x56, 0x61, 0x6c,
- 0x75, 0x65, 0x12, 0x27, 0x0a, 0x06, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03,
- 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x42, 0x79,
- 0x74, 0x65, 0x73, 0x52, 0x06, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0xc4, 0x02, 0x0a, 0x05,
- 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x0d, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x4b, 0x65, 0x79,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x33, 0x0a, 0x0b, 0x53,
- 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
- 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75,
- 0x65, 0x48, 0x00, 0x52, 0x0b, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65,
- 0x12, 0x2d, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c,
- 0x75, 0x65, 0x48, 0x00, 0x52, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12,
- 0x2a, 0x0a, 0x08, 0x53, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48,
- 0x00, 0x52, 0x08, 0x53, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2d, 0x0a, 0x09, 0x48,
- 0x61, 0x73, 0x68, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d,
- 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52,
- 0x09, 0x48, 0x61, 0x73, 0x68, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2d, 0x0a, 0x09, 0x5a, 0x53,
- 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e,
- 0x70, 0x62, 0x2e, 0x5a, 0x53, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x09,
- 0x5a, 0x53, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x45, 0x78, 0x70,
- 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x45,
- 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x07, 0x0a, 0x05, 0x56, 0x61, 0x6c,
- 0x75, 0x65, 0x22, 0x5b, 0x0a, 0x05, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x24, 0x0a, 0x05, 0x49,
- 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e,
- 0x49, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x49, 0x74, 0x65, 0x6d,
- 0x73, 0x1a, 0x2c, 0x0a, 0x04, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x4b, 0x65, 0x79,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x44,
- 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x2a,
- 0xd4, 0x03, 0x0a, 0x06, 0x4f, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6f,
- 0x6e, 0x65, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x10, 0x01, 0x12,
- 0x07, 0x0a, 0x03, 0x44, 0x65, 0x6c, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x45, 0x78, 0x70, 0x69,
- 0x72, 0x65, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x41, 0x74,
- 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x48, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x10, 0x05, 0x12, 0x08,
- 0x0a, 0x04, 0x48, 0x44, 0x65, 0x6c, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x49, 0x6e, 0x63,
- 0x72, 0x42, 0x79, 0x10, 0x07, 0x12, 0x10, 0x0a, 0x0c, 0x48, 0x49, 0x6e, 0x63, 0x72, 0x42, 0x79,
- 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x10, 0x08, 0x12, 0x09, 0x0a, 0x05, 0x48, 0x4d, 0x53, 0x65, 0x74,
- 0x10, 0x09, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x53, 0x65, 0x74, 0x10, 0x0a, 0x12, 0x0b, 0x0a, 0x07,
- 0x4c, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x10, 0x0c, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x50, 0x6f,
- 0x70, 0x10, 0x0d, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x50, 0x6f, 0x70, 0x52, 0x50, 0x75, 0x73, 0x68,
- 0x10, 0x0e, 0x12, 0x09, 0x0a, 0x05, 0x4c, 0x50, 0x75, 0x73, 0x68, 0x10, 0x0f, 0x12, 0x0a, 0x0a,
- 0x06, 0x4c, 0x50, 0x75, 0x73, 0x68, 0x58, 0x10, 0x10, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x52, 0x65,
- 0x6d, 0x10, 0x11, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x53, 0x65, 0x74, 0x10, 0x12, 0x12, 0x09, 0x0a,
- 0x05, 0x4c, 0x54, 0x72, 0x69, 0x6d, 0x10, 0x13, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x50, 0x6f, 0x70,
- 0x10, 0x14, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x50, 0x6f, 0x70, 0x4c, 0x50, 0x75, 0x73, 0x68, 0x10,
- 0x15, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x50, 0x75, 0x73, 0x68, 0x10, 0x16, 0x12, 0x0a, 0x0a, 0x06,
- 0x52, 0x50, 0x75, 0x73, 0x68, 0x58, 0x10, 0x17, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x41, 0x64, 0x64,
- 0x10, 0x18, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x52, 0x65, 0x6d, 0x10, 0x19, 0x12, 0x07, 0x0a, 0x03,
- 0x53, 0x65, 0x74, 0x10, 0x1a, 0x12, 0x08, 0x0a, 0x04, 0x5a, 0x41, 0x64, 0x64, 0x10, 0x1b, 0x12,
- 0x0a, 0x0a, 0x06, 0x5a, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x10, 0x1c, 0x12, 0x0b, 0x0a, 0x07, 0x5a,
- 0x49, 0x6e, 0x63, 0x72, 0x42, 0x79, 0x10, 0x1d, 0x12, 0x08, 0x0a, 0x04, 0x5a, 0x52, 0x65, 0x6d,
- 0x10, 0x1e, 0x12, 0x13, 0x0a, 0x0f, 0x5a, 0x52, 0x65, 0x6d, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x42,
- 0x79, 0x52, 0x61, 0x6e, 0x6b, 0x10, 0x1f, 0x12, 0x14, 0x0a, 0x10, 0x5a, 0x52, 0x65, 0x6d, 0x52,
- 0x61, 0x6e, 0x67, 0x65, 0x42, 0x79, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x10, 0x20, 0x12, 0x0a, 0x0a,
- 0x06, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x10, 0x21, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x65, 0x72,
- 0x73, 0x69, 0x73, 0x74, 0x10, 0x22, 0x12, 0x0f, 0x0a, 0x0b, 0x5a, 0x55, 0x6e, 0x69, 0x6f, 0x6e,
- 0x53, 0x74, 0x6f, 0x72, 0x65, 0x10, 0x23, 0x12, 0x0f, 0x0a, 0x0b, 0x5a, 0x49, 0x6e, 0x74, 0x65,
- 0x72, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x10, 0x24, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x65, 0x6e, 0x61,
- 0x6d, 0x65, 0x4e, 0x58, 0x10, 0x25, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x2e, 0x2f, 0x70, 0x62, 0x62,
- 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x65, 0x18, 0x19, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a,
+ 0x07, 0x4b, 0x65, 0x65, 0x70, 0x54, 0x54, 0x4c, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07,
+ 0x4b, 0x65, 0x65, 0x70, 0x54, 0x54, 0x4c, 0x22, 0x38, 0x0a, 0x08, 0x4b, 0x65, 0x79, 0x53, 0x63,
+ 0x6f, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x06, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x53,
+ 0x63, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x53, 0x63, 0x6f, 0x72,
+ 0x65, 0x22, 0x31, 0x0a, 0x09, 0x5a, 0x53, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x24,
+ 0x0a, 0x06, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c,
+ 0x2e, 0x70, 0x62, 0x2e, 0x4b, 0x65, 0x79, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x52, 0x06, 0x56, 0x61,
+ 0x6c, 0x75, 0x65, 0x73, 0x22, 0x23, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75,
+ 0x65, 0x12, 0x16, 0x0a, 0x06, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
+ 0x0c, 0x52, 0x06, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x23, 0x0a, 0x0b, 0x53, 0x74, 0x72,
+ 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75,
+ 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3b,
+ 0x0a, 0x0b, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x16, 0x0a,
+ 0x06, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4d,
+ 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x22, 0x0a, 0x08, 0x53,
+ 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x56, 0x61, 0x6c, 0x75, 0x65,
+ 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22,
+ 0x34, 0x0a, 0x09, 0x48, 0x61, 0x73, 0x68, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x27, 0x0a, 0x06,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70,
+ 0x62, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x06, 0x56,
+ 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0xc4, 0x02, 0x0a, 0x05, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
+ 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x54,
+ 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x33, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56,
+ 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x2e,
+ 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x53,
+ 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2d, 0x0a, 0x09, 0x4c, 0x69,
+ 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e,
+ 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x09,
+ 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2a, 0x0a, 0x08, 0x53, 0x65, 0x74,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x62,
+ 0x2e, 0x53, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x08, 0x53, 0x65, 0x74,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2d, 0x0a, 0x09, 0x48, 0x61, 0x73, 0x68, 0x56, 0x61, 0x6c,
+ 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x61,
+ 0x73, 0x68, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x09, 0x48, 0x61, 0x73, 0x68, 0x56,
+ 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2d, 0x0a, 0x09, 0x5a, 0x53, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75,
+ 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x2e, 0x5a, 0x53, 0x65,
+ 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x09, 0x5a, 0x53, 0x65, 0x74, 0x56, 0x61,
+ 0x6c, 0x75, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x42, 0x07, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x5b, 0x0a, 0x05,
+ 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x24, 0x0a, 0x05, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x2e,
+ 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x1a, 0x2c, 0x0a, 0x04, 0x49,
+ 0x74, 0x65, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x2a, 0xd4, 0x03, 0x0a, 0x06, 0x4f, 0x70,
+ 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12, 0x09,
+ 0x0a, 0x05, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x65, 0x6c,
+ 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x10, 0x03, 0x12, 0x0c,
+ 0x0a, 0x08, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x41, 0x74, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06,
+ 0x48, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x10, 0x05, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x44, 0x65, 0x6c,
+ 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x49, 0x6e, 0x63, 0x72, 0x42, 0x79, 0x10, 0x07, 0x12,
+ 0x10, 0x0a, 0x0c, 0x48, 0x49, 0x6e, 0x63, 0x72, 0x42, 0x79, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x10,
+ 0x08, 0x12, 0x09, 0x0a, 0x05, 0x48, 0x4d, 0x53, 0x65, 0x74, 0x10, 0x09, 0x12, 0x08, 0x0a, 0x04,
+ 0x48, 0x53, 0x65, 0x74, 0x10, 0x0a, 0x12, 0x0b, 0x0a, 0x07, 0x4c, 0x49, 0x6e, 0x73, 0x65, 0x72,
+ 0x74, 0x10, 0x0c, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x50, 0x6f, 0x70, 0x10, 0x0d, 0x12, 0x0d, 0x0a,
+ 0x09, 0x4c, 0x50, 0x6f, 0x70, 0x52, 0x50, 0x75, 0x73, 0x68, 0x10, 0x0e, 0x12, 0x09, 0x0a, 0x05,
+ 0x4c, 0x50, 0x75, 0x73, 0x68, 0x10, 0x0f, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x50, 0x75, 0x73, 0x68,
+ 0x58, 0x10, 0x10, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x52, 0x65, 0x6d, 0x10, 0x11, 0x12, 0x08, 0x0a,
+ 0x04, 0x4c, 0x53, 0x65, 0x74, 0x10, 0x12, 0x12, 0x09, 0x0a, 0x05, 0x4c, 0x54, 0x72, 0x69, 0x6d,
+ 0x10, 0x13, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x50, 0x6f, 0x70, 0x10, 0x14, 0x12, 0x0d, 0x0a, 0x09,
+ 0x52, 0x50, 0x6f, 0x70, 0x4c, 0x50, 0x75, 0x73, 0x68, 0x10, 0x15, 0x12, 0x09, 0x0a, 0x05, 0x52,
+ 0x50, 0x75, 0x73, 0x68, 0x10, 0x16, 0x12, 0x0a, 0x0a, 0x06, 0x52, 0x50, 0x75, 0x73, 0x68, 0x58,
+ 0x10, 0x17, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x41, 0x64, 0x64, 0x10, 0x18, 0x12, 0x08, 0x0a, 0x04,
+ 0x53, 0x52, 0x65, 0x6d, 0x10, 0x19, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x65, 0x74, 0x10, 0x1a, 0x12,
+ 0x08, 0x0a, 0x04, 0x5a, 0x41, 0x64, 0x64, 0x10, 0x1b, 0x12, 0x0a, 0x0a, 0x06, 0x5a, 0x43, 0x6c,
+ 0x65, 0x61, 0x72, 0x10, 0x1c, 0x12, 0x0b, 0x0a, 0x07, 0x5a, 0x49, 0x6e, 0x63, 0x72, 0x42, 0x79,
+ 0x10, 0x1d, 0x12, 0x08, 0x0a, 0x04, 0x5a, 0x52, 0x65, 0x6d, 0x10, 0x1e, 0x12, 0x13, 0x0a, 0x0f,
+ 0x5a, 0x52, 0x65, 0x6d, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x79, 0x52, 0x61, 0x6e, 0x6b, 0x10,
+ 0x1f, 0x12, 0x14, 0x0a, 0x10, 0x5a, 0x52, 0x65, 0x6d, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x79,
+ 0x53, 0x63, 0x6f, 0x72, 0x65, 0x10, 0x20, 0x12, 0x0a, 0x0a, 0x06, 0x52, 0x65, 0x6e, 0x61, 0x6d,
+ 0x65, 0x10, 0x21, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x10, 0x22,
+ 0x12, 0x0f, 0x0a, 0x0b, 0x5a, 0x55, 0x6e, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x10,
+ 0x23, 0x12, 0x0f, 0x0a, 0x0b, 0x5a, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x53, 0x74, 0x6f, 0x72, 0x65,
+ 0x10, 0x24, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x4e, 0x58, 0x10, 0x25,
+ 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x33,
}
var (
diff --git a/pb/nodis.proto b/pb/nodis.proto
index f99c09a..0a32674 100644
--- a/pb/nodis.proto
+++ b/pb/nodis.proto
@@ -69,6 +69,7 @@ message Operation {
repeated double weights = 23;
string aggregate = 24;
int64 Mode = 25;
+ bool KeepTTL = 26;
}
message KeyScore {
diff --git a/pb/op.go b/pb/op.go
index d29f825..db8ed18 100644
--- a/pb/op.go
+++ b/pb/op.go
@@ -158,6 +158,12 @@ func (o *Op) Mode(mode int64) *Op {
return o
}
+// KeepTTL set the keep ttl
+func (o *Op) KeepTTL(keepTTL bool) *Op {
+ o.Operation.KeepTTL = keepTTL
+ return o
+}
+
func (o *Op) Reset() {
o.Operation.Reset()
opPool.Put(o)
diff --git a/store_test.go b/store_test.go
index 4b9540b..cc8e3f8 100644
--- a/store_test.go
+++ b/store_test.go
@@ -275,7 +275,7 @@ func TestStore_parseValue(t *testing.T) {
Path: "testdata",
}
n := Open(opt)
- n.Set("test", []byte("test"))
+ n.Set("test", []byte("test"), false)
data := n.GetEntry("test")
value, err := n.store.parseValue(data)
if err != nil {
diff --git a/str.go b/str.go
index 2e6cba4..d9f674d 100644
--- a/str.go
+++ b/str.go
@@ -15,12 +15,15 @@ func (n *Nodis) newStr() ds.Value {
}
// Set a key with a value and a TTL
-func (n *Nodis) Set(key string, value []byte) {
+func (n *Nodis) Set(key string, value []byte, keepTTL bool) {
_ = n.exec(func(tx *Tx) error {
meta := tx.writeKey(key, n.newStr)
meta.value.(*str.String).Set(value)
+ if !keepTTL {
+ meta.expiration = 0
+ }
n.signalModifiedKey(key, meta)
- n.notify(pb.NewOp(pb.OpType_Set, key).Value(value))
+ n.notify(pb.NewOp(pb.OpType_Set, key).Value(value).KeepTTL(keepTTL))
return nil
})
}
@@ -42,9 +45,7 @@ func (n *Nodis) GetSet(key string, value []byte) []byte {
func (n *Nodis) SetEX(key string, value []byte, seconds int64) {
_ = n.exec(func(tx *Tx) error {
meta := tx.writeKey(key, n.newStr)
- if meta.expiration == 0 {
- meta.expiration = time.Now().UnixMilli()
- }
+ meta.expiration = time.Now().UnixMilli()
meta.expiration += seconds * 1000
meta.value.(*str.String).Set(value)
n.signalModifiedKey(key, meta)
@@ -57,9 +58,7 @@ func (n *Nodis) SetEX(key string, value []byte, seconds int64) {
func (n *Nodis) SetPX(key string, value []byte, milliseconds int64) {
_ = n.exec(func(tx *Tx) error {
meta := tx.writeKey(key, n.newStr)
- if meta.expiration == 0 {
- meta.expiration = time.Now().UnixMilli()
- }
+ meta.expiration = time.Now().UnixMilli()
meta.expiration += milliseconds
n.signalModifiedKey(key, meta)
n.notify(pb.NewOp(pb.OpType_Set, key).Value(value).Expiration(meta.expiration))
@@ -69,7 +68,7 @@ func (n *Nodis) SetPX(key string, value []byte, milliseconds int64) {
}
// SetNX set a key with a value if it does not exist
-func (n *Nodis) SetNX(key string, value []byte) bool {
+func (n *Nodis) SetNX(key string, value []byte, keepTTL bool) bool {
var ok bool
_ = n.exec(func(tx *Tx) error {
meta := tx.writeKey(key, nil)
@@ -77,9 +76,12 @@ func (n *Nodis) SetNX(key string, value []byte) bool {
return nil
}
meta = tx.newKey(meta, key, n.newStr)
+ if !keepTTL {
+ meta.expiration = 0
+ }
meta.value.(*str.String).Set(value)
n.signalModifiedKey(key, meta)
- n.notify(pb.NewOp(pb.OpType_Set, key).Value(value))
+ n.notify(pb.NewOp(pb.OpType_Set, key).Value(value).KeepTTL(keepTTL))
ok = true
return nil
})
@@ -87,16 +89,19 @@ func (n *Nodis) SetNX(key string, value []byte) bool {
}
// SetXX set a key with a value if it exists
-func (n *Nodis) SetXX(key string, value []byte) bool {
+func (n *Nodis) SetXX(key string, value []byte, keepTTL bool) bool {
var ok bool
_ = n.exec(func(tx *Tx) error {
meta := tx.writeKey(key, nil)
if !meta.isOk() {
return nil
}
- n.signalModifiedKey(key, meta)
- n.notify(pb.NewOp(pb.OpType_Set, key).Value(value))
meta.value.(*str.String).Set(value)
+ if !keepTTL {
+ meta.expiration = 0
+ }
+ n.signalModifiedKey(key, meta)
+ n.notify(pb.NewOp(pb.OpType_Set, key).Value(value).KeepTTL(keepTTL))
ok = true
return nil
})
@@ -321,6 +326,6 @@ func (n *Nodis) MSet(pairs ...string) {
return
}
for i := 0; i < len(pairs); i += 2 {
- n.Set(pairs[i], unsafe.Slice(unsafe.StringData(pairs[i+1]), len(pairs[i+1])))
+ n.Set(pairs[i], unsafe.Slice(unsafe.StringData(pairs[i+1]), len(pairs[i+1])), false)
}
}
diff --git a/str_test.go b/str_test.go
index 724b738..fabe737 100644
--- a/str_test.go
+++ b/str_test.go
@@ -10,17 +10,17 @@ func TestStr_Set(t *testing.T) {
Path: "testdata",
TidyDuration: 60 * time.Second,
})
- n.Set("a", []byte("b"))
+ n.Set("a", []byte("b"), false)
v := n.Get("a")
if string(v) != "b" {
t.Errorf("Set failed expected b got `%s`", string(v))
}
- n.Set("a", []byte("b"))
+ n.Set("a", []byte("b"), false)
v = n.Get("a")
if string(v) != "b" {
t.Errorf("Set failed expected b got `%s`", string(v))
}
- n.Set("a", []byte("b"))
+ n.Set("a", []byte("b"), false)
v = n.Get("a")
if string(v) != "b" {
t.Errorf("Set failed expected b got `%s`", string(v))
@@ -56,6 +56,6 @@ func TestStr_BitCount(t *testing.T) {
n.SetBit("a", 6, true)
n.SetBit("a", 7, true)
if n.BitCount("a", 0, 0, true) != 8 {
- t.Errorf("BitCount failed expected 8 got %d", n.BitCount("a", 0, 0,true))
+ t.Errorf("BitCount failed expected 8 got %d", n.BitCount("a", 0, 0, true))
}
}