Compare commits

..

No commits in common. "master" and "feat-storage-aof" have entirely different histories.

111 changed files with 579 additions and 11970 deletions

View File

@ -1,7 +0,0 @@
FROM ubuntu:18.04
WORKDIR /home/src/gitee.com/wheat-os/wheat-cache
ADD . /home/src/gitee.com/wheat-os/wheat-cache
RUN mkdir /etc/wheat-cache
RUN mv /home/src/gitee.com/wheat-os/wheat-cache/conf/wheat-cache.yaml /etc/wheat-cache/

Binary file not shown.

147
README.md

File diff suppressed because one or more lines are too long

View File

@ -1,8 +1,8 @@
package client package client
import ( import (
"gitee.com/wheat-os/wheatCache/client/middle" "gitee.com/timedb/wheatCache/client/middle"
"gitee.com/wheat-os/wheatCache/pkg/proto" "gitee.com/timedb/wheatCache/pkg/proto"
"google.golang.org/grpc" "google.golang.org/grpc"
) )

View File

@ -4,8 +4,8 @@ import (
"context" "context"
"testing" "testing"
"gitee.com/wheat-os/wheatCache/client/middle" "gitee.com/timedb/wheatCache/client/middle"
"gitee.com/wheat-os/wheatCache/pkg/proto" "gitee.com/timedb/wheatCache/pkg/proto"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -14,7 +14,10 @@ func TestClient(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
ctx := context.Background() ctx := context.Background()
bKey := proto.NewBaseKey("apple") bKey := &proto.BaseKey{
Key: "apple",
Ttl: 10,
}
resp, err := cli.Set(ctx, &proto.SetRequest{ resp, err := cli.Set(ctx, &proto.SetRequest{
Key: bKey, Key: bKey,
Val: "yyyy", Val: "yyyy",

View File

@ -3,7 +3,7 @@ package middle
import ( import (
"context" "context"
"gitee.com/wheat-os/wheatCache/pkg/proto" "gitee.com/timedb/wheatCache/pkg/proto"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"

View File

@ -3,7 +3,7 @@ version: 'v1.0'
env: 'dev' env: 'dev'
storage: storage:
host: '0.0.0.0' host: '127.0.0.1'
port: 5890 port: 5890
timeOut: 2 # second timeOut: 2 # second
@ -52,7 +52,7 @@ plugins-control:
plugins-infos-context: ["mock-plugins"] plugins-infos-context: ["mock-plugins"]
gateway: gateway:
host: '0.0.0.0' host: '127.0.0.1'
port: 5891 port: 5891
target: ["127.0.0.1:5890"] target: ["127.0.0.1:5890"]

View File

@ -1,2 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="94" height="20" role="img" aria-label="license: AFL3.0"><title>license: AFL3.0</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="94" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="47" height="20" fill="#555"/><rect x="47" width="47" height="20" fill="#97ca00"/><rect width="94" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="245" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="370">license</text><text x="245" y="140" transform="scale(.1)" fill="#fff" textLength="370">license</text><text aria-hidden="true" x="695" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="370">AFL3.0</text><text x="695" y="140" transform="scale(.1)" fill="#fff" textLength="370">AFL3.0</text></g></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 37 KiB

View File

@ -1,2 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="88" height="20" role="img" aria-label="Wheat: Cache"><title>Wheat: Cache</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="88" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="45" height="20" fill="#555"/><rect x="45" width="43" height="20" fill="#a4a61d"/><rect width="88" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="235" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="350">Wheat</text><text x="235" y="140" transform="scale(.1)" fill="#fff" textLength="350">Wheat</text><text aria-hidden="true" x="655" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="330">Cache</text><text x="655" y="140" transform="scale(.1)" fill="#fff" textLength="330">Cache</text></g></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.9 KiB

View File

@ -1,2 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="86" height="20" role="img" aria-label="version: v1.1"><title>version: v1.1</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="86" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="51" height="20" fill="#555"/><rect x="51" width="35" height="20" fill="#007ec6"/><rect width="86" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="265" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="410">version</text><text x="265" y="140" transform="scale(.1)" fill="#fff" textLength="410">version</text><text aria-hidden="true" x="675" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="250">v1.1</text><text x="675" y="140" transform="scale(.1)" fill="#fff" textLength="250">v1.1</text></g></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,13 +0,0 @@
### 事件驱动 2.0
### event 1.0 存在的问题
事件驱动 1.0 在 相互关联访问时,会发生 死锁问题, 导致一个事件执行周期失败
### event 2.0 新特性
- 异步事件支持
- 挂起操作
### event 2.0 设计图
![](../../_icon/event.svg)

View File

@ -1,15 +1,6 @@
### 快速进行 storage 开发 ### 快速进行 storage 开发
#### 开发环境
- ubuntu18, 可以使用 wsl
- go1.15+, python3
- jinja2
- go mod
- protobuf 3.17.3
- protoc-gen-go v1.26.0
#### storage 执行流程
![](../_icon/storage-dao.svg)
#### 分层,简介 #### 分层,简介
```sh ```sh
. .
@ -36,8 +27,6 @@
#### 快速开发接口 #### 快速开发接口
> [快速开发视频 blibli](https://www.bilibili.com/video/BV1HL4y1v7ps)
1. 修改 temp/tem.yaml 文件,添加新接口 1. 修改 temp/tem.yaml 文件,添加新接口
2. 在项目根目录执行 `make dcgen` 生成 proto 原始结构 2. 在项目根目录执行 `make dcgen` 生成 proto 原始结构
3. 修改对应新添加接口的 proto 文件,再次执行 `make dcgen` 完成 proto 迁移 3. 修改对应新添加接口的 proto 文件,再次执行 `make dcgen` 完成 proto 迁移

View File

@ -7,9 +7,9 @@ package dao
import ( import (
"testing" "testing"
_ "gitee.com/wheat-os/wheatCache/conf" _ "gitee.com/timedb/wheatCache/conf"
"gitee.com/wheat-os/wheatCache/pkg/lru" "gitee.com/timedb/wheatCache/pkg/lru"
"gitee.com/wheat-os/wheatCache/pkg/proto" "gitee.com/timedb/wheatCache/pkg/proto"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )

View File

@ -4,12 +4,12 @@ import (
"fmt" "fmt"
"net" "net"
_ "gitee.com/wheat-os/wheatCache/conf" _ "gitee.com/timedb/wheatCache/conf"
wheatCodec "gitee.com/wheat-os/wheatCache/gateway/codec" wheatCodec "gitee.com/timedb/wheatCache/gateway/codec"
"gitee.com/wheat-os/wheatCache/gateway/endpoint" "gitee.com/timedb/wheatCache/gateway/proxy"
"gitee.com/wheat-os/wheatCache/gateway/proxy" "gitee.com/timedb/wheatCache/gateway/transport"
"gitee.com/wheat-os/wheatCache/pkg/logx" "gitee.com/timedb/wheatCache/pkg/logx"
"gitee.com/wheat-os/wheatCache/pkg/util/server" "gitee.com/timedb/wheatCache/pkg/util/server"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
"google.golang.org/grpc" "google.golang.org/grpc"
@ -56,13 +56,13 @@ func GetGatewayServer() *grpc.Server {
logx.Debug("service target in %v", targets) logx.Debug("service target in %v", targets)
stream := proxy.GetDirectorByServiceHash() stream := proxy.GetDirectorByServiceHash()
endpoint := endpoint.NewHashEndpoint(endpoint.HashReplicasDefault, nil, targets...) transport := transport.NewHashTransport(transport.HashReplicasDefault, nil, targets...)
opts := make([]grpc.ServerOption, 0) opts := make([]grpc.ServerOption, 0)
opts = append( opts = append(
opts, opts,
grpc.ForceServerCodec(wheatCodec.Codec()), grpc.ForceServerCodec(wheatCodec.Codec()),
grpc.UnknownServiceHandler(proxy.TransparentHandler(stream, endpoint)), grpc.UnknownServiceHandler(proxy.TransparentHandler(stream, transport)),
) )
return grpc.NewServer(opts...) return grpc.NewServer(opts...)

View File

@ -1,6 +1,21 @@
/*
Copyright © 2021 NAME HERE <EMAIL ADDRESS>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main package main
import "gitee.com/wheat-os/wheatCache/gateway/cmd" import "gitee.com/timedb/wheatCache/gateway/cmd"
func main() { func main() {
cmd.Execute() cmd.Execute()

View File

@ -3,11 +3,11 @@ package proxy
import ( import (
"context" "context"
"gitee.com/wheat-os/wheatCache/gateway/endpoint" "gitee.com/timedb/wheatCache/gateway/transport"
"google.golang.org/grpc" "google.golang.org/grpc"
) )
type StreamDirector func(ctx context.Context, fullMethodName string, endpoint endpoint.EndpointInterface) (context.Context, *grpc.ClientConn, error) type StreamDirector func(ctx context.Context, fullMethodName string, transport transport.TransPortInterface) (context.Context, *grpc.ClientConn, error)
var ( var (
clientStreamDescForProxying = &grpc.StreamDesc{ clientStreamDescForProxying = &grpc.StreamDesc{

View File

@ -3,9 +3,9 @@ package proxy
import ( import (
"context" "context"
"gitee.com/wheat-os/wheatCache/gateway/codec" "gitee.com/timedb/wheatCache/gateway/codec"
"gitee.com/wheat-os/wheatCache/gateway/endpoint" "gitee.com/timedb/wheatCache/gateway/transport"
"gitee.com/wheat-os/wheatCache/pkg/proto" "gitee.com/timedb/wheatCache/pkg/proto"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"
@ -13,7 +13,7 @@ import (
) )
func GetDirectorByServiceHash() StreamDirector { func GetDirectorByServiceHash() StreamDirector {
return func(ctx context.Context, fullMethodName string, endpoint endpoint.EndpointInterface) (context.Context, *grpc.ClientConn, error) { return func(ctx context.Context, fullMethodName string, transport transport.TransPortInterface) (context.Context, *grpc.ClientConn, error) {
md, ok := metadata.FromIncomingContext(ctx) md, ok := metadata.FromIncomingContext(ctx)
if !ok { if !ok {
@ -26,7 +26,7 @@ func GetDirectorByServiceHash() StreamDirector {
"grpc header is not found %s, please check the client interceptor", proto.BaseKeyMethodKey) "grpc header is not found %s, please check the client interceptor", proto.BaseKeyMethodKey)
} }
target, err := endpoint.GetTargetAddr(baseKey...) target, err := transport.GetTargetAddr(baseKey...)
if err != nil { if err != nil {
return nil, nil, status.Errorf(codes.Unknown, "get transport err, err:%v", err) return nil, nil, status.Errorf(codes.Unknown, "get transport err, err:%v", err)
} }

View File

@ -4,8 +4,8 @@ import (
"context" "context"
"io" "io"
wheatCodec "gitee.com/wheat-os/wheatCache/gateway/codec" wheatCodec "gitee.com/timedb/wheatCache/gateway/codec"
"gitee.com/wheat-os/wheatCache/gateway/endpoint" "gitee.com/timedb/wheatCache/gateway/transport"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
@ -16,17 +16,17 @@ import (
// backends. It should be used as a `grpc.UnknownServiceHandler`. // backends. It should be used as a `grpc.UnknownServiceHandler`.
// //
// This can *only* be used if the `server` also uses grpcproxy.CodecForServer() ServerOption. // This can *only* be used if the `server` also uses grpcproxy.CodecForServer() ServerOption.
func TransparentHandler(director StreamDirector, endpoint endpoint.EndpointInterface) grpc.StreamHandler { func TransparentHandler(director StreamDirector, tranport transport.TransPortInterface) grpc.StreamHandler {
streamer := &handler{ streamer := &handler{
director, director,
endpoint, tranport,
} }
return streamer.handler return streamer.handler
} }
type handler struct { type handler struct {
director StreamDirector director StreamDirector
endpoint endpoint.EndpointInterface transport transport.TransPortInterface
} }
// handler is where the real magic of proxying happens. // handler is where the real magic of proxying happens.
@ -38,7 +38,7 @@ func (s *handler) handler(srv interface{}, serverStream grpc.ServerStream) error
return status.Errorf(codes.Internal, "lowLevelServerStream not exists in context") return status.Errorf(codes.Internal, "lowLevelServerStream not exists in context")
} }
outgoingCtx, backendConn, err := s.director(serverStream.Context(), fullMethodName, s.endpoint) outgoingCtx, backendConn, err := s.director(serverStream.Context(), fullMethodName, s.transport)
if err != nil { if err != nil {
return err return err
} }

View File

@ -1,6 +1,6 @@
package endpoint package transport
type EndpointInterface interface { type TransPortInterface interface {
GetTargetAddr(...string) (string, error) GetTargetAddr(...string) (string, error)
IsEmpty() bool IsEmpty() bool
AddTarget(targets ...string) AddTarget(targets ...string)

View File

@ -1,11 +1,11 @@
package endpoint package transport
import ( import (
"hash/crc32" "hash/crc32"
"sort" "sort"
"strconv" "strconv"
"gitee.com/wheat-os/wheatCache/pkg/errorx" "gitee.com/timedb/wheatCache/pkg/errorx"
) )
type HashFunc func(data []byte) uint32 type HashFunc func(data []byte) uint32
@ -25,34 +25,34 @@ func (s UInt32Slice) Swap(i, j int) {
s[i], s[j] = s[j], s[i] s[i], s[j] = s[j], s[i]
} }
type HashEndpoint struct { type HashTransport struct {
hash HashFunc hash HashFunc
replicas int // 复制因子 replicas int // 复制因子
keys UInt32Slice keys UInt32Slice
hashMap map[uint32]string // taraget 隐射 hashMap map[uint32]string // taraget 隐射
} }
func NewHashEndpoint(replicas int, fn HashFunc, target ...string) EndpointInterface { func NewHashTransport(replicas int, fn HashFunc, target ...string) TransPortInterface {
endpoint := &HashEndpoint{ transport := &HashTransport{
replicas: replicas, replicas: replicas,
hash: fn, hash: fn,
hashMap: make(map[uint32]string, len(target)), hashMap: make(map[uint32]string, len(target)),
} }
if endpoint.hash == nil { if transport.hash == nil {
endpoint.hash = crc32.ChecksumIEEE // 默认使用 CRC32 算法 transport.hash = crc32.ChecksumIEEE // 默认使用 CRC32 算法
} }
endpoint.AddTarget(target...) transport.AddTarget(target...)
return endpoint return transport
} }
func (h *HashEndpoint) IsEmpty() bool { func (h *HashTransport) IsEmpty() bool {
return len(h.keys) == 0 return len(h.keys) == 0
} }
func (h *HashEndpoint) AddTarget(targets ...string) { func (h *HashTransport) AddTarget(targets ...string) {
for _, tar := range targets { for _, tar := range targets {
for i := 0; i < h.replicas; i++ { for i := 0; i < h.replicas; i++ {
@ -66,7 +66,7 @@ func (h *HashEndpoint) AddTarget(targets ...string) {
sort.Sort(h.keys) sort.Sort(h.keys)
} }
func (h *HashEndpoint) GetTargetAddr(str ...string) (string, error) { func (h *HashTransport) GetTargetAddr(str ...string) (string, error) {
if h.IsEmpty() { if h.IsEmpty() {
return "", errorx.New("gateway not register transport") return "", errorx.New("gateway not register transport")
} }

View File

@ -1,4 +1,4 @@
package endpoint package transport
import ( import (
"testing" "testing"
@ -7,7 +7,7 @@ import (
) )
func TestHashTransport_GetTargetAddr(t *testing.T) { func TestHashTransport_GetTargetAddr(t *testing.T) {
tran := NewHashEndpoint(3, nil, "127.0.0.1:5581", "127.0.0.1:5582", "127.0.0.1:5583") tran := NewHashTransport(3, nil, "127.0.0.1:5581", "127.0.0.1:5582", "127.0.0.1:5583")
key := "test" key := "test"

3
go.mod
View File

@ -1,9 +1,8 @@
module gitee.com/wheat-os/wheatCache module gitee.com/timedb/wheatCache
go 1.16 go 1.16
require ( require (
github.com/golang/mock v1.5.0
github.com/spf13/cobra v1.2.1 github.com/spf13/cobra v1.2.1
github.com/spf13/viper v1.8.1 github.com/spf13/viper v1.8.1
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0

1
go.sum
View File

@ -89,7 +89,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=

View File

@ -52,7 +52,3 @@ init-conf:
.PHONY: gen-service .PHONY: gen-service
gen-service: gen-service:
@python3 ./shell/make_service.py @python3 ./shell/make_service.py
.PHONY: gen-mock
gen-mock:
@mockgen -source=./pkg/proto/storage.pb.go CommServerClient > ./mock/storage/mock_client.gen.go

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +0,0 @@
package errorx
func EventRecoveryErr() error {
return New("this event has been recycled")
}

View File

@ -5,5 +5,5 @@ func LruNotWorkFuncEventErr() error {
} }
func KeyBaseIsNilErr() error { func KeyBaseIsNilErr() error {
return New("key base can't be nil") return New("key base not is nil")
} }

View File

@ -4,7 +4,7 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
"gitee.com/wheat-os/wheatCache/pkg/errorx" "gitee.com/timedb/wheatCache/pkg/errorx"
) )
// 事件 poll 降低 new 对象的频率 // 事件 poll 降低 new 对象的频率

View File

@ -1,21 +0,0 @@
package event2
import "context"
type Consumer struct {
driver DriverInterface
}
func (c *Consumer) Receive(ctx context.Context) *event {
return c.driver.Get()
}
func (c *Consumer) NewEvent(name string) *event {
return c.driver.NewEvent(name)
}
func NewConsumer(driver DriverInterface) ConsumerInterface {
return &Consumer{
driver: driver,
}
}

View File

@ -1,49 +0,0 @@
package event2
import (
"context"
)
const (
initEventState = int32(iota) // 初始化状态
waitEventState // 等待状态
workEventState // 工作状态
closeEventState // 事件关闭状态
recoveryEventState // 事件回收状态
)
const (
awaitThread = 3
)
const (
WorkFuncEventKey = "workFunc"
)
// 线程安全
type EventWorkFunc func() (interface{}, error)
// 挂起事件, 线程不安全
type EventAwaitFunc func() (interface{}, error)
// 实际操作
type awaitFunc func() (*event, interface{}, error)
type DriverInterface interface {
Get() *event
Put(*event)
GetLength() int
NewEvent(string) *event
await(awaitFunc)
recovery(e *event)
}
type ProduceInterface interface {
Call(context.Context, *event)
NewEvent(string) *event
}
type ConsumerInterface interface {
Receive(ctx context.Context) *event
}

View File

@ -1,221 +0,0 @@
package event2
import (
"sync/atomic"
"time"
"gitee.com/wheat-os/wheatCache/pkg/errorx"
)
type event struct {
msgCtx map[string]interface{}
eventName string
msg map[string]string // 消息
waitResult chan interface{} // 等待返回
err error
eventStatus int32
ttlManage *time.Timer
parentDriver DriverInterface
}
func (e *event) reset() {
if e.ttlManage != nil {
e.ttlManage.Stop()
if len(e.ttlManage.C) > 0 {
<-e.ttlManage.C
}
}
e.err = nil
// 清空结果
if len(e.waitResult) != 0 {
<-e.waitResult
}
}
func (e *event) Recovery() {
e.parentDriver.recovery(e)
}
func (e *event) SetMsg(key string, val string) {
if e.msg == nil {
e.msg = make(map[string]string)
}
e.msg[key] = val
}
func (e *event) GetMsg(key string) string {
if e.msg == nil {
return ""
}
return e.msg[key]
}
func (e *event) GetEventName() string {
return e.eventName
}
// SetValue 写入 ctx 传递用参数
func (e *event) SetValue(key string, value interface{}) {
if e.msgCtx == nil {
e.msgCtx = make(map[string]interface{})
}
e.msgCtx[key] = value
}
func (e *event) GetValue(key string) (interface{}, bool) {
if e.msgCtx == nil {
return nil, false
}
val, ok := e.msgCtx[key]
return val, ok
}
func (e *event) InitWaitEvent() {
e.reset()
if e.waitResult == nil {
e.waitResult = make(chan interface{})
}
atomic.SwapInt32(&e.eventStatus, waitEventState)
}
func (e *event) SetResultErr(err error) {
if !atomic.CompareAndSwapInt32(&e.eventStatus, waitEventState, workEventState) {
return
}
e.err = err
e.waitResult <- nil
}
// StartWaitEvent 开始一个等待任务
func (e *event) StartWaitEvent(ttl time.Duration) (interface{}, error) {
if e.ttlManage == nil {
e.ttlManage = time.NewTimer(ttl)
} else {
e.ttlManage.Reset(ttl)
}
for {
select {
case <-e.ttlManage.C:
if atomic.CompareAndSwapInt32(&e.eventStatus, waitEventState, closeEventState) {
return nil, errorx.TimeOutErr()
}
continue
case result := <-e.waitResult:
atomic.SwapInt32(&e.eventStatus, closeEventState)
return result, e.err
}
}
}
// 实际执行推送
func (e *event) execWorker(res interface{}, err error) {
switch work := res.(type) {
case EventAwaitFunc:
await := func() (*event, interface{}, error) {
result, err := work()
return e, result, err
}
e.parentDriver.await(await)
case EventWorkFunc:
e.InitWaitEvent()
e.SetValue(WorkFuncEventKey, work)
e.parentDriver.Put(e)
default:
e.err = err
e.waitResult <- res
}
}
func (e *event) ExecWorkAndSendResult(work EventWorkFunc) (interface{}, error) {
if !atomic.CompareAndSwapInt32(&e.eventStatus, waitEventState, workEventState) {
return nil, errorx.New("not wait status, exec err")
}
res, err := work()
e.execWorker(res, err)
return res, err
}
type driver struct {
waitQueue chan awaitFunc
eventQueue chan *event
levelQueue chan *event
// event 池的实现
poll chan *event
maxPoolSize int32
nowPoolSize int32
}
func NewDriver(maxSize int) DriverInterface {
d := &driver{
// pool
maxPoolSize: int32(maxSize),
nowPoolSize: 0,
poll: make(chan *event, maxSize),
// waitQueue 1/3 的挂起指标
waitQueue: make(chan awaitFunc, maxSize/3),
levelQueue: make(chan *event, maxSize/3),
eventQueue: make(chan *event, maxSize),
}
d.awaitWorker()
return d
}
func (d *driver) NewEvent(name string) *event {
issSize := atomic.LoadInt32(&d.nowPoolSize)
if issSize < d.maxPoolSize {
atomic.AddInt32(&d.nowPoolSize, 1)
return d.newEvent(name)
}
e := <-d.poll
e.eventName = name
return e
}
func (d *driver) newEvent(name string) *event {
status := initEventState
return &event{
eventStatus: status,
parentDriver: d,
eventName: name,
}
}
// 先尝试 level
func (d *driver) Get() *event {
if len(d.levelQueue) > 0 {
return <-d.levelQueue
}
return <-d.eventQueue
}
func (d *driver) Put(e *event) {
d.eventQueue <- e
}
func (d *driver) GetLength() int {
return len(d.eventQueue) + len(d.levelQueue)
}
func (d *driver) recovery(e *event) {
atomic.SwapInt32(&e.eventStatus, recoveryEventState)
e.reset()
d.poll <- e
}
// 挂起操作相关
func (d *driver) await(a awaitFunc) {
d.waitQueue <- a
}

View File

@ -1,152 +0,0 @@
package event2
import (
"context"
"fmt"
"strconv"
"sync"
"testing"
"time"
"github.com/stretchr/testify/require"
)
const testEvent = "1001"
const waitTestEvent = "1002"
// 简单的 单向 event 使用
func Test_EventDriver(t *testing.T) {
driver := NewDriver(2000)
produce := NewProduce(driver)
consumer := NewConsumer(driver)
ctx := context.Background()
wait := sync.WaitGroup{}
wait.Add(30000)
go func() {
for i := 0; i < 30000; i++ {
event := produce.NewEvent(testEvent)
event.SetMsg("k", strconv.Itoa(i))
produce.Call(ctx, event)
}
}()
go func() {
for {
event := consumer.Receive(ctx)
fmt.Println(event.GetMsg("k"))
event.Recovery()
wait.Done()
}
}()
wait.Wait()
}
// 双向 event
func Test_EventDriver_Tow_way(t *testing.T) {
ctx := context.Background()
driver := NewDriver(2000)
produce := NewProduce(driver)
consumer := NewConsumer(driver)
go func() {
for {
event := consumer.Receive(ctx)
work, ok := event.GetValue(WorkFuncEventKey)
if !ok {
panic("get work key err")
}
workFunc, ok := work.(EventWorkFunc)
if !ok {
panic("work func err")
}
_, err := event.ExecWorkAndSendResult(workFunc)
require.NoError(t, err)
}
}()
// 一般的 two-way 模式
for i := 0; i < 10000; i++ {
event := produce.NewEvent(waitTestEvent)
event.InitWaitEvent()
event.SetValue(WorkFuncEventKey, EventWorkFunc(func() (interface{}, error) {
return i + 1, nil
}))
produce.Call(ctx, event)
res, err := event.StartWaitEvent(2 * time.Second)
require.NoError(t, err)
require.Equal(t, res, i+1)
event.Recovery()
}
// 挂起模式2 秒左右的执行时间
group := sync.WaitGroup{}
group.Add(5)
for i := 0; i < 5; i++ {
go func(i int) {
event := produce.NewEvent(waitTestEvent)
event.InitWaitEvent()
event.SetValue(WorkFuncEventKey, EventWorkFunc(func() (interface{}, error) {
// 访问 await Work 来发起一个 异步请求操作
return EventAwaitFunc(func() (interface{}, error) {
time.Sleep(time.Second)
return i + 1, nil
}), nil
}))
produce.Call(ctx, event)
res, err := event.StartWaitEvent(2 * time.Second)
require.NoError(t, err)
require.Equal(t, res, i+1)
event.Recovery()
group.Done()
}(i)
}
// 挂起成功不发生超时
for i := 0; i < 10000; i++ {
event := produce.NewEvent(waitTestEvent)
event.InitWaitEvent()
event.SetValue(WorkFuncEventKey, EventWorkFunc(func() (interface{}, error) {
return i + 1, nil
}))
produce.Call(ctx, event)
res, err := event.StartWaitEvent(500 * time.Millisecond)
require.NoError(t, err)
require.Equal(t, res, i+1)
event.Recovery()
}
group.Wait()
// 挂起一个高延迟操作, 保证局部操作还在事件中
group = sync.WaitGroup{}
group.Add(5)
for i := 0; i < 5; i++ {
event := produce.NewEvent(waitTestEvent)
event.InitWaitEvent()
event.SetValue(WorkFuncEventKey, EventWorkFunc(func() (interface{}, error) {
return EventAwaitFunc(func() (interface{}, error) {
// 返回值为 EventWorkFunc 时, 会重新加入末端队列
return EventWorkFunc(func() (interface{}, error) {
return i + 1, nil
}), nil
}), nil
}))
produce.Call(ctx, event)
res, err := event.StartWaitEvent(2 * time.Second)
require.NoError(t, err)
require.Equal(t, res, i+1)
event.Recovery()
group.Done()
fmt.Println(i)
}
group.Wait()
}

View File

@ -1,21 +0,0 @@
package event2
import "context"
type Produce struct {
driver DriverInterface
}
func (p *Produce) NewEvent(name string) *event {
return p.driver.NewEvent(name)
}
func (p *Produce) Call(ctx context.Context, e *event) {
p.driver.Put(e)
}
func NewProduce(driver DriverInterface) ProduceInterface {
return &Produce{
driver: driver,
}
}

View File

@ -1,13 +0,0 @@
package event2
func (d *driver) awaitWorker() {
for i := 0; i < awaitThread; i++ {
go func() {
for {
awaitFunc := <-d.waitQueue
e, res, err := awaitFunc()
e.execWorker(res, err)
}
}()
}
}

View File

@ -2,10 +2,9 @@ package logx
import ( import (
"context" "context"
"sync" "gitee.com/timedb/wheatCache/pkg/event"
"gitee.com/wheat-os/wheatCache/pkg/event"
"github.com/spf13/viper" "github.com/spf13/viper"
"sync"
) )
type LogLevelState int8 type LogLevelState int8

View File

@ -8,8 +8,8 @@ import (
"strings" "strings"
"time" "time"
"gitee.com/wheat-os/wheatCache/pkg/event" "gitee.com/timedb/wheatCache/pkg/event"
middleMsg "gitee.com/wheat-os/wheatCache/pkg/middle-msg" middleMsg "gitee.com/timedb/wheatCache/pkg/middle-msg"
) )
func With(ctx context.Context, p event.ProduceInterface) *upLogger { func With(ctx context.Context, p event.ProduceInterface) *upLogger {

View File

@ -2,10 +2,9 @@ package logx
import ( import (
"context" "context"
_ "gitee.com/timedb/wheatCache/conf"
"gitee.com/timedb/wheatCache/pkg/event"
"testing" "testing"
_ "gitee.com/wheat-os/wheatCache/conf"
"gitee.com/wheat-os/wheatCache/pkg/event"
) )
func TestStd(t *testing.T) { func TestStd(t *testing.T) {

View File

@ -4,16 +4,17 @@ import (
"sync" "sync"
"time" "time"
"gitee.com/wheat-os/wheatCache/pkg/proto" "gitee.com/timedb/wheatCache/pkg/proto"
"gitee.com/wheat-os/wheatCache/pkg/structure" "gitee.com/timedb/wheatCache/pkg/structure"
) )
type SingleWorkFunc func() interface{} type SingleWorkFunc func() interface{}
const ( const (
OptionEventName = "operateEvent" OptionEventName = "operateEvent"
CleanEventName = "clearEvent" CleanEventName = "clearEvent"
TtlEventName = "ttlEvent" TtlEventName = "ttlEvent"
WorkFuncEventKey = "workFunc"
) )
var ( var (

View File

@ -4,14 +4,13 @@ import (
"container/list" "container/list"
"sync/atomic" "sync/atomic"
_ "gitee.com/wheat-os/wheatCache/conf" _ "gitee.com/timedb/wheatCache/conf"
"gitee.com/wheat-os/wheatCache/pkg/errorx" "gitee.com/timedb/wheatCache/pkg/errorx"
"gitee.com/wheat-os/wheatCache/pkg/event" "gitee.com/timedb/wheatCache/pkg/event"
"gitee.com/wheat-os/wheatCache/pkg/event2" "gitee.com/timedb/wheatCache/pkg/middle"
"gitee.com/wheat-os/wheatCache/pkg/middle" "gitee.com/timedb/wheatCache/pkg/proto"
"gitee.com/wheat-os/wheatCache/pkg/proto" "gitee.com/timedb/wheatCache/pkg/structure"
"gitee.com/wheat-os/wheatCache/pkg/structure" "gitee.com/timedb/wheatCache/pkg/util"
"gitee.com/wheat-os/wheatCache/pkg/util"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@ -30,9 +29,9 @@ type SingleCache struct {
lruMaxDiverSize int lruMaxDiverSize int
lruTtlManage *lruTTl // 定时清理器 lruTtlManage *lruTTl // 定时清理器
lruDriver event2.DriverInterface lruDriver event.DriverInterface
lruConsumer event2.ConsumerInterface lruConsumer event.ConsumerInterface
lruCleanProduce event2.ProduceInterface // 发送清理事件 lruCleanProduce event.ProduceInterface // 发送清理事件
middleProduce event.ProduceInterface // 中间件驱动 middleProduce event.ProduceInterface // 中间件驱动
} }
@ -77,7 +76,7 @@ func cacheInit() (int64, int64, int, int) {
// NewLRUCache lru初始化 // NewLRUCache lru初始化
func NewLRUCache() *SingleCache { func NewLRUCache() *SingleCache {
maxSize, clearSize, maxDriverSize, detachNum := cacheInit() maxSize, clearSize, maxDriverSize, detachNum := cacheInit()
lruDriver := event2.NewDriver(maxDriverSize) lruDriver := event.NewDriver(maxDriverSize)
lruCacheOnce.Do(func() { lruCacheOnce.Do(func() {
lru := &SingleCache{ lru := &SingleCache{
maxsize: maxSize, maxsize: maxSize,
@ -87,8 +86,8 @@ func NewLRUCache() *SingleCache {
lruMap: make(map[string]*list.Element), lruMap: make(map[string]*list.Element),
lruMaxDiverSize: maxDriverSize, lruMaxDiverSize: maxDriverSize,
lruDriver: lruDriver, lruDriver: lruDriver,
lruConsumer: event2.NewConsumer(lruDriver), lruConsumer: event.NewConsumer(lruDriver),
lruCleanProduce: event2.NewProduce(lruDriver), lruCleanProduce: event.NewProduce(lruDriver),
middleProduce: event.NewProduce(middle.NewMiddleWare().GetEventDriver()), middleProduce: event.NewProduce(middle.NewMiddleWare().GetEventDriver()),
lruTtlManage: newLruTTl(detachNum), lruTtlManage: newLruTTl(detachNum),
} }
@ -104,7 +103,7 @@ func NewLRUCache() *SingleCache {
} }
// GetDriver 获取驱动 // GetDriver 获取驱动
func (lru *SingleCache) GetDriver() event2.DriverInterface { func (lru *SingleCache) GetDriver() event.DriverInterface {
return lru.lruDriver return lru.lruDriver
} }
@ -123,9 +122,6 @@ func (lru *SingleCache) Add(key *proto.BaseKey, val structure.KeyBaseInterface)
} }
if elVal, ok := lru.lruMap[key.Key]; ok { if elVal, ok := lru.lruMap[key.Key]; ok {
lru.li.MoveToFront(elVal) lru.li.MoveToFront(elVal)
oldSize := elVal.Value.(structure.KeyBaseInterface).SizeByte()
lru.UpdateLruSize(structure.UpdateLength(val.SizeByte() - oldSize))
elVal.Value = keyBaseVal elVal.Value = keyBaseVal
return nil return nil
} }

View File

@ -5,8 +5,8 @@ import (
"testing" "testing"
"time" "time"
"gitee.com/wheat-os/wheatCache/pkg/proto" "gitee.com/timedb/wheatCache/pkg/proto"
"gitee.com/wheat-os/wheatCache/pkg/structure/stringx" "gitee.com/timedb/wheatCache/pkg/structure/stringx"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )

View File

@ -4,8 +4,8 @@ import (
"sync" "sync"
"time" "time"
"gitee.com/wheat-os/wheatCache/pkg/proto" "gitee.com/timedb/wheatCache/pkg/proto"
"gitee.com/wheat-os/wheatCache/pkg/util/skiplist" "gitee.com/timedb/wheatCache/pkg/util/skiplist"
) )
// lru 的 ttl 管理器 // lru 的 ttl 管理器
@ -20,11 +20,6 @@ func (l *lruTTl) setKeys(key *proto.BaseKey) int64 {
l.mu.Lock() l.mu.Lock()
defer l.mu.Unlock() defer l.mu.Unlock()
// 永久存储
if key.Expire == nil && key.Ttl == 0 {
return 0
}
ttlTime := time.Now().Unix() ttlTime := time.Now().Unix()
if key.Expire != nil { if key.Expire != nil {
ttlTime = key.Expire.GetSeconds() ttlTime = key.Expire.GetSeconds()

View File

@ -5,8 +5,8 @@ import (
"testing" "testing"
"time" "time"
"gitee.com/wheat-os/wheatCache/pkg/proto" "gitee.com/timedb/wheatCache/pkg/proto"
"gitee.com/wheat-os/wheatCache/pkg/structure/stringx" "gitee.com/timedb/wheatCache/pkg/structure/stringx"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )

View File

@ -5,19 +5,19 @@ import (
"testing" "testing"
"time" "time"
"gitee.com/wheat-os/wheatCache/pkg/event2" "gitee.com/timedb/wheatCache/pkg/event"
"gitee.com/wheat-os/wheatCache/pkg/logx" "gitee.com/timedb/wheatCache/pkg/logx"
"gitee.com/wheat-os/wheatCache/pkg/proto" "gitee.com/timedb/wheatCache/pkg/proto"
"gitee.com/wheat-os/wheatCache/pkg/structure/stringx" "gitee.com/timedb/wheatCache/pkg/structure/stringx"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestWorker(t *testing.T) { func TestWorker(t *testing.T) {
ctx := context.Background() ctx := context.Background()
lru := NewLRUCache() lru := NewLRUCache()
produce := event2.NewProduce(lru.GetDriver()) produce := event.NewProduce(lru.GetDriver())
workEvent := produce.NewEvent(OptionEventName) workEvent := produce.NewEvent(OptionEventName)
workEvent.SetValue(event2.WorkFuncEventKey, event2.EventWorkFunc(func() (interface{}, error) { workEvent.SetValue(WorkFuncEventKey, event.EventWorkFunc(func() (interface{}, error) {
v1 := stringx.NewStringSingle() v1 := stringx.NewStringSingle()
key := proto.BaseKey{ key := proto.BaseKey{
Key: "v1", Key: "v1",
@ -36,11 +36,11 @@ func TestWorker(t *testing.T) {
func TestSingleCache_DelToClearSize(t *testing.T) { func TestSingleCache_DelToClearSize(t *testing.T) {
ctx := context.Background() ctx := context.Background()
lru := NewLRUCache() lru := NewLRUCache()
produce := event2.NewProduce(lru.GetDriver()) produce := event.NewProduce(lru.GetDriver())
for i := int32(20000); i > 0; i-- { for i := int32(20000); i > 0; i-- {
workEvent := produce.NewEvent(OptionEventName) workEvent := produce.NewEvent(OptionEventName)
workEvent.SetValue(event2.WorkFuncEventKey, event2.EventWorkFunc(func() (interface{}, error) { workEvent.SetValue(WorkFuncEventKey, event.EventWorkFunc(func() (interface{}, error) {
v1 := stringx.NewStringSingle() v1 := stringx.NewStringSingle()
key := proto.BaseKey{ key := proto.BaseKey{
Key: string(i), Key: string(i),
@ -53,7 +53,7 @@ func TestSingleCache_DelToClearSize(t *testing.T) {
workEvent.InitWaitEvent() workEvent.InitWaitEvent()
produce.Call(ctx, workEvent) produce.Call(ctx, workEvent)
workEvent.StartWaitEvent(2 * time.Second) workEvent.StartWaitEvent(2 * time.Second)
workEvent.Recovery() produce.Recovery(workEvent)
} }
logx.Info("start size is %d", lru.nowSize) logx.Info("start size is %d", lru.nowSize)

View File

@ -4,18 +4,17 @@ import (
"context" "context"
"time" "time"
"gitee.com/wheat-os/wheatCache/pkg/errorx" "gitee.com/timedb/wheatCache/pkg/errorx"
"gitee.com/wheat-os/wheatCache/pkg/event" "gitee.com/timedb/wheatCache/pkg/event"
"gitee.com/wheat-os/wheatCache/pkg/event2" "gitee.com/timedb/wheatCache/pkg/logx"
"gitee.com/wheat-os/wheatCache/pkg/logx" mMsg "gitee.com/timedb/wheatCache/pkg/middle-msg"
mMsg "gitee.com/wheat-os/wheatCache/pkg/middle-msg"
) )
func (lru *SingleCache) lruSingleWork() { func (lru *SingleCache) lruSingleWork() {
ctx := context.Background() ctx := context.Background()
for { for {
workEvent := lru.lruConsumer.Receive(ctx) workEvent := lru.lruConsumer.Receive(ctx)
workFunc, ok := workEvent.GetValue(event2.WorkFuncEventKey) workFunc, ok := workEvent.GetValue(WorkFuncEventKey)
if !ok { if !ok {
workEvent.SetResultErr(errorx.LruNotWorkFuncEventErr()) workEvent.SetResultErr(errorx.LruNotWorkFuncEventErr())
continue continue
@ -23,7 +22,7 @@ func (lru *SingleCache) lruSingleWork() {
switch workEvent.GetEventName() { switch workEvent.GetEventName() {
case OptionEventName: case OptionEventName:
if work, ok := workFunc.(event2.EventWorkFunc); ok { if work, ok := workFunc.(event.EventWorkFunc); ok {
workEvent.ExecWorkAndSendResult(work) workEvent.ExecWorkAndSendResult(work)
} }
@ -34,12 +33,12 @@ func (lru *SingleCache) lruSingleWork() {
lru.lruCleanProduce.Call(ctx, workEvent) lru.lruCleanProduce.Call(ctx, workEvent)
continue continue
} }
if work, ok := workFunc.(event2.EventWorkFunc); ok { if work, ok := workFunc.(event.EventWorkFunc); ok {
workEvent.ExecWorkAndSendResult(work) workEvent.ExecWorkAndSendResult(work)
} }
case TtlEventName: case TtlEventName:
if work, ok := workFunc.(event2.EventWorkFunc); ok { if work, ok := workFunc.(event.EventWorkFunc); ok {
workEvent.ExecWorkAndSendResult(work) workEvent.ExecWorkAndSendResult(work)
} }
} }
@ -53,7 +52,7 @@ func (lru *SingleCache) lruTtlWork() {
// 清理事件 // 清理事件
go func() { go func() {
work := event2.EventWorkFunc(func() (interface{}, error) { work := event.EventWorkFunc(func() (interface{}, error) {
beforeTime := time.Now().Unix() beforeTime := time.Now().Unix()
cle := lru.lruTtlManage.detachNum cle := lru.lruTtlManage.detachNum
@ -81,12 +80,12 @@ func (lru *SingleCache) lruTtlWork() {
} }
ttlEvent := lru.lruCleanProduce.NewEvent(TtlEventName) ttlEvent := lru.lruCleanProduce.NewEvent(TtlEventName)
ttlEvent.SetValue(event2.WorkFuncEventKey, work) ttlEvent.SetValue(WorkFuncEventKey, work)
ttlEvent.InitWaitEvent() ttlEvent.InitWaitEvent()
lru.lruCleanProduce.Call(ctx, ttlEvent) lru.lruCleanProduce.Call(ctx, ttlEvent)
keys, err := ttlEvent.StartWaitEvent(time.Second * 2) keys, err := ttlEvent.StartWaitEvent(time.Second * 2)
ttlEvent.Recovery() lru.lruCleanProduce.Recovery(ttlEvent)
mMsg.SendMiddleMsg(ctx, lru.middleProduce, mMsg.LruTTlContext{ mMsg.SendMiddleMsg(ctx, lru.middleProduce, mMsg.LruTTlContext{
Keys: keys.([]string), Keys: keys.([]string),
@ -119,7 +118,7 @@ func (lru *SingleCache) cleanWork() {
time.Sleep(2 * time.Second) time.Sleep(2 * time.Second)
if lru.clearSize < lru.nowSize { if lru.clearSize < lru.nowSize {
lruCleanEvent := lru.lruCleanProduce.NewEvent(CleanEventName) lruCleanEvent := lru.lruCleanProduce.NewEvent(CleanEventName)
lruCleanEvent.SetValue(event2.WorkFuncEventKey, work) lruCleanEvent.SetValue(WorkFuncEventKey, work)
lruCleanEvent.InitWaitEvent() lruCleanEvent.InitWaitEvent()
lru.lruCleanProduce.Call(cxt, lruCleanEvent) lru.lruCleanProduce.Call(cxt, lruCleanEvent)
@ -129,7 +128,7 @@ func (lru *SingleCache) cleanWork() {
} }
// 归还 // 归还
lruCleanEvent.Recovery() lru.lruCleanProduce.Recovery(lruCleanEvent)
} }
} }
} }

View File

@ -3,8 +3,8 @@ package middlemsg
import ( import (
"context" "context"
"gitee.com/wheat-os/wheatCache/pkg/errorx" "gitee.com/timedb/wheatCache/pkg/errorx"
"gitee.com/wheat-os/wheatCache/pkg/event" "gitee.com/timedb/wheatCache/pkg/event"
) )
const ( const (

View File

@ -1,10 +1,10 @@
package middle package middle
import ( import (
_ "gitee.com/wheat-os/wheatCache/conf" _ "gitee.com/timedb/wheatCache/conf"
"gitee.com/wheat-os/wheatCache/pkg/event" "gitee.com/timedb/wheatCache/pkg/event"
"gitee.com/wheat-os/wheatCache/plugins" "gitee.com/timedb/wheatCache/plugins"
"gitee.com/wheat-os/wheatCache/plugins/config" "gitee.com/timedb/wheatCache/plugins/config"
"github.com/spf13/viper" "github.com/spf13/viper"
) )

View File

@ -3,8 +3,8 @@ package middle
import ( import (
"context" "context"
"gitee.com/wheat-os/wheatCache/pkg/logx" "gitee.com/timedb/wheatCache/pkg/logx"
middleMsg "gitee.com/wheat-os/wheatCache/pkg/middle-msg" middleMsg "gitee.com/timedb/wheatCache/pkg/middle-msg"
) )
func (m *MiddleWare) startWork() { func (m *MiddleWare) startWork() {

View File

@ -6,8 +6,8 @@ import (
"testing" "testing"
"time" "time"
"gitee.com/wheat-os/wheatCache/pkg/event" "gitee.com/timedb/wheatCache/pkg/event"
middleMsg "gitee.com/wheat-os/wheatCache/pkg/middle-msg" middleMsg "gitee.com/timedb/wheatCache/pkg/middle-msg"
) )
func Test_middleware_loadPlugins(t *testing.T) { func Test_middleware_loadPlugins(t *testing.T) {

View File

@ -84,44 +84,6 @@ func (x *BaseKey) GetExpire() *timestamppb.Timestamp {
return nil return nil
} }
type External struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *External) Reset() {
*x = External{}
if protoimpl.UnsafeEnabled {
mi := &file_base_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *External) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*External) ProtoMessage() {}
func (x *External) ProtoReflect() protoreflect.Message {
mi := &file_base_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use External.ProtoReflect.Descriptor instead.
func (*External) Descriptor() ([]byte, []int) {
return file_base_proto_rawDescGZIP(), []int{1}
}
var File_base_proto protoreflect.FileDescriptor var File_base_proto protoreflect.FileDescriptor
var file_base_proto_rawDesc = []byte{ var file_base_proto_rawDesc = []byte{
@ -134,9 +96,8 @@ var file_base_proto_rawDesc = []byte{
0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54,
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65,
0x22, 0x0a, 0x0a, 0x08, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x42, 0x0b, 0x5a, 0x09, 0x42, 0x0b, 0x5a, 0x09, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70,
0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x33,
} }
var ( var (
@ -151,14 +112,13 @@ func file_base_proto_rawDescGZIP() []byte {
return file_base_proto_rawDescData return file_base_proto_rawDescData
} }
var file_base_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_base_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_base_proto_goTypes = []interface{}{ var file_base_proto_goTypes = []interface{}{
(*BaseKey)(nil), // 0: BaseKey (*BaseKey)(nil), // 0: BaseKey
(*External)(nil), // 1: External (*timestamppb.Timestamp)(nil), // 1: google.protobuf.Timestamp
(*timestamppb.Timestamp)(nil), // 2: google.protobuf.Timestamp
} }
var file_base_proto_depIdxs = []int32{ var file_base_proto_depIdxs = []int32{
2, // 0: BaseKey.expire:type_name -> google.protobuf.Timestamp 1, // 0: BaseKey.expire:type_name -> google.protobuf.Timestamp
1, // [1:1] is the sub-list for method output_type 1, // [1:1] is the sub-list for method output_type
1, // [1:1] is the sub-list for method input_type 1, // [1:1] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name 1, // [1:1] is the sub-list for extension type_name
@ -184,18 +144,6 @@ func file_base_proto_init() {
return nil return nil
} }
} }
file_base_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*External); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
} }
type x struct{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
@ -203,7 +151,7 @@ func file_base_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_base_proto_rawDesc, RawDescriptor: file_base_proto_rawDesc,
NumEnums: 0, NumEnums: 0,
NumMessages: 2, NumMessages: 1,
NumExtensions: 0, NumExtensions: 0,
NumServices: 0, NumServices: 0,
}, },

View File

@ -1,733 +0,0 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.17.3
// source: channelx.proto
package proto
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type CPushRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Key *BaseKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
Value []string `protobuf:"bytes,2,rep,name=value,proto3" json:"value,omitempty"`
}
func (x *CPushRequest) Reset() {
*x = CPushRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_channelx_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CPushRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CPushRequest) ProtoMessage() {}
func (x *CPushRequest) ProtoReflect() protoreflect.Message {
mi := &file_channelx_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CPushRequest.ProtoReflect.Descriptor instead.
func (*CPushRequest) Descriptor() ([]byte, []int) {
return file_channelx_proto_rawDescGZIP(), []int{0}
}
func (x *CPushRequest) GetKey() *BaseKey {
if x != nil {
return x.Key
}
return nil
}
func (x *CPushRequest) GetValue() []string {
if x != nil {
return x.Value
}
return nil
}
type CPushResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
E *External `protobuf:"bytes,1,opt,name=e,proto3" json:"e,omitempty"`
}
func (x *CPushResponse) Reset() {
*x = CPushResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_channelx_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CPushResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CPushResponse) ProtoMessage() {}
func (x *CPushResponse) ProtoReflect() protoreflect.Message {
mi := &file_channelx_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CPushResponse.ProtoReflect.Descriptor instead.
func (*CPushResponse) Descriptor() ([]byte, []int) {
return file_channelx_proto_rawDescGZIP(), []int{1}
}
func (x *CPushResponse) GetE() *External {
if x != nil {
return x.E
}
return nil
}
type CPopRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Key *BaseKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
Count int32 `protobuf:"varint,2,opt,name=count,proto3" json:"count,omitempty"`
}
func (x *CPopRequest) Reset() {
*x = CPopRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_channelx_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CPopRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CPopRequest) ProtoMessage() {}
func (x *CPopRequest) ProtoReflect() protoreflect.Message {
mi := &file_channelx_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CPopRequest.ProtoReflect.Descriptor instead.
func (*CPopRequest) Descriptor() ([]byte, []int) {
return file_channelx_proto_rawDescGZIP(), []int{2}
}
func (x *CPopRequest) GetKey() *BaseKey {
if x != nil {
return x.Key
}
return nil
}
func (x *CPopRequest) GetCount() int32 {
if x != nil {
return x.Count
}
return 0
}
type CPopResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
E *External `protobuf:"bytes,1,opt,name=e,proto3" json:"e,omitempty"`
Result []string `protobuf:"bytes,2,rep,name=result,proto3" json:"result,omitempty"`
}
func (x *CPopResponse) Reset() {
*x = CPopResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_channelx_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CPopResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CPopResponse) ProtoMessage() {}
func (x *CPopResponse) ProtoReflect() protoreflect.Message {
mi := &file_channelx_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CPopResponse.ProtoReflect.Descriptor instead.
func (*CPopResponse) Descriptor() ([]byte, []int) {
return file_channelx_proto_rawDescGZIP(), []int{3}
}
func (x *CPopResponse) GetE() *External {
if x != nil {
return x.E
}
return nil
}
func (x *CPopResponse) GetResult() []string {
if x != nil {
return x.Result
}
return nil
}
type CMakeRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Key *BaseKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
Length int32 `protobuf:"varint,2,opt,name=length,proto3" json:"length,omitempty"`
}
func (x *CMakeRequest) Reset() {
*x = CMakeRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_channelx_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CMakeRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CMakeRequest) ProtoMessage() {}
func (x *CMakeRequest) ProtoReflect() protoreflect.Message {
mi := &file_channelx_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CMakeRequest.ProtoReflect.Descriptor instead.
func (*CMakeRequest) Descriptor() ([]byte, []int) {
return file_channelx_proto_rawDescGZIP(), []int{4}
}
func (x *CMakeRequest) GetKey() *BaseKey {
if x != nil {
return x.Key
}
return nil
}
func (x *CMakeRequest) GetLength() int32 {
if x != nil {
return x.Length
}
return 0
}
type CMakeResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *CMakeResponse) Reset() {
*x = CMakeResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_channelx_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CMakeResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CMakeResponse) ProtoMessage() {}
func (x *CMakeResponse) ProtoReflect() protoreflect.Message {
mi := &file_channelx_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CMakeResponse.ProtoReflect.Descriptor instead.
func (*CMakeResponse) Descriptor() ([]byte, []int) {
return file_channelx_proto_rawDescGZIP(), []int{5}
}
type CLenRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Key *BaseKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
}
func (x *CLenRequest) Reset() {
*x = CLenRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_channelx_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CLenRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CLenRequest) ProtoMessage() {}
func (x *CLenRequest) ProtoReflect() protoreflect.Message {
mi := &file_channelx_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CLenRequest.ProtoReflect.Descriptor instead.
func (*CLenRequest) Descriptor() ([]byte, []int) {
return file_channelx_proto_rawDescGZIP(), []int{6}
}
func (x *CLenRequest) GetKey() *BaseKey {
if x != nil {
return x.Key
}
return nil
}
type CLenResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Length int32 `protobuf:"varint,2,opt,name=length,proto3" json:"length,omitempty"`
}
func (x *CLenResponse) Reset() {
*x = CLenResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_channelx_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CLenResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CLenResponse) ProtoMessage() {}
func (x *CLenResponse) ProtoReflect() protoreflect.Message {
mi := &file_channelx_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CLenResponse.ProtoReflect.Descriptor instead.
func (*CLenResponse) Descriptor() ([]byte, []int) {
return file_channelx_proto_rawDescGZIP(), []int{7}
}
func (x *CLenResponse) GetLength() int32 {
if x != nil {
return x.Length
}
return 0
}
type CCleanRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Key *BaseKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
}
func (x *CCleanRequest) Reset() {
*x = CCleanRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_channelx_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CCleanRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CCleanRequest) ProtoMessage() {}
func (x *CCleanRequest) ProtoReflect() protoreflect.Message {
mi := &file_channelx_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CCleanRequest.ProtoReflect.Descriptor instead.
func (*CCleanRequest) Descriptor() ([]byte, []int) {
return file_channelx_proto_rawDescGZIP(), []int{8}
}
func (x *CCleanRequest) GetKey() *BaseKey {
if x != nil {
return x.Key
}
return nil
}
type CCleanResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *CCleanResponse) Reset() {
*x = CCleanResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_channelx_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CCleanResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CCleanResponse) ProtoMessage() {}
func (x *CCleanResponse) ProtoReflect() protoreflect.Message {
mi := &file_channelx_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CCleanResponse.ProtoReflect.Descriptor instead.
func (*CCleanResponse) Descriptor() ([]byte, []int) {
return file_channelx_proto_rawDescGZIP(), []int{9}
}
var File_channelx_proto protoreflect.FileDescriptor
var file_channelx_proto_rawDesc = []byte{
0x0a, 0x0e, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x1a, 0x0a, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x40, 0x0a, 0x0c,
0x43, 0x50, 0x75, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x03,
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x42, 0x61, 0x73, 0x65,
0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x28,
0x0a, 0x0d, 0x43, 0x50, 0x75, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x17, 0x0a, 0x01, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x45, 0x78, 0x74,
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x01, 0x65, 0x22, 0x3f, 0x0a, 0x0b, 0x43, 0x50, 0x6f, 0x70,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03,
0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01,
0x28, 0x05, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3f, 0x0a, 0x0c, 0x43, 0x50, 0x6f,
0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x17, 0x0a, 0x01, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x52,
0x01, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x03,
0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x42, 0x0a, 0x0c, 0x43, 0x4d,
0x61, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x03, 0x6b, 0x65,
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x4b, 0x65,
0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68,
0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x22, 0x0f,
0x0a, 0x0d, 0x43, 0x4d, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x29, 0x0a, 0x0b, 0x43, 0x4c, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a,
0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x42, 0x61,
0x73, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x26, 0x0a, 0x0c, 0x43, 0x4c,
0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65,
0x6e, 0x67, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6c, 0x65, 0x6e, 0x67,
0x74, 0x68, 0x22, 0x2b, 0x0a, 0x0d, 0x43, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x08, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22,
0x10, 0x0a, 0x0e, 0x43, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x42, 0x0b, 0x5a, 0x09, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_channelx_proto_rawDescOnce sync.Once
file_channelx_proto_rawDescData = file_channelx_proto_rawDesc
)
func file_channelx_proto_rawDescGZIP() []byte {
file_channelx_proto_rawDescOnce.Do(func() {
file_channelx_proto_rawDescData = protoimpl.X.CompressGZIP(file_channelx_proto_rawDescData)
})
return file_channelx_proto_rawDescData
}
var file_channelx_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
var file_channelx_proto_goTypes = []interface{}{
(*CPushRequest)(nil), // 0: CPushRequest
(*CPushResponse)(nil), // 1: CPushResponse
(*CPopRequest)(nil), // 2: CPopRequest
(*CPopResponse)(nil), // 3: CPopResponse
(*CMakeRequest)(nil), // 4: CMakeRequest
(*CMakeResponse)(nil), // 5: CMakeResponse
(*CLenRequest)(nil), // 6: CLenRequest
(*CLenResponse)(nil), // 7: CLenResponse
(*CCleanRequest)(nil), // 8: CCleanRequest
(*CCleanResponse)(nil), // 9: CCleanResponse
(*BaseKey)(nil), // 10: BaseKey
(*External)(nil), // 11: External
}
var file_channelx_proto_depIdxs = []int32{
10, // 0: CPushRequest.key:type_name -> BaseKey
11, // 1: CPushResponse.e:type_name -> External
10, // 2: CPopRequest.key:type_name -> BaseKey
11, // 3: CPopResponse.e:type_name -> External
10, // 4: CMakeRequest.key:type_name -> BaseKey
10, // 5: CLenRequest.key:type_name -> BaseKey
10, // 6: CCleanRequest.key:type_name -> BaseKey
7, // [7:7] is the sub-list for method output_type
7, // [7:7] is the sub-list for method input_type
7, // [7:7] is the sub-list for extension type_name
7, // [7:7] is the sub-list for extension extendee
0, // [0:7] is the sub-list for field type_name
}
func init() { file_channelx_proto_init() }
func file_channelx_proto_init() {
if File_channelx_proto != nil {
return
}
file_base_proto_init()
if !protoimpl.UnsafeEnabled {
file_channelx_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CPushRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_channelx_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CPushResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_channelx_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CPopRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_channelx_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CPopResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_channelx_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CMakeRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_channelx_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CMakeResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_channelx_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CLenRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_channelx_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CLenResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_channelx_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CCleanRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_channelx_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CCleanResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_channelx_proto_rawDesc,
NumEnums: 0,
NumMessages: 10,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_channelx_proto_goTypes,
DependencyIndexes: file_channelx_proto_depIdxs,
MessageInfos: file_channelx_proto_msgTypes,
}.Build()
File_channelx_proto = out.File
file_channelx_proto_rawDesc = nil
file_channelx_proto_goTypes = nil
file_channelx_proto_depIdxs = nil
}

View File

@ -15,7 +15,7 @@ const (
// NewBaseKey // NewBaseKey
// keyttlexpire // keyttlexpire
func NewBaseKey(key string, t ...int64) *BaseKey { func NewBaseKey(key string, t ...int64) *BaseKey {
var expire *timestamppb.Timestamp = nil var expire *timestamppb.Timestamp
var ttl int64 var ttl int64
if len(t) > 1 { if len(t) > 1 {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -580,6 +580,8 @@ type SetBitResponse struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Result string `protobuf:"bytes,2,opt,name=result,proto3" json:"result,omitempty"`
} }
func (x *SetBitResponse) Reset() { func (x *SetBitResponse) Reset() {
@ -614,6 +616,13 @@ func (*SetBitResponse) Descriptor() ([]byte, []int) {
return file_stringx_proto_rawDescGZIP(), []int{11} return file_stringx_proto_rawDescGZIP(), []int{11}
} }
func (x *SetBitResponse) GetResult() string {
if x != nil {
return x.Result
}
return ""
}
type GetBitRequest struct { type GetBitRequest struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -1062,35 +1071,37 @@ var file_stringx_proto_rawDesc = []byte{
0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x61, 0x6c, 0x18, 0x02, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x61, 0x6c, 0x18, 0x02,
0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x76, 0x61, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x66, 0x66, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x76, 0x61, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x66, 0x66,
0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x22, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x22,
0x10, 0x0a, 0x0e, 0x53, 0x65, 0x74, 0x42, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x28, 0x0a, 0x0e, 0x53, 0x65, 0x74, 0x42, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x41, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x42, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,
0x73, 0x74, 0x12, 0x1a, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x41, 0x0a, 0x0d, 0x47, 0x65, 0x74,
0x08, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x42, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x03, 0x6b, 0x65,
0x0a, 0x05, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6f, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x4b, 0x65,
0x66, 0x66, 0x65, 0x72, 0x22, 0x22, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x42, 0x69, 0x74, 0x52, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x18,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x22, 0x22, 0x0a, 0x0e,
0x01, 0x28, 0x08, 0x52, 0x03, 0x76, 0x61, 0x6c, 0x22, 0x55, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52, 0x47, 0x65, 0x74, 0x42, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10,
0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x03, 0x6b, 0x0a, 0x03, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x76, 0x61, 0x6c,
0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x4b, 0x22, 0x55, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75,
0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x32, 0x08, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
0x03, 0x65, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x22, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05,
0x2a, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01,
0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x28, 0x05, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x22, 0x2a, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x52, 0x61,
0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3d, 0x0a, 0x0d, 0x47, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72,
0x65, 0x74, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x03, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x73,
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x75, 0x6c, 0x74, 0x22, 0x3d, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71,
0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x61, 0x6c, 0x18, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x76, 0x61, 0x6c, 0x22, 0x28, 0x0a, 0x0e, 0x47, 0x65, 0x0b, 0x32, 0x08, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79,
0x74, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x76,
0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x6c, 0x22, 0x28, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70,
0x73, 0x75, 0x6c, 0x74, 0x22, 0x2b, 0x0a, 0x0d, 0x53, 0x74, 0x72, 0x4c, 0x65, 0x6e, 0x52, 0x65, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x2b, 0x0a, 0x0d,
0x28, 0x0b, 0x32, 0x08, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x53, 0x74, 0x72, 0x4c, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a,
0x79, 0x22, 0x28, 0x0a, 0x0e, 0x53, 0x74, 0x72, 0x4c, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x42, 0x61, 0x73,
0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x01, 0x20, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x28, 0x0a, 0x0e, 0x53, 0x74, 0x72,
0x01, 0x28, 0x05, 0x52, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x42, 0x0b, 0x5a, 0x09, 0x70, 0x4c, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6c,
0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6c, 0x65, 0x6e,
0x67, 0x74, 0x68, 0x42, 0x0b, 0x5a, 0x09, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (

View File

@ -1,66 +0,0 @@
package channelx
import (
"sync/atomic"
"gitee.com/wheat-os/wheatCache/pkg/structure"
)
type ChannelX struct {
channel chan *structure.Value
sizeByte int64
}
func MakeChannelX(length int) structure.ChannelXInterface {
return &ChannelX{
channel: make(chan *structure.Value, length),
sizeByte: 0,
}
}
func (c *ChannelX) SizeByte() int64 {
return c.sizeByte
}
// RollBack TODO 事务相关, V2 实现
func (c *ChannelX) RollBack() error {
panic("not implemented") // TODO: Implement
}
// Begin 事务相关, V2 实现
func (c *ChannelX) Begin() error {
panic("not implemented") // TODO: Implement
}
// Comment 事务相关, V2 实现
func (c *ChannelX) Comment() error {
panic("not implemented") // TODO: Implement
}
func (c *ChannelX) Encode() ([]byte, error) {
panic("not implemented") // TODO: Implement
}
func (c *ChannelX) Push(value string) structure.UpdateLength {
val := structure.NewValue(value)
up := val.GetSize()
c.channel <- val
atomic.AddInt64(&c.sizeByte, int64(up))
return structure.UpdateLength(up)
}
func (c *ChannelX) Pop() (string, structure.UpdateLength) {
val := <-c.channel
return val.ToString(), structure.UpdateLength(val.GetSize()) * -1
}
func (c *ChannelX) Length() int {
return len(c.channel)
}
func (c *ChannelX) Clean() structure.UpdateLength {
c.channel = make(chan *structure.Value, cap(c.channel))
up := c.sizeByte
c.sizeByte = 0
return structure.UpdateLength(up) * -1
}

View File

@ -1,24 +0,0 @@
package channelx
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestChannelX_Push(t *testing.T) {
c := MakeChannelX(10)
require.Equal(t, c.Length(), 0)
up := c.Push("111")
require.Equal(t, 24, int(up))
res, up := c.Pop()
require.Equal(t, -24, int(up))
require.Equal(t, res, "111")
up = c.Push("111")
c.Clean()
require.Equal(t, c.Length(), 0)
}

View File

@ -53,25 +53,3 @@ type ListXInterface interface {
Range(start, end int) ([]string, error) Range(start, end int) ([]string, error)
Remove(value string, count int) (int, UpdateLength) Remove(value string, count int) (int, UpdateLength)
} }
type HashXInterface interface {
KeyBaseInterface
Set(key string, val string) UpdateLength
Get(key string) (string, error)
Del(key string) (UpdateLength, error)
Key() []string
Value() []string
Item() map[string]string
Add(renewal int, key ...string) (int, []string, error) // 访问影响成功的结果
SetX(key string, val string) (bool, UpdateLength) // 不存在才插入
Length() int
Range(consur, count int, regex string) []string
}
type ChannelXInterface interface {
KeyBaseInterface
Push(value string) UpdateLength
Pop() (string, UpdateLength)
Length() int
Clean() UpdateLength
}

View File

@ -1,157 +0,0 @@
package hashx
import (
"regexp"
"gitee.com/wheat-os/wheatCache/pkg/errorx"
"gitee.com/wheat-os/wheatCache/pkg/structure"
)
type HashX map[string]*structure.Value
func NewHashXSingle() structure.HashXInterface {
return make(HashX)
}
func (h HashX) SizeByte() int64 {
var size int
for _, val := range h {
size += val.GetSize()
}
return int64(size)
}
// RollBack TODO 事务相关, V2 实现
func (h HashX) RollBack() error {
panic("not implemented") // TODO: Implement
}
// Begin 事务相关, V2 实现
func (h HashX) Begin() error {
panic("not implemented") // TODO: Implement
}
// Comment 事务相关, V2 实现
func (h HashX) Comment() error {
panic("not implemented") // TODO: Implement
}
func (h HashX) Encode() ([]byte, error) {
panic("not implemented") // TODO: Implement
}
func (h HashX) Set(key string, val string) structure.UpdateLength {
var Length structure.UpdateLength
if v, ok := h[key]; ok {
Length -= structure.UpdateLength(v.GetSize())
}
strVal := structure.NewValue(val)
h[key] = strVal
return Length + structure.UpdateLength(strVal.GetSize())
}
func (h HashX) Get(key string) (string, error) {
if v, ok := h[key]; ok {
return v.ToString(), nil
}
return "", errorx.New("this key does not exist in hashx, key:%s", key)
}
func (h HashX) Del(key string) (structure.UpdateLength, error) {
if v, ok := h[key]; ok {
delete(h, key)
return structure.UpdateLength(v.GetSize()), nil
}
return 0, errorx.New("this key does not exist in hashx, key:%s", key)
}
func (h HashX) Key() []string {
result := make([]string, 0, len(h))
for key := range h {
result = append(result, key)
}
return result
}
func (h HashX) Value() []string {
result := make([]string, 0, len(h))
for _, val := range h {
result = append(result, val.ToString())
}
return result
}
func (h HashX) Item() map[string]string {
result := make(map[string]string, len(h))
for key, val := range h {
result[key] = val.ToString()
}
return result
}
func (h HashX) Add(renewal int, keys ...string) (count int, result []string, err error) {
for _, key := range keys {
if v, ok := h[key]; ok {
res, err := v.Incr(int32(renewal))
if err != nil {
continue
}
count += 1
result = append(result, res)
}
}
return count, result, nil
}
func (h HashX) SetX(key string, val string) (bool, structure.UpdateLength) {
if _, ok := h[key]; ok {
return false, 0
}
strVal := structure.NewValue(val)
h[key] = strVal
return true, structure.UpdateLength(strVal.GetSize())
}
func (h HashX) Length() int {
return len(h)
}
func (h HashX) Range(consur, count int, regex string) []string {
var reComp *regexp.Regexp
if regex == "" {
reComp = nil
} else {
reComp = regexp.MustCompile(regex)
}
result := make([]string, 0)
for _, val := range h {
if consur > 0 {
consur--
continue
}
if count == 0 && count != -1 {
break
}
s := val.ToString()
if reComp == nil {
count--
result = append(result, s)
continue
}
if reComp.MatchString(s) {
count--
result = append(result, s)
}
}
return result
}

View File

@ -1,113 +0,0 @@
package hashx
import (
"fmt"
"reflect"
"regexp"
"testing"
"unsafe"
"github.com/stretchr/testify/require"
)
func TestHashX_Set_SetX(t *testing.T) {
h := NewHashXSingle()
h.Set("key", "opq")
res, err := h.Get("key")
require.NoError(t, err)
require.Equal(t, res, "opq")
b, _ := h.SetX("key", "opq")
require.Equal(t, b, false)
b, _ = h.SetX("key1", "opq")
require.Equal(t, b, true)
res, err = h.Get("key1")
require.NoError(t, err)
require.Equal(t, res, "opq")
}
func TestHashX_Del(t *testing.T) {
h := NewHashXSingle()
up := h.Set("key", "opq")
upu, err := h.Del("key")
require.NoError(t, err)
require.Equal(t, up, upu)
}
func TestHashX_Key(t *testing.T) {
h := NewHashXSingle()
h.Set("key", "opq")
h.Set("key1", "opq")
h.Set("key2", "opq")
require.Equal(t, h.Key(), []string{"key", "key1", "key2"})
}
func TestHashX_Value(t *testing.T) {
h := NewHashXSingle()
h.Set("key", "opq")
h.Set("key1", "opq")
h.Set("key2", "opq")
require.Equal(t, h.Value(), []string{"opq", "opq", "opq"})
}
func TestHashX_Add(t *testing.T) {
h := NewHashXSingle()
h.Set("1", "1")
c, res, err := h.Add(1, "1")
require.NoError(t, err)
require.Equal(t, c, 1)
require.Equal(t, res, []string{"2"})
s, err := h.Get("1")
require.NoError(t, err)
require.Equal(t, s, "2")
}
func Test_Pointer(t *testing.T) {
s := make([]int, 9, 20)
lens := *(*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&s)) + uintptr(8)))
fmt.Println(lens, len(s))
mp := make(map[string]int)
mp["qcrao"] = 100
mp["stefno"] = 18
count := **(**uint8)(unsafe.Pointer(uintptr(unsafe.Pointer(&mp)) + uintptr(16)))
fmt.Println(count, len(mp)) // 2
}
func string2bytes(s string) []byte {
stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&s))
result := reflect.SliceHeader{
Data: stringHeader.Data,
Len: stringHeader.Len,
Cap: stringHeader.Len,
}
return *(*[]byte)(unsafe.Pointer(&result))
}
func TestHashX_Range(t *testing.T) {
reComp := regexp.MustCompile("a.+")
require.True(t, reComp.MatchString("abbs"))
h := NewHashXSingle()
h.Set("abbs", "abbs")
h.Set("ppp", "ppp")
h.Set("accs", "accs")
result := h.Range(0, 3, "")
require.Len(t, result, 3)
result = h.Range(0, -1, "")
require.Len(t, result, 3)
result = h.Range(0, -1, "a.+")
require.Len(t, result, 2)
result = h.Range(1, -1, "a.+")
require.Len(t, result, 1)
}

View File

@ -1,8 +1,8 @@
package listx package listx
import ( import (
"gitee.com/wheat-os/wheatCache/pkg/errorx" "gitee.com/timedb/wheatCache/pkg/errorx"
"gitee.com/wheat-os/wheatCache/pkg/structure" "gitee.com/timedb/wheatCache/pkg/structure"
) )
/* /*

View File

@ -1,7 +1,10 @@
package stringx package stringx
import ( import (
"gitee.com/wheat-os/wheatCache/pkg/structure" "strconv"
"gitee.com/timedb/wheatCache/pkg/errorx"
"gitee.com/timedb/wheatCache/pkg/structure"
) )
type StringSingle struct { type StringSingle struct {
@ -48,8 +51,32 @@ func (s *StringSingle) Get() string {
return s.val.ToString() return s.val.ToString()
} }
func updateValueNotString(s *StringSingle, val int32) (string, error) {
switch s.val.GetDynamicType() {
case structure.DynamicNull:
s.val.SetInt(int64(val))
return strconv.Itoa(int(val)), nil
case structure.DynamicFloat:
f, err := s.val.ToFloat64()
if err != nil {
return "", err
}
s.val.SetFloat64(f + float64(val))
return strconv.FormatFloat(f+float64(val), 'f', 2, 64), nil
case structure.DynamicInt:
i, err := s.val.ToInt()
if err != nil {
return "", err
}
s.val.SetInt(int64(val) + i)
return strconv.Itoa(int(i + int64(val))), nil
default:
return "", errorx.New("string cannot perform add operations")
}
}
func (s *StringSingle) Add(renewal int32) (string, error) { func (s *StringSingle) Add(renewal int32) (string, error) {
result, err := s.val.Incr(renewal) result, err := updateValueNotString(s, renewal)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -57,7 +84,7 @@ func (s *StringSingle) Add(renewal int32) (string, error) {
} }
func (s *StringSingle) Reduce(renewal int32) (string, error) { func (s *StringSingle) Reduce(renewal int32) (string, error) {
result, err := s.val.Incr(-1 * renewal) result, err := updateValueNotString(s, -1*renewal)
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@ -5,7 +5,7 @@ import (
"testing" "testing"
"unsafe" "unsafe"
"gitee.com/wheat-os/wheatCache/pkg/structure" "gitee.com/timedb/wheatCache/pkg/structure"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )

View File

@ -3,11 +3,10 @@ package structure
import ( import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"fmt"
"math" "math"
"strconv" "strconv"
"gitee.com/wheat-os/wheatCache/pkg/errorx" "gitee.com/timedb/wheatCache/pkg/errorx"
) )
// Value 提供一个基础的 动态类型 // Value 提供一个基础的 动态类型
@ -148,90 +147,41 @@ func (v *Value) ChangeValueLength(f func()) UpdateLength {
func (v *Value) SetByte(offset int, val bool) { func (v *Value) SetByte(offset int, val bool) {
v.onType = DynamicNull // 位图使用无类型 v.onType = DynamicNull // 位图使用无类型
b := byte(0)
// 扩容
if len(v.val) <= offset/8 {
newByte := make([]byte, (offset/8)+1)
copy(newByte, v.val[:len(v.val)])
v.val = newByte
v.length = len(v.val)
}
if val { if val {
// true 位 b = byte(1)
v.val[offset/8] |= (0b1 << (offset % 8)) }
if v.length >= offset {
v.val[offset] = b
return return
} }
// false 位 newByte := make([]byte, offset+1)
v.val[offset/8] ^= (0b1 << (offset % 8)) newByte[offset] = b
copy(newByte, v.val[:v.length])
v.val = newByte
v.length = len(newByte)
} }
func (v *Value) GetByte(offset int) (bool, error) { func (v *Value) GetByte(offset int) (bool, error) {
if len(v.val) >= offset/8 { if v.length >= offset {
// 采用 & 来运算 是否为 true return v.val[offset] == byte(1), nil
return v.val[offset/8]&(0b1<<(offset%8)) != 0, nil
} }
return false, errorx.New("the maximum length is exceeded") return false, errorx.New("the maximum length is exceeded")
} }
func (v *Value) SliceByString(start, end int) ([]byte, error) { func (v *Value) SliceByString(start, end int) ([]byte, error) {
if v.onType != DynamicString {
return nil, errorx.New("not is string")
}
if start > end { if start > end {
return nil, errorx.New("the end cannot be greater than the beginning") return nil, errorx.New("the end cannot be greater than the beginning")
} }
if v.onType == DynamicInt {
ret, err := v.ToInt()
if err != nil {
return nil, err
}
value := strconv.Itoa(int(ret))
if end > len(value) {
return nil, errorx.New("the maximum index is exceeded, max index: %d", len(value))
}
return []byte(value[start:end]), nil
}
if v.onType == DynamicFloat {
ret, err := v.ToFloat64()
if err != nil {
return nil, err
}
value := fmt.Sprintf("%.2f", ret)
if end > len(value) {
return nil, errorx.New("the maximum index is exceeded, max index: %d", len(value))
}
return []byte(value[start:end]), nil
}
if end > v.length { if end > v.length {
return nil, errorx.New("the maximum index is exceeded, max index: %d", v.length) return nil, errorx.New("the maximum index is exceeded, max index: %d", v.length)
} }
return v.val[start:end], nil return v.val[start:end], nil
} }
// 自增
func (v *Value) Incr(renewal int32) (string, error) {
switch v.GetDynamicType() {
case DynamicNull:
v.SetInt(int64(renewal))
return strconv.Itoa(int(renewal)), nil
case DynamicFloat:
f, err := v.ToFloat64()
if err != nil {
return "", err
}
v.SetFloat64(f + float64(renewal))
return strconv.FormatFloat(f+float64(renewal), 'f', 2, 64), nil
case DynamicInt:
i, err := v.ToInt()
if err != nil {
return "", err
}
v.SetInt(int64(renewal) + i)
return strconv.Itoa(int(i + int64(renewal))), nil
default:
return "", errorx.New("string cannot perform add operations")
}
}

View File

@ -1,7 +1,6 @@
package structure package structure
import ( import (
"fmt"
"strconv" "strconv"
"testing" "testing"
@ -127,20 +126,4 @@ func TestValue_SetByte(t *testing.T) {
v, err = value.GetByte(10001) v, err = value.GetByte(10001)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, v, true) require.Equal(t, v, true)
require.Equal(t, value.GetSize(), (10001/8)+1+16)
}
func TestValue_SetByteWei(t *testing.T) {
k := make([]byte, 100)
offset := 700
k[offset/8] = 0b00000001
k[offset/8] |= 0b1 << (offset % 8)
fmt.Printf("%b\n", k[offset/8])
fmt.Printf("%v", (k[offset/8]&(0b1<<(offset%8))) != 0)
k[offset/8] ^= 0b1 << (offset % 8)
fmt.Printf("%v", (k[offset/8]&(0b1<<(offset%8))) != 0)
} }

View File

@ -5,7 +5,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"gitee.com/wheat-os/wheatCache/pkg/errorx" "gitee.com/timedb/wheatCache/pkg/errorx"
) )
// ParseSizeToBit // ParseSizeToBit

View File

@ -5,7 +5,7 @@ import (
"os/signal" "os/signal"
"syscall" "syscall"
"gitee.com/wheat-os/wheatCache/pkg/logx" "gitee.com/timedb/wheatCache/pkg/logx"
"google.golang.org/grpc" "google.golang.org/grpc"
) )

View File

@ -6,7 +6,7 @@ import (
"testing" "testing"
"time" "time"
"gitee.com/wheat-os/wheatCache/pkg/logx" "gitee.com/timedb/wheatCache/pkg/logx"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )

View File

@ -4,9 +4,9 @@
package config package config
import ( import (
"gitee.com/wheat-os/wheatCache/plugins" "gitee.com/timedb/wheatCache/plugins"
mockPlugin "gitee.com/wheat-os/wheatCache/plugins/mock-plugin" mockPlugin "gitee.com/timedb/wheatCache/plugins/mock-plugin"
) )
func GetMiddlewareMap() map[string]plugins.PluginInterface { func GetMiddlewareMap() map[string]plugins.PluginInterface {

View File

@ -4,9 +4,9 @@
package config package config
import ( import (
"gitee.com/wheat-os/wheatCache/plugins" "gitee.com/timedb/wheatCache/plugins"
{%for dir in dirs %} {%for dir in dirs %}
{{dir[0]}} "gitee.com/wheat-os/wheatCache/plugins/{{dir[1]}}" {{dir[0]}} "gitee.com/timedb/wheatCache/plugins/{{dir[1]}}"
{%- endfor%} {%- endfor%}
) )

View File

@ -5,8 +5,8 @@ import (
"net/http" "net/http"
_ "net/http/pprof" _ "net/http/pprof"
_ "gitee.com/wheat-os/wheatCache/conf" _ "gitee.com/timedb/wheatCache/conf"
"gitee.com/wheat-os/wheatCache/pkg/logx" "gitee.com/timedb/wheatCache/pkg/logx"
"github.com/spf13/viper" "github.com/spf13/viper"
) )

View File

@ -7,8 +7,4 @@ message BaseKey {
string key = 1; string key = 1;
int64 ttl = 2; int64 ttl = 2;
google.protobuf.Timestamp expire = 3; google.protobuf.Timestamp expire = 3;
}
message External {
} }

View File

@ -1,45 +0,0 @@
syntax = "proto3";
import "base.proto";
option go_package = "pkg/proto";
message CPushRequest {
BaseKey key = 1;
repeated string value = 2;
}
message CPushResponse {
External e = 1;
}
message CPopRequest {
BaseKey key = 1;
int32 count = 2;
}
message CPopResponse {
External e = 1;
repeated string result = 2;
}
message CMakeRequest {
BaseKey key = 1;
int32 length = 2;
}
message CMakeResponse {
}
message CLenRequest {
BaseKey key = 1;
}
message CLenResponse {
int32 length = 2;
}
message CCleanRequest {
BaseKey key = 1;
}
message CCleanResponse {
}

View File

@ -1,81 +0,0 @@
syntax = "proto3";
import "base.proto";
option go_package = "pkg/proto";
message HDelRequest {
BaseKey key = 1;
repeated string h_keys = 2;
}
message HDelResponse {
}
message HExistsRequest {
BaseKey key = 1;
string h_key = 2;
}
message HExistsResponse {
bool exists = 1;
}
message HGetRequest {
BaseKey key = 1;
repeated string h_keys = 2;
}
message HGetResponse {
map<string, string> items = 1;
}
message HGetAllRequest {
BaseKey key = 1;
}
message HGetAllResponse {
map<string, string> items = 1;
}
message HIncrByRequest {
BaseKey key = 1;
repeated string h_keys = 2;
int32 renewal = 3;
}
message HIncrByResponse {
int32 count = 1;
repeated string values = 2;
}
message HKeysRequest {
BaseKey key = 1;
}
message HKeysResponse {
repeated string keys = 1;
}
message HLenRequest {
BaseKey key = 1;
}
message HLenResponse {
int32 length = 1;
}
message HSetRequest {
BaseKey key = 1;
map<string, string> items = 2;
}
message HSetResponse {
}
message HSetXRequest {
BaseKey key = 1;
map<string, string> items = 2;
}
message HSetXResponse {
int32 count = 1;
}

View File

@ -1,126 +0,0 @@
syntax = "proto3";
import "base.proto";
option go_package = "pkg/proto";
message SAddRequest {
BaseKey key = 1;
repeated string member = 2;
}
message SAddResponse {
}
message SCardRequest {
BaseKey key = 1;
}
message SCardResponse {
int32 length = 1;
}
message SDiffRequest {
BaseKey key = 1;
repeated string s_keys = 2;
}
message SDiffResponse {
External e = 1;
repeated string result = 2;
}
message SDiffStoreRequest {
BaseKey key = 1;
repeated string s_keys = 2;
string save_key = 3;
}
message SDiffStoreResponse {
External e = 1; // External
}
message SInterRequest {
BaseKey key = 1;
repeated string s_keys = 2;
}
message SInterResponse {
External e = 1;
repeated string result = 2;
}
message SInterStoreRequest {
BaseKey key = 1;
repeated string s_keys = 2;
string save_key = 3;
}
message SInterStoreResponse {
External e = 1;
}
message SIsMemberRequest {
BaseKey key = 1;
string member = 2;
}
message SIsMemberResponse {
bool exist = 1;
}
message SMoveRequest {
BaseKey key = 1;
string move_key = 2;
repeated string members = 3;
}
message SMoveResponse {
External e = 1;
}
message SPopRequest {
BaseKey key = 1;
int32 count = 2;
}
message SPopResponse {
repeated string members = 1;
}
message SRemRequest {
BaseKey key = 1;
int32 count = 2;
}
message SRemResponse {
}
message SUnionRequest {
BaseKey key = 1;
repeated string s_keys = 2;
}
message SUnionResponse {
External e = 1;
repeated string result = 2;
}
message SUnionStoreRequest {
BaseKey key = 1;
repeated string s_keys = 2;
string save_key = 3;
}
message SUnionStoreResponse {
External e = 1;
}
message SScanRequest {
BaseKey key = 1;
int32 cursor = 2;
string regexp = 3;
int32 count = 4;
}
message SScanResponse {
repeated string results = 1;
}

View File

@ -7,9 +7,6 @@ option go_package = "pkg/proto";
import "stringx.proto"; import "stringx.proto";
import "listx.proto"; import "listx.proto";
import "hashx.proto";
import "setx.proto";
import "channelx.proto";
service CommServer { service CommServer {
@ -35,31 +32,4 @@ service CommServer {
rpc LTrim (LTrimRequest) returns (LTrimResponse); rpc LTrim (LTrimRequest) returns (LTrimResponse);
rpc RPush (RPushRequest) returns (RPushResponse); rpc RPush (RPushRequest) returns (RPushResponse);
rpc RPushX (RPushXRequest) returns (RPushXResponse); rpc RPushX (RPushXRequest) returns (RPushXResponse);
rpc HDel (HDelRequest) returns (HDelResponse);
rpc HExists (HExistsRequest) returns (HExistsResponse);
rpc HGet (HGetRequest) returns (HGetResponse);
rpc HGetAll (HGetAllRequest) returns (HGetAllResponse);
rpc HIncrBy (HIncrByRequest) returns (HIncrByResponse);
rpc HKeys (HKeysRequest) returns (HKeysResponse);
rpc HLen (HLenRequest) returns (HLenResponse);
rpc HSet (HSetRequest) returns (HSetResponse);
rpc HSetX (HSetXRequest) returns (HSetXResponse);
rpc SAdd (SAddRequest) returns (SAddResponse);
rpc SCard (SCardRequest) returns (SCardResponse);
rpc SDiff (SDiffRequest) returns (SDiffResponse);
rpc SDiffStore (SDiffStoreRequest) returns (SDiffStoreResponse);
rpc SInter (SInterRequest) returns (SInterResponse);
rpc SInterStore (SInterStoreRequest) returns (SInterStoreResponse);
rpc SIsMember (SIsMemberRequest) returns (SIsMemberResponse);
rpc SMove (SMoveRequest) returns (SMoveResponse);
rpc SPop (SPopRequest) returns (SPopResponse);
rpc SRem (SRemRequest) returns (SRemResponse);
rpc SUnion (SUnionRequest) returns (SUnionResponse);
rpc SUnionStore (SUnionStoreRequest) returns (SUnionStoreResponse);
rpc SScan (SScanRequest) returns (SScanResponse);
rpc CPush (CPushRequest) returns (CPushResponse);
rpc CPop (CPopRequest) returns (CPopResponse);
rpc CMake (CMakeRequest) returns (CMakeResponse);
rpc CLen (CLenRequest) returns (CLenResponse);
rpc CClean (CCleanRequest) returns (CCleanResponse);
} }

View File

@ -53,6 +53,7 @@ message SetBitRequest {
} }
message SetBitResponse { message SetBitResponse {
string result = 2;
} }
message GetBitRequest { message GetBitRequest {

View File

@ -17,7 +17,6 @@ class ProtoOption(object):
self.method = method self.method = method
self.option = [] self.option = []
self.ret = [] self.ret = []
self.external = False
def add_option(self, opt: List[str]): def add_option(self, opt: List[str]):
self.option.extend(opt) self.option.extend(opt)
@ -33,17 +32,13 @@ class ProtoOption(object):
def dist_to_ProOpt(req, resp) -> List[ProtoOption]: def dist_to_ProOpt(req, resp) -> List[ProtoOption]:
def to_camel(val: str) -> str:
return "".join([k.capitalize() for k in val.split('_')])
def parse_type(l: str) -> List[str]: def parse_type(l: str) -> List[str]:
l = l.strip() l = l.strip()
if l == "": if l == "":
return [], False return []
opt = l.split(";") opt = l.split(";")
result = [] result = []
f = False
for l_opt in opt: for l_opt in opt:
l_opt = l_opt.strip() l_opt = l_opt.strip()
l_list = l_opt.split() l_list = l_opt.split()
@ -53,34 +48,21 @@ def dist_to_ProOpt(req, resp) -> List[ProtoOption]:
val = l_list[0] val = l_list[0]
if val == "BaseKey": if val == "BaseKey":
val = "*proto.BaseKey" val = "*proto.BaseKey"
result.append([to_camel(l_list[1]), val]) result.append([l_list[1].capitalize(), val])
elif val == "repeated": elif val == "repeated":
val = f"[]{l_list[1]}" val = f"[]{l_list[1]}"
result.append([to_camel(l_list[2]), val]) result.append([l_list[2].capitalize(), val])
elif "map" in val:
resMap = re.findall(
r"^map\s*<(.*?)\s*,\s*(.*?)\s*>.*?(\w+).*?", l_opt)
if len(resMap[0]) == 3:
mapKey, mapVal, var = resMap[0]
result.append([to_camel(var), f"map[{mapKey}]{mapVal}"])
elif "External" in val:
f = True
else: else:
result.append([to_camel(l_list[1]), val]) result.append([l_list[1].capitalize(), val])
return result, f return result
lists = [] lists = []
for key, value in req.items(): for key, value in req.items():
p = ProtoOption(method=key) p = ProtoOption(method=key)
p.add_option(parse_type(value)[0]) p.add_option(parse_type(value))
p.add_ret(parse_type(resp.get(key, "")))
ret, e = parse_type(resp.get(key, ""))
if e:
p.external = True
p.add_ret(ret)
lists.append(p) lists.append(p)
return lists return lists
@ -122,7 +104,6 @@ def load_protobuf() -> List[ProtoOption]:
li.extend(parse_protobuf_to_Opt(name)) li.extend(parse_protobuf_to_Opt(name))
return li return li
def go_fmt(path: str): def go_fmt(path: str):
os.system(f"go fmt {path}") os.system(f"go fmt {path}")
@ -131,7 +112,6 @@ def load_template(name: str) -> str:
with open(f"{tempPath}/{name}", "r", encoding="utf-8") as fp: with open(f"{tempPath}/{name}", "r", encoding="utf-8") as fp:
return fp.read() return fp.read()
def gen_dao_interface(proto): def gen_dao_interface(proto):
tem_text = load_template("dao.template") tem_text = load_template("dao.template")
@ -154,7 +134,6 @@ def gen_single_service(proto):
with open(temp_path, 'w', encoding='utf-8') as f: with open(temp_path, 'w', encoding='utf-8') as f:
f.write(text) f.write(text)
def gen_aof(proto): def gen_aof(proto):
tem_text = load_template("aof.template") tem_text = load_template("aof.template")
template = Template(tem_text) template = Template(tem_text)
@ -165,23 +144,10 @@ def gen_aof(proto):
with open(temp_path, 'w', encoding='utf-8') as f: with open(temp_path, 'w', encoding='utf-8') as f:
f.write(text) f.write(text)
# 生成 AOF 恢复机制
tem_text = load_template("dao_aof.template")
template = Template(tem_text)
text = template.render(keys=proto)
temp_path = f"{daoPath}/dao.gen.go"
with open(temp_path, 'w', encoding='utf-8') as f:
f.write(text)
def format_code_go(): def format_code_go():
go_fmt(f"{daoPath}/interface.gen.go") go_fmt(f"{daoPath}/interface.gen.go")
go_fmt(f"{servicePath}/single_service.gen.go") go_fmt(f"{servicePath}/single_service.gen.go")
go_fmt(f"{aofPath}/codec.gen.go") go_fmt(f"{aofPath}/codec.gen.go")
go_fmt(f"{daoPath}/dao.gen.go")
def main(): def main():
# 加载 protobuf # 加载 protobuf
@ -197,6 +163,5 @@ def main():
gen_aof(protobuf) gen_aof(protobuf)
format_code_go() format_code_go()
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -17,7 +17,6 @@ def out_proto():
if err: if err:
print(f, "-> out put err") print(f, "-> out put err")
return os._exit(-1)
else: else:
print(f, "-> success") print(f, "-> success")

View File

@ -6,12 +6,12 @@ import (
"log" "log"
"net" "net"
"gitee.com/wheat-os/wheatCache/storage/service" "gitee.com/timedb/wheatCache/storage/service"
_ "gitee.com/wheat-os/wheatCache/conf" _ "gitee.com/timedb/wheatCache/conf"
"gitee.com/wheat-os/wheatCache/pkg/logx" "gitee.com/timedb/wheatCache/pkg/logx"
"gitee.com/wheat-os/wheatCache/pkg/proto" "gitee.com/timedb/wheatCache/pkg/proto"
"gitee.com/wheat-os/wheatCache/pkg/util/server" "gitee.com/timedb/wheatCache/pkg/util/server"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
"google.golang.org/grpc" "google.golang.org/grpc"

View File

@ -1,94 +0,0 @@
package dao
import (
"gitee.com/wheat-os/wheatCache/pkg/errorx"
"gitee.com/wheat-os/wheatCache/pkg/event2"
"gitee.com/wheat-os/wheatCache/pkg/proto"
"gitee.com/wheat-os/wheatCache/pkg/structure"
"gitee.com/wheat-os/wheatCache/pkg/structure/channelx"
)
func (d *Dao) CPush(key *proto.BaseKey, Value []string) (interface{}, error) {
val, ok := d.lru.Get(key)
if !ok {
return nil, errorx.NotKeyErr(key.Key)
}
chanVal, ok := val.(structure.ChannelXInterface)
if !ok {
return nil, errorx.DaoTypeErr("channelx")
}
return event2.EventAwaitFunc(func() (interface{}, error) {
var sumUp structure.UpdateLength
for _, v := range Value {
sumUp += chanVal.Push(v)
}
d.lru.UpdateLruSize(sumUp)
return &proto.CPushResponse{}, nil
}), nil
}
func (d *Dao) CPop(key *proto.BaseKey, count int32) (interface{}, error) {
val, ok := d.lru.Get(key)
if !ok {
return nil, errorx.NotKeyErr(key.Key)
}
chanVal, ok := val.(structure.ChannelXInterface)
if !ok {
return nil, errorx.DaoTypeErr("channelx")
}
return event2.EventAwaitFunc(func() (interface{}, error) {
var sumUp structure.UpdateLength
result := make([]string, 0, count)
for i := int32(0); i < count; i++ {
v, up := chanVal.Pop()
sumUp += up
result = append(result, v)
}
d.lru.UpdateLruSize(sumUp)
return &proto.CPopResponse{Result: result}, nil
}), nil
}
func (d *Dao) CMake(key *proto.BaseKey, length int32) (*proto.CMakeResponse, error) {
chanVal := channelx.MakeChannelX(int(length))
err := d.lru.Add(key, chanVal)
if err != nil {
return nil, err
}
return &proto.CMakeResponse{}, nil
}
func (d *Dao) CLen(key *proto.BaseKey) (*proto.CLenResponse, error) {
val, ok := d.lru.Get(key)
if !ok {
return nil, errorx.NotKeyErr(key.Key)
}
chanVal, ok := val.(structure.ChannelXInterface)
if !ok {
return nil, errorx.DaoTypeErr("channelx")
}
return &proto.CLenResponse{Length: int32(chanVal.Length())}, nil
}
func (d *Dao) CClean(key *proto.BaseKey) (*proto.CCleanResponse, error) {
val, ok := d.lru.Get(key)
if !ok {
return nil, errorx.NotKeyErr(key.Key)
}
chanVal, ok := val.(structure.ChannelXInterface)
if !ok {
return nil, errorx.DaoTypeErr("channelx")
}
up := chanVal.Clean()
d.lru.UpdateLruSize(up)
return &proto.CCleanResponse{}, nil
}

View File

@ -1,70 +0,0 @@
package dao
import (
"strconv"
"testing"
"gitee.com/wheat-os/wheatCache/pkg/event2"
"gitee.com/wheat-os/wheatCache/pkg/lru"
"gitee.com/wheat-os/wheatCache/pkg/proto"
"github.com/stretchr/testify/require"
)
func execWaitFunc(t *testing.T, work interface{}) (interface{}, error) {
wait, ok := work.(event2.EventAwaitFunc)
require.True(t, ok)
return wait()
}
func TestDao_CPush_CPop(t *testing.T) {
testBaseKey := proto.NewBaseKey("123")
l := lru.NewLRUCache()
dao := NewDao(l)
_, err := dao.CMake(testBaseKey, 200)
require.NoError(t, err)
wait, err := dao.CPush(testBaseKey, []string{"1", "2", "3"})
require.NoError(t, err)
waitFunc, ok := wait.(event2.EventAwaitFunc)
require.True(t, ok)
_, err = waitFunc()
require.NoError(t, err)
wait, err = dao.CPop(testBaseKey, 3)
require.NoError(t, err)
res, err := execWaitFunc(t, wait)
require.NoError(t, err)
require.Equal(t, res.(*proto.CPopResponse).Result, []string{"1", "2", "3"})
}
func TestDao_Async_Push(t *testing.T) {
testBaseKey := proto.NewBaseKey("123")
l := lru.NewLRUCache()
dao := NewDao(l)
_, err := dao.CMake(testBaseKey, 200)
require.NoError(t, err)
rq := make([]string, 0)
for i := 0; i < 300; i++ {
rq = append(rq, strconv.Itoa(i))
}
go func() {
wait, err := dao.CPush(testBaseKey, rq)
require.NoError(t, err)
_, err = execWaitFunc(t, wait)
require.NoError(t, err)
}()
wait, err := dao.CPop(testBaseKey, 300)
require.NoError(t, err)
resp, err := execWaitFunc(t, wait)
require.NoError(t, err)
require.Equal(t, resp.(*proto.CPopResponse).Result, rq)
}

View File

@ -1,176 +0,0 @@
// Code generated by gen-struct. DO NOT EDIT.
// make gen-service generated
package dao
import (
"gitee.com/wheat-os/wheatCache/pkg/errorx"
"gitee.com/wheat-os/wheatCache/pkg/lru"
"gitee.com/wheat-os/wheatCache/pkg/proto"
protobuf "google.golang.org/protobuf/proto"
)
type Dao struct {
lru lru.CacheInterface
}
func NewDao(lru lru.CacheInterface) Interface {
return &Dao{
lru: lru,
}
}
// 执行 msg
func (d *Dao) ExecMessage(message protobuf.Message) error {
switch req := message.(type) {
case *proto.LIndexRequest:
_, err := d.LIndex(req.Key, req.Index)
return err
case *proto.LLenRequest:
_, err := d.LLen(req.Key)
return err
case *proto.LPopRequest:
_, err := d.LPop(req.Key, req.Count)
return err
case *proto.LPushRequest:
_, err := d.LPush(req.Key, req.Values)
return err
case *proto.LPushXRequest:
_, err := d.LPushX(req.Key, req.Values)
return err
case *proto.LRangeRequest:
_, err := d.LRange(req.Key, req.Start, req.End)
return err
case *proto.LRemRequest:
_, err := d.LRem(req.Key, req.Count, req.Value)
return err
case *proto.LSetRequest:
_, err := d.LSet(req.Key, req.Index, req.Value)
return err
case *proto.RPopRequest:
_, err := d.RPop(req.Key, req.Count)
return err
case *proto.LTrimRequest:
_, err := d.LTrim(req.Key, req.Start, req.End)
return err
case *proto.RPushRequest:
_, err := d.RPush(req.Key, req.Values)
return err
case *proto.RPushXRequest:
_, err := d.RPushX(req.Key, req.Values)
return err
case *proto.HDelRequest:
_, err := d.HDel(req.Key, req.HKeys)
return err
case *proto.HExistsRequest:
_, err := d.HExists(req.Key, req.HKey)
return err
case *proto.HGetRequest:
_, err := d.HGet(req.Key, req.HKeys)
return err
case *proto.HGetAllRequest:
_, err := d.HGetAll(req.Key)
return err
case *proto.HIncrByRequest:
_, err := d.HIncrBy(req.Key, req.HKeys, req.Renewal)
return err
case *proto.HKeysRequest:
_, err := d.HKeys(req.Key)
return err
case *proto.HLenRequest:
_, err := d.HLen(req.Key)
return err
case *proto.HSetRequest:
_, err := d.HSet(req.Key, req.Items)
return err
case *proto.HSetXRequest:
_, err := d.HSetX(req.Key, req.Items)
return err
case *proto.CPushRequest:
_, err := d.CPush(req.Key, req.Value)
return err
case *proto.CPopRequest:
_, err := d.CPop(req.Key, req.Count)
return err
case *proto.CMakeRequest:
_, err := d.CMake(req.Key, req.Length)
return err
case *proto.CLenRequest:
_, err := d.CLen(req.Key)
return err
case *proto.CCleanRequest:
_, err := d.CClean(req.Key)
return err
case *proto.SetRequest:
_, err := d.Set(req.Key, req.Val)
return err
case *proto.GetRequest:
_, err := d.Get(req.Key)
return err
case *proto.AddRequest:
_, err := d.Add(req.Key, req.Renewal)
return err
case *proto.ReduceRequest:
_, err := d.Reduce(req.Key, req.Renewal)
return err
case *proto.SetnxRequest:
_, err := d.Setnx(req.Key, req.Val)
return err
case *proto.SetBitRequest:
_, err := d.SetBit(req.Key, req.Val, req.Offer)
return err
case *proto.GetBitRequest:
_, err := d.GetBit(req.Key, req.Offer)
return err
case *proto.GetRangeRequest:
_, err := d.GetRange(req.Key, req.Start, req.End)
return err
case *proto.GetSetRequest:
_, err := d.GetSet(req.Key, req.Val)
return err
case *proto.StrLenRequest:
_, err := d.StrLen(req.Key)
return err
case *proto.SAddRequest:
_, err := d.SAdd(req.Key, req.Member)
return err
case *proto.SCardRequest:
_, err := d.SCard(req.Key)
return err
case *proto.SDiffRequest:
_, err := d.SDiff(req.Key, req.SKeys)
return err
case *proto.SDiffStoreRequest:
_, err := d.SDiffStore(req.Key, req.SKeys, req.SaveKey)
return err
case *proto.SInterRequest:
_, err := d.SInter(req.Key, req.SKeys)
return err
case *proto.SInterStoreRequest:
_, err := d.SInterStore(req.Key, req.SKeys, req.SaveKey)
return err
case *proto.SIsMemberRequest:
_, err := d.SIsMember(req.Key, req.Member)
return err
case *proto.SMoveRequest:
_, err := d.SMove(req.Key, req.MoveKey, req.Members)
return err
case *proto.SPopRequest:
_, err := d.SPop(req.Key, req.Count)
return err
case *proto.SRemRequest:
_, err := d.SRem(req.Key, req.Count)
return err
case *proto.SUnionRequest:
_, err := d.SUnion(req.Key, req.SKeys)
return err
case *proto.SUnionStoreRequest:
_, err := d.SUnionStore(req.Key, req.SKeys, req.SaveKey)
return err
case *proto.SScanRequest:
_, err := d.SScan(req.Key, req.Cursor, req.Regexp, req.Count)
return err
default:
return errorx.New("The type that is not registered exec err")
}
}

15
storage/dao/dao.go Normal file
View File

@ -0,0 +1,15 @@
package dao
import (
"gitee.com/timedb/wheatCache/pkg/lru"
)
type Dao struct {
lru lru.CacheInterface
}
func NewDao(lru lru.CacheInterface) Interface {
return &Dao{
lru: lru,
}
}

5
storage/dao/dao_test.go Normal file
View File

@ -0,0 +1,5 @@
package dao
import (
_ "gitee.com/timedb/wheatCache/conf"
)

View File

@ -1,169 +0,0 @@
package dao
import (
"gitee.com/wheat-os/wheatCache/pkg/errorx"
"gitee.com/wheat-os/wheatCache/pkg/proto"
"gitee.com/wheat-os/wheatCache/pkg/structure"
"gitee.com/wheat-os/wheatCache/pkg/structure/hashx"
)
func (d *Dao) HDel(key *proto.BaseKey, hKeys []string) (*proto.HDelResponse, error) {
value, ok := d.lru.Get(key)
if !ok {
return nil, errorx.NotKeyErr(key.Key)
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("hashx")
}
for _, hK := range hKeys {
up, err := hashVal.Del(hK)
if err != nil {
return nil, err
}
d.lru.UpdateLruSize(up)
}
return &proto.HDelResponse{}, nil
}
func (d *Dao) HExists(key *proto.BaseKey, hKeys string) (*proto.HExistsResponse, error) {
value, ok := d.lru.Get(key)
if !ok {
return nil, errorx.NotKeyErr(key.Key)
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("hashx")
}
_, err := hashVal.Get(hKeys)
if err != nil {
return &proto.HExistsResponse{Exists: false}, nil
}
return &proto.HExistsResponse{Exists: true}, nil
}
func (d *Dao) HGet(key *proto.BaseKey, hKeys []string) (*proto.HGetResponse, error) {
value, ok := d.lru.Get(key)
if !ok {
return nil, errorx.NotKeyErr(key.Key)
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("hashx")
}
result := make(map[string]string)
for _, hK := range hKeys {
res, err := hashVal.Get(hK)
if err != nil {
return nil, err
}
result[hK] = res
}
return &proto.HGetResponse{Items: result}, nil
}
func (d *Dao) HGetAll(key *proto.BaseKey) (*proto.HGetAllResponse, error) {
value, ok := d.lru.Get(key)
if !ok {
return nil, errorx.NotKeyErr(key.Key)
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("hashx")
}
return &proto.HGetAllResponse{Items: hashVal.Item()}, nil
}
func (d *Dao) HIncrBy(key *proto.BaseKey, hKeys []string, renewal int32) (*proto.HIncrByResponse, error) {
value, ok := d.lru.Get(key)
if !ok {
return nil, errorx.NotKeyErr(key.Key)
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("hashx")
}
count, result, err := hashVal.Add(int(renewal), hKeys...)
return &proto.HIncrByResponse{
Count: int32(count),
Values: result,
}, err
}
func (d *Dao) HKeys(key *proto.BaseKey) (*proto.HKeysResponse, error) {
value, ok := d.lru.Get(key)
if !ok {
return nil, errorx.NotKeyErr(key.Key)
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("hashx")
}
return &proto.HKeysResponse{Keys: hashVal.Key()}, nil
}
func (d *Dao) HLen(key *proto.BaseKey) (*proto.HLenResponse, error) {
value, ok := d.lru.Get(key)
if !ok {
return nil, errorx.NotKeyErr(key.Key)
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("hashx")
}
return &proto.HLenResponse{Length: int32(hashVal.Length())}, nil
}
func (d *Dao) HSet(key *proto.BaseKey, set map[string]string) (*proto.HSetResponse, error) {
value, ok := d.lru.Get(key)
if !ok {
hashVal := hashx.NewHashXSingle()
for k, v := range set {
hashVal.Set(k, v)
}
err := d.lru.Add(key, hashVal)
return &proto.HSetResponse{}, err
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("hashx")
}
for k, v := range set {
upLength := hashVal.Set(k, v)
d.lru.UpdateLruSize(upLength)
}
return &proto.HSetResponse{}, nil
}
func (d *Dao) HSetX(key *proto.BaseKey, set map[string]string) (*proto.HSetXResponse, error) {
value, ok := d.lru.Get(key)
if !ok {
return &proto.HSetXResponse{}, errorx.NotKeyErr(key.Key)
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("hashx")
}
for k, v := range set {
upLength := hashVal.Set(k, v)
d.lru.UpdateLruSize(upLength)
}
return &proto.HSetXResponse{}, nil
}

View File

@ -1,160 +0,0 @@
package dao
import (
"testing"
"gitee.com/wheat-os/wheatCache/pkg/lru"
"gitee.com/wheat-os/wheatCache/pkg/proto"
"github.com/stretchr/testify/require"
)
func initData(t *testing.T, key *proto.BaseKey, dao Interface) {
_, err := dao.HSet(key, map[string]string{
"test": "test",
"test1": "1",
"test2": "1.1",
})
require.NoError(t, err)
}
func TestDao_HSet(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
baseKey := proto.NewBaseKey("apple")
initData(t, baseKey, dao)
res, err := dao.HGet(baseKey, []string{"test", "test1"})
require.NoError(t, err)
require.Equal(t, res.Items, map[string]string{
"test": "test",
"test1": "1",
})
res, err = dao.HGet(baseKey, []string{"test", "test1", "test2"})
require.NoError(t, err)
require.Equal(t, res.Items, map[string]string{
"test": "test",
"test1": "1",
"test2": "1.10", // 默认2个小数点
})
}
func TestDao_HGet(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
baseKey := proto.NewBaseKey("apple")
initData(t, baseKey, dao)
res, err := dao.HGet(baseKey, []string{"test", "test1", "test2"})
require.NoError(t, err)
require.Equal(t, res.Items, map[string]string{
"test": "test",
"test1": "1",
"test2": "1.10", // 默认2个小数点
})
_, err = dao.HGet(baseKey, []string{"test", "test1", "test2", "a"})
require.Error(t, err)
}
func TestDao_HExists(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
baseKey := proto.NewBaseKey("apple")
initData(t, baseKey, dao)
resp, err := dao.HExists(baseKey, "test")
require.NoError(t, err)
require.Equal(t, resp.Exists, true)
resp, err = dao.HExists(baseKey, "kjd")
require.NoError(t, err)
require.Equal(t, resp.Exists, false)
}
func TestDao_HDel(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
baseKey := proto.NewBaseKey("apple")
initData(t, baseKey, dao)
_, err := dao.HDel(baseKey, []string{"test", "test1"})
require.NoError(t, err)
_, err = dao.HDel(baseKey, []string{"test"})
require.Error(t, err)
res, err := dao.HExists(baseKey, "test")
require.NoError(t, err)
require.Equal(t, res.Exists, false)
res, err = dao.HExists(baseKey, "test2")
require.NoError(t, err)
require.Equal(t, res.Exists, true)
}
func TestDao_HGetAll(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
baseKey := proto.NewBaseKey("apple")
initData(t, baseKey, dao)
resp, err := dao.HGetAll(baseKey)
require.NoError(t, err)
require.Equal(t, resp.Items, map[string]string{
"test": "test",
"test1": "1",
"test2": "1.10",
})
}
func TestDao_HSetX(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
baseKey := proto.NewBaseKey("apple")
initData(t, baseKey, dao)
res, err := dao.HSetX(baseKey, map[string]string{
"test": "test",
"test1": "1",
"test2": "1.10", // 默认2个小数点
})
require.NoError(t, err)
require.Equal(t, res.Count, 0)
}
func TestDao_HLen(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
baseKey := proto.NewBaseKey("apple")
initData(t, baseKey, dao)
resp, err := dao.HLen(baseKey)
require.NoError(t, err)
require.Equal(t, resp.Length, int32(3))
}
func TestDao_HKeys(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
baseKey := proto.NewBaseKey("apple")
initData(t, baseKey, dao)
res, err := dao.HKeys(baseKey)
require.NoError(t, err)
require.Equal(t, res.Keys, []string{"test", "test1", "test2"})
}
func TestDao_HIncrBy(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
baseKey := proto.NewBaseKey("apple")
initData(t, baseKey, dao)
resp, err := dao.HIncrBy(baseKey, []string{"test", "test1"}, 10)
require.NoError(t, err)
require.Equal(t, resp.Count, int32(1))
require.Equal(t, resp.Values, []string{"11"})
}

View File

@ -3,10 +3,7 @@
package dao package dao
import ( import "gitee.com/timedb/wheatCache/pkg/proto"
"gitee.com/wheat-os/wheatCache/pkg/proto"
protobuf "google.golang.org/protobuf/proto"
)
type Interface interface { type Interface interface {
LIndex(*proto.BaseKey, int32) (*proto.LIndexResponse, error) LIndex(*proto.BaseKey, int32) (*proto.LIndexResponse, error)
@ -21,20 +18,6 @@ type Interface interface {
LTrim(*proto.BaseKey, int32, int32) (*proto.LTrimResponse, error) LTrim(*proto.BaseKey, int32, int32) (*proto.LTrimResponse, error)
RPush(*proto.BaseKey, []string) (*proto.RPushResponse, error) RPush(*proto.BaseKey, []string) (*proto.RPushResponse, error)
RPushX(*proto.BaseKey, []string) (*proto.RPushXResponse, error) RPushX(*proto.BaseKey, []string) (*proto.RPushXResponse, error)
HDel(*proto.BaseKey, []string) (*proto.HDelResponse, error)
HExists(*proto.BaseKey, string) (*proto.HExistsResponse, error)
HGet(*proto.BaseKey, []string) (*proto.HGetResponse, error)
HGetAll(*proto.BaseKey) (*proto.HGetAllResponse, error)
HIncrBy(*proto.BaseKey, []string, int32) (*proto.HIncrByResponse, error)
HKeys(*proto.BaseKey) (*proto.HKeysResponse, error)
HLen(*proto.BaseKey) (*proto.HLenResponse, error)
HSet(*proto.BaseKey, map[string]string) (*proto.HSetResponse, error)
HSetX(*proto.BaseKey, map[string]string) (*proto.HSetXResponse, error)
CPush(*proto.BaseKey, []string) (interface{}, error)
CPop(*proto.BaseKey, int32) (interface{}, error)
CMake(*proto.BaseKey, int32) (*proto.CMakeResponse, error)
CLen(*proto.BaseKey) (*proto.CLenResponse, error)
CClean(*proto.BaseKey) (*proto.CCleanResponse, error)
Set(*proto.BaseKey, string) (*proto.SetResponse, error) Set(*proto.BaseKey, string) (*proto.SetResponse, error)
Get(*proto.BaseKey) (*proto.GetResponse, error) Get(*proto.BaseKey) (*proto.GetResponse, error)
Add(*proto.BaseKey, int32) (*proto.AddResponse, error) Add(*proto.BaseKey, int32) (*proto.AddResponse, error)
@ -45,18 +28,4 @@ type Interface interface {
GetRange(*proto.BaseKey, int32, int32) (*proto.GetRangeResponse, error) GetRange(*proto.BaseKey, int32, int32) (*proto.GetRangeResponse, error)
GetSet(*proto.BaseKey, string) (*proto.GetSetResponse, error) GetSet(*proto.BaseKey, string) (*proto.GetSetResponse, error)
StrLen(*proto.BaseKey) (*proto.StrLenResponse, error) StrLen(*proto.BaseKey) (*proto.StrLenResponse, error)
SAdd(*proto.BaseKey, []string) (*proto.SAddResponse, error)
SCard(*proto.BaseKey) (*proto.SCardResponse, error)
SDiff(*proto.BaseKey, []string) (interface{}, error)
SDiffStore(*proto.BaseKey, []string, string) (interface{}, error)
SInter(*proto.BaseKey, []string) (interface{}, error)
SInterStore(*proto.BaseKey, []string, string) (interface{}, error)
SIsMember(*proto.BaseKey, string) (*proto.SIsMemberResponse, error)
SMove(*proto.BaseKey, string, []string) (interface{}, error)
SPop(*proto.BaseKey, int32) (*proto.SPopResponse, error)
SRem(*proto.BaseKey, int32) (*proto.SRemResponse, error)
SUnion(*proto.BaseKey, []string) (interface{}, error)
SUnionStore(*proto.BaseKey, []string, string) (interface{}, error)
SScan(*proto.BaseKey, int32, string, int32) (*proto.SScanResponse, error)
ExecMessage(message protobuf.Message) error
} }

View File

@ -1,10 +1,10 @@
package dao package dao
import ( import (
"gitee.com/wheat-os/wheatCache/pkg/errorx" "gitee.com/timedb/wheatCache/pkg/errorx"
"gitee.com/wheat-os/wheatCache/pkg/proto" "gitee.com/timedb/wheatCache/pkg/proto"
"gitee.com/wheat-os/wheatCache/pkg/structure" "gitee.com/timedb/wheatCache/pkg/structure"
"gitee.com/wheat-os/wheatCache/pkg/structure/listx" "gitee.com/timedb/wheatCache/pkg/structure/listx"
) )
func (d *Dao) LIndex(key *proto.BaseKey, index int32) (*proto.LIndexResponse, error) { func (d *Dao) LIndex(key *proto.BaseKey, index int32) (*proto.LIndexResponse, error) {

View File

@ -1,471 +0,0 @@
package dao
import (
"context"
"gitee.com/wheat-os/wheatCache/pkg/errorx"
"gitee.com/wheat-os/wheatCache/pkg/event2"
"gitee.com/wheat-os/wheatCache/pkg/proto"
"gitee.com/wheat-os/wheatCache/pkg/structure"
"gitee.com/wheat-os/wheatCache/pkg/structure/hashx"
"gitee.com/wheat-os/wheatCache/storage/external"
)
func (d *Dao) SAdd(key *proto.BaseKey, setVal []string) (*proto.SAddResponse, error) {
value, ok := d.lru.Get(key)
if !ok {
hashVal := hashx.NewHashXSingle()
for _, sv := range setVal {
hashVal.SetX(sv, sv)
}
d.lru.Add(key, hashVal)
return &proto.SAddResponse{}, nil
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("setx")
}
for _, sv := range setVal {
b, up := hashVal.SetX(sv, sv)
if b {
d.lru.UpdateLruSize(up)
}
}
return &proto.SAddResponse{}, nil
}
func (d *Dao) SCard(key *proto.BaseKey) (*proto.SCardResponse, error) {
value, ok := d.lru.Get(key)
if !ok {
return nil, errorx.KeyBaseIsNilErr()
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("setx")
}
return &proto.SCardResponse{Length: int32(hashVal.Length())}, nil
}
func mathSDiff(masterItem []string, extKey []string) ([]string, error) {
cli, err := external.NewGatewayClient()
if err != nil {
return nil, err
}
m := make(map[string]struct{})
for _, bVal := range masterItem {
m[bVal] = struct{}{}
}
setItem := make([]string, 0, len(masterItem))
ctx := context.Background()
for _, sKey := range extKey {
baseKey := proto.NewBaseKey(sKey)
resp, err := cli.SScan(ctx, &proto.SScanRequest{
Key: baseKey,
Count: -1,
})
if err != nil {
continue
}
for _, item := range resp.Results {
if _, ok := m[item]; !ok {
setItem = append(setItem, item)
m[item] = struct{}{}
}
}
}
return setItem, nil
}
func (d *Dao) SDiff(key *proto.BaseKey, setKey []string) (interface{}, error) {
value, ok := d.lru.Get(key)
if !ok {
return nil, errorx.KeyBaseIsNilErr()
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("setx")
}
baseItem := hashVal.Key()
// await 挂起
return event2.EventAwaitFunc(func() (interface{}, error) {
setItem, err := mathSDiff(baseItem, setKey)
if err != nil {
return nil, err
}
return &proto.SDiffResponse{Result: setItem}, nil
}), nil
}
func (d *Dao) SDiffStore(key *proto.BaseKey, setKey []string, saveKey string) (interface{}, error) {
value, ok := d.lru.Get(key)
if !ok {
return nil, errorx.KeyBaseIsNilErr()
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("setx")
}
baseItem := hashVal.Key()
// await 挂起
return event2.EventAwaitFunc(func() (interface{}, error) {
setItem, err := mathSDiff(baseItem, setKey)
if err != nil {
return nil, err
}
cli, err := external.NewGatewayClient()
if err != nil {
return nil, err
}
ctx := context.Background()
_, err = cli.SAdd(ctx, &proto.SAddRequest{
Key: proto.NewBaseKey(saveKey),
Member: setItem,
})
if err != nil {
return nil, err
}
return &proto.SDiffStoreResponse{}, nil
}), nil
}
func mathSInter(masterItem []string, extKey []string) ([]string, error) {
cli, err := external.NewGatewayClient()
if err != nil {
return nil, err
}
m := make(map[string]struct{})
for _, bVal := range masterItem {
m[bVal] = struct{}{}
}
setItem := make([]string, 0, len(masterItem))
ctx := context.Background()
for _, sKey := range extKey {
resp, err := cli.SScan(ctx, &proto.SScanRequest{
Key: proto.NewBaseKey(sKey),
Count: -1,
})
if err != nil {
continue
}
for _, item := range resp.Results {
if _, ok := m[item]; ok {
setItem = append(setItem, item)
delete(m, item)
}
}
}
return setItem, nil
}
func (d *Dao) SInter(key *proto.BaseKey, setKey []string) (interface{}, error) {
value, ok := d.lru.Get(key)
if !ok {
return nil, errorx.KeyBaseIsNilErr()
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("setx")
}
baseItem := hashVal.Key()
// await 挂起
return event2.EventAwaitFunc(func() (interface{}, error) {
setItem, err := mathSInter(baseItem, setKey)
if err != nil {
return nil, err
}
return &proto.SInterResponse{Result: setItem}, nil
}), nil
}
func (d *Dao) SInterStore(key *proto.BaseKey, setKey []string, saveKey string) (interface{}, error) {
value, ok := d.lru.Get(key)
if !ok {
return nil, errorx.KeyBaseIsNilErr()
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("setx")
}
baseItem := hashVal.Key()
// await 挂起
return event2.EventAwaitFunc(func() (interface{}, error) {
setItem, err := mathSInter(baseItem, setKey)
if err != nil {
return nil, err
}
cli, err := external.NewGatewayClient()
if err != nil {
return nil, err
}
ctx := context.Background()
_, err = cli.SAdd(ctx, &proto.SAddRequest{
Key: proto.NewBaseKey(saveKey),
Member: setItem,
})
if err != nil {
return nil, err
}
return &proto.SInterStoreResponse{}, nil
}), nil
}
func (d *Dao) SIsMember(key *proto.BaseKey, member string) (*proto.SIsMemberResponse, error) {
value, ok := d.lru.Get(key)
if !ok {
return nil, errorx.KeyBaseIsNilErr()
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("setx")
}
_, err := hashVal.Get(member)
if err != nil {
return &proto.SIsMemberResponse{Exist: false}, nil
}
return &proto.SIsMemberResponse{Exist: true}, nil
}
func (d *Dao) SMove(key *proto.BaseKey, moveKey string, members []string) (interface{}, error) {
value, ok := d.lru.Get(key)
if !ok {
return nil, errorx.KeyBaseIsNilErr()
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("setx")
}
moveMembers := make([]string, 0, len(members))
for _, member := range members {
up, err := hashVal.Del(member)
if err == nil {
d.lru.UpdateLruSize(up)
moveMembers = append(moveMembers, member)
}
}
return event2.EventAwaitFunc(func() (interface{}, error) {
cli, err := external.NewGatewayClient()
if err != nil {
return nil, err
}
ctx := context.Background()
_, err = cli.SAdd(ctx, &proto.SAddRequest{
Key: proto.NewBaseKey(moveKey),
Member: moveMembers,
})
if err != nil {
return nil, err
}
return &proto.SMoveResponse{}, nil
}), nil
}
func (d *Dao) SPop(key *proto.BaseKey, count int32) (*proto.SPopResponse, error) {
value, ok := d.lru.Get(key)
if !ok {
return nil, errorx.KeyBaseIsNilErr()
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("setx")
}
members := make([]string, 0, count)
result := hashVal.Range(0, int(count), "")
for _, res := range result {
up, err := hashVal.Del(res)
if err != nil {
return nil, err
}
d.lru.UpdateLruSize(up)
members = append(members, res)
}
return &proto.SPopResponse{Members: members}, nil
}
func (d *Dao) SRem(key *proto.BaseKey, count int32) (*proto.SRemResponse, error) {
value, ok := d.lru.Get(key)
if !ok {
return nil, errorx.KeyBaseIsNilErr()
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("setx")
}
result := hashVal.Range(0, int(count), "")
for _, res := range result {
up, err := hashVal.Del(res)
if err != nil {
return nil, err
}
d.lru.UpdateLruSize(up)
}
return &proto.SRemResponse{}, nil
}
func mathSUnion(masterItem []string, extKey []string) ([]string, error) {
cli, err := external.NewGatewayClient()
if err != nil {
return nil, err
}
m := make(map[string]struct{})
for _, bVal := range masterItem {
m[bVal] = struct{}{}
}
ctx := context.Background()
for _, sKey := range extKey {
resp, err := cli.SScan(ctx, &proto.SScanRequest{
Key: proto.NewBaseKey(sKey),
Count: -1,
})
if err != nil {
continue
}
for _, item := range resp.Results {
if _, ok := m[item]; !ok {
masterItem = append(masterItem, item)
m[item] = struct{}{}
}
}
}
return masterItem, nil
}
func (d *Dao) SUnion(key *proto.BaseKey, setKey []string) (interface{}, error) {
value, ok := d.lru.Get(key)
if !ok {
return nil, errorx.KeyBaseIsNilErr()
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("setx")
}
baseItem := hashVal.Key()
// await 挂起
return event2.EventAwaitFunc(func() (interface{}, error) {
setItem, err := mathSUnion(baseItem, setKey)
if err != nil {
return nil, err
}
return &proto.SUnionResponse{Result: setItem}, nil
}), nil
}
func (d *Dao) SUnionStore(key *proto.BaseKey, setKey []string, saveKey string) (interface{}, error) {
value, ok := d.lru.Get(key)
if !ok {
return nil, errorx.KeyBaseIsNilErr()
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("setx")
}
baseItem := hashVal.Key()
// await 挂起
return event2.EventAwaitFunc(func() (interface{}, error) {
setItem, err := mathSUnion(baseItem, setKey)
if err != nil {
return nil, err
}
cli, err := external.NewGatewayClient()
if err != nil {
return nil, err
}
ctx := context.Background()
_, err = cli.SAdd(ctx, &proto.SAddRequest{
Key: proto.NewBaseKey(saveKey),
Member: setItem,
})
if err != nil {
return nil, err
}
return &proto.SUnionStoreResponse{}, nil
}), nil
}
func (d *Dao) SScan(key *proto.BaseKey, cursor int32, regex string, count int32) (*proto.SScanResponse, error) {
value, ok := d.lru.Get(key)
if !ok {
return nil, errorx.KeyBaseIsNilErr()
}
hashVal, ok := value.(structure.HashXInterface)
if !ok {
return nil, errorx.DaoTypeErr("setx")
}
result := hashVal.Range(int(cursor), int(count), regex)
return &proto.SScanResponse{Results: result}, nil
}

View File

@ -1,386 +0,0 @@
package dao
import (
"context"
"testing"
mockproto "gitee.com/wheat-os/wheatCache/mock/storage"
"gitee.com/wheat-os/wheatCache/pkg/event2"
"gitee.com/wheat-os/wheatCache/pkg/lru"
"gitee.com/wheat-os/wheatCache/pkg/proto"
"gitee.com/wheat-os/wheatCache/storage/external"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
)
func TestDao_SAdd(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
baseKey := proto.NewBaseKey("apple")
_, err := dao.SAdd(baseKey, []string{"1", "2", "3"})
require.NoError(t, err)
res, err := dao.SPop(baseKey, 3)
require.NoError(t, err)
t.Log(res.Members)
require.Len(t, res.Members, 3)
}
func IsAdd(t *testing.T, baseKey *proto.BaseKey, dao Interface) {
_, err := dao.SAdd(baseKey, []string{"1", "2", "3", "4", "4"})
require.NoError(t, err)
}
func TestDao_SCard(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
baseKey := proto.NewBaseKey("apple")
IsAdd(t, baseKey, dao)
res, err := dao.SCard(baseKey)
require.NoError(t, err)
require.Equal(t, res.Length, int32(4))
}
func mockSScan(t *testing.T, ctrl *gomock.Controller) {
external.GateWayCtrl = ctrl
client, err := external.NewGatewayClient()
require.NoError(t, err)
mockCli, ok := client.(*mockproto.MockCommServerClient)
require.True(t, ok)
gomock.InOrder(
mockCli.EXPECT().SScan(gomock.Any(), gomock.Any()).Return(
&proto.SScanResponse{
Results: []string{"a", "b", "c"},
}, nil).MaxTimes(1),
mockCli.EXPECT().SScan(gomock.Any(), gomock.Any()).Return(
&proto.SScanResponse{
Results: []string{"1", "2", "3"},
}, nil).AnyTimes(),
mockCli.EXPECT().SScan(gomock.Any(), gomock.Any()).Return(
&proto.SScanResponse{
Results: []string{"1", "2", "4"},
}, nil).AnyTimes(),
mockCli.EXPECT().SScan(gomock.Any(), gomock.Any()).Return(
&proto.SScanResponse{
Results: []string{"99", "6", "1.20"},
}, nil).AnyTimes(),
)
}
func mockSAdd(t *testing.T, ctrl *gomock.Controller, dao Interface) {
external.GateWayCtrl = ctrl
client, err := external.NewGatewayClient()
require.NoError(t, err)
mockCli, ok := client.(*mockproto.MockCommServerClient)
require.True(t, ok)
execFunc := func(
ctx context.Context,
req *proto.SAddRequest,
) (*proto.SAddResponse, error) {
return dao.SAdd(req.Key, req.Member)
}
mockCli.EXPECT().SAdd(gomock.Any(), gomock.Any()).DoAndReturn(execFunc)
}
func TestDao_SDiff(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
baseKey := proto.NewBaseKey("diff")
_, err := dao.SAdd(baseKey, []string{"a", "b", "s"})
require.NoError(t, err)
// mock client
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockSScan(t, ctrl)
wait, err := dao.SDiff(baseKey, []string{"opp"})
require.NoError(t, err)
waitWork, ok := wait.(event2.EventAwaitFunc)
require.True(t, ok)
resp, err := waitWork()
require.NoError(t, err)
res, ok := resp.(*proto.SDiffResponse)
require.True(t, ok)
require.Equal(t, res.Result, []string{"c"})
}
func TestDao_SDiffStore(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
baseKey := proto.NewBaseKey("diffStore")
storeKey := proto.NewBaseKey("apple")
_, err := dao.SAdd(baseKey, []string{"a", "b", "s"})
require.NoError(t, err)
// mock client
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockSScan(t, ctrl)
// 必须调用一次 storage
mockSAdd(t, ctrl, dao)
wait, err := dao.SDiffStore(baseKey, []string{"opp", "oo2"}, storeKey.Key)
require.NoError(t, err)
waitWork, ok := wait.(event2.EventAwaitFunc)
require.True(t, ok)
resp, err := waitWork()
require.NoError(t, err)
_, ok = resp.(*proto.SDiffStoreResponse)
require.True(t, ok)
res, err := dao.SScan(storeKey, 0, "", -1)
require.NoError(t, err)
t.Log(res.Results)
require.Len(t, res.Results, 4)
}
func TestDao_SInter(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
baseKey := proto.NewBaseKey("inter")
_, err := dao.SAdd(baseKey, []string{"a", "b", "s"})
require.NoError(t, err)
// mock client
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockSScan(t, ctrl)
wait, err := dao.SInter(baseKey, []string{"opp"})
require.NoError(t, err)
waitWork, ok := wait.(event2.EventAwaitFunc)
require.True(t, ok)
resp, err := waitWork()
require.NoError(t, err)
res, ok := resp.(*proto.SInterResponse)
require.True(t, ok)
require.Equal(t, res.Result, []string{"a", "b"})
}
func TestDao_SInterStore(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
baseKey := proto.NewBaseKey("interStore")
storeKey := proto.NewBaseKey("apple")
_, err := dao.SAdd(baseKey, []string{"a", "b", "s"})
require.NoError(t, err)
// mock client
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockSScan(t, ctrl)
// 必须调用一次 storage
mockSAdd(t, ctrl, dao)
wait, err := dao.SInterStore(baseKey, []string{"opp", "oo2"}, storeKey.Key)
require.NoError(t, err)
waitWork, ok := wait.(event2.EventAwaitFunc)
require.True(t, ok)
resp, err := waitWork()
require.NoError(t, err)
_, ok = resp.(*proto.SInterStoreResponse)
require.True(t, ok)
res, err := dao.SScan(storeKey, 0, "", -1)
require.NoError(t, err)
t.Log(res.Results)
require.Len(t, res.Results, 2)
}
func TestDao_SIsMember(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
testKey := proto.NewBaseKey("testKey")
IsAdd(t, testKey, dao)
resp, err := dao.SIsMember(testKey, "1")
require.NoError(t, err)
require.Equal(t, resp.Exist, true)
resp, err = dao.SIsMember(testKey, "6")
require.NoError(t, err)
require.Equal(t, resp.Exist, false)
}
func TestDao_SMove(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
testKey := proto.NewBaseKey("testKey")
moveKey := proto.NewBaseKey("moveKey")
// mock client
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockSAdd(t, ctrl, dao)
_, err := dao.SAdd(testKey, []string{"1", "2", "3", "4"})
require.NoError(t, err)
waitWork, err := dao.SMove(testKey, moveKey.Key, []string{"3", "4", "5"})
require.NoError(t, err)
_, err = waitWork.(event2.EventAwaitFunc)()
require.NoError(t, err)
res, err := dao.SScan(testKey, 0, "", -1)
require.NoError(t, err)
require.Equal(t, res.Results, []string{"1", "2"})
// 移动 key
res, err = dao.SScan(moveKey, 0, "", -1)
require.NoError(t, err)
require.Equal(t, res.Results, []string{"3", "4"})
}
func TestDao_SPop(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
testKey := proto.NewBaseKey("testKey")
_, err := dao.SAdd(testKey, []string{"1", "2", "3", "4"})
require.NoError(t, err)
resp, err := dao.SPop(testKey, 2)
require.NoError(t, err)
require.Len(t, resp.Members, 2)
res, err := dao.SScan(testKey, 0, "", -1)
require.NoError(t, err)
require.Len(t, res.Results, 2)
}
func TestDao_SRem(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
testKey := proto.NewBaseKey("testKey")
_, err := dao.SAdd(testKey, []string{"1", "2", "3", "4"})
require.NoError(t, err)
_, err = dao.SRem(testKey, 2)
require.NoError(t, err)
res, err := dao.SScan(testKey, 0, "", -1)
require.NoError(t, err)
require.Len(t, res.Results, 2)
}
func TestDao_SUnion(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
baseKey := proto.NewBaseKey("union")
_, err := dao.SAdd(baseKey, []string{"a", "b", "s"})
require.NoError(t, err)
// mock client
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockSScan(t, ctrl)
wait, err := dao.SUnion(baseKey, []string{"opp"})
require.NoError(t, err)
waitWork, ok := wait.(event2.EventAwaitFunc)
require.True(t, ok)
resp, err := waitWork()
require.NoError(t, err)
res, ok := resp.(*proto.SUnionResponse)
require.True(t, ok)
require.Equal(t, res.Result, []string{"a", "b", "s", "c"})
}
func TestDao_SUnionStore(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
baseKey := proto.NewBaseKey("unionStore")
storeKey := proto.NewBaseKey("apple")
_, err := dao.SAdd(baseKey, []string{"a", "b", "s"})
require.NoError(t, err)
// mock client
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockSScan(t, ctrl)
// 必须调用一次 storage
mockSAdd(t, ctrl, dao)
wait, err := dao.SUnionStore(baseKey, []string{"opp", "oo2"}, storeKey.Key)
require.NoError(t, err)
waitWork, ok := wait.(event2.EventAwaitFunc)
require.True(t, ok)
resp, err := waitWork()
require.NoError(t, err)
_, ok = resp.(*proto.SUnionStoreResponse)
require.True(t, ok)
res, err := dao.SScan(storeKey, 0, "", -1)
require.NoError(t, err)
t.Log(res.Results)
require.Len(t, res.Results, 7)
}
func TestDao_SScan(t *testing.T) {
lru := lru.NewLRUCache()
dao := NewDao(lru)
baseKey := proto.NewBaseKey("apple")
_, err := dao.SAdd(baseKey, []string{"1", "2", "3", "a", "b", "c"})
require.NoError(t, err)
scanResp, err := dao.SScan(baseKey, 0, "", -1)
require.NoError(t, err)
require.Len(t, scanResp.Results, 6)
scanResp, err = dao.SScan(baseKey, 0, `\d`, -1)
require.NoError(t, err)
require.Len(t, scanResp.Results, 3)
scanResp, err = dao.SScan(baseKey, 0, `\d`, 4)
require.NoError(t, err)
require.Len(t, scanResp.Results, 3)
scanResp, err = dao.SScan(baseKey, 0, `\d`, 2)
require.NoError(t, err)
require.Len(t, scanResp.Results, 2)
scanResp, err = dao.SScan(baseKey, 0, `[a-z]+`, -1)
require.NoError(t, err)
require.Len(t, scanResp.Results, 3)
}

View File

@ -1,10 +1,10 @@
package dao package dao
import ( import (
"gitee.com/wheat-os/wheatCache/pkg/errorx" "gitee.com/timedb/wheatCache/pkg/errorx"
"gitee.com/wheat-os/wheatCache/pkg/proto" "gitee.com/timedb/wheatCache/pkg/proto"
"gitee.com/wheat-os/wheatCache/pkg/structure" "gitee.com/timedb/wheatCache/pkg/structure"
"gitee.com/wheat-os/wheatCache/pkg/structure/stringx" "gitee.com/timedb/wheatCache/pkg/structure/stringx"
) )
// stringx 相关的方法 // stringx 相关的方法
@ -147,28 +147,19 @@ func (d *Dao) GetRange(key *proto.BaseKey, start, end int32) (*proto.GetRangeRes
func (d *Dao) GetSet(key *proto.BaseKey, value string) (*proto.GetSetResponse, error) { func (d *Dao) GetSet(key *proto.BaseKey, value string) (*proto.GetSetResponse, error) {
val, ok := d.lru.Get(key) val, ok := d.lru.Get(key)
var oldValue string
if !ok { if !ok {
oldValue = "" return nil, errorx.NotKeyErr(key.Key)
strValue := stringx.NewStringSingle()
strValue.Set(value)
err := d.lru.Add(key, strValue)
if err != nil {
return nil, err
}
} else {
strVal, ok := val.(structure.StringXInterface)
if !ok {
return nil, errorx.DaoTypeErr("stringx")
}
oldValue = strVal.Get()
_, updateLength := strVal.Set(value)
d.lru.UpdateLruSize(updateLength)
} }
strVal, ok := val.(structure.StringXInterface)
if !ok {
return nil, errorx.DaoTypeErr("stringx")
}
oldValue := strVal.Get()
_, updateLength := strVal.Set(value)
d.lru.UpdateLruSize(updateLength)
return &proto.GetSetResponse{Result: oldValue}, nil return &proto.GetSetResponse{Result: oldValue}, nil
} }

View File

@ -1,175 +0,0 @@
package dao
import (
// "reflect"
"testing"
"gitee.com/wheat-os/wheatCache/pkg/lru"
"gitee.com/wheat-os/wheatCache/pkg/proto"
"github.com/stretchr/testify/require"
)
func TestDao_Set_Get(t *testing.T) {
baseKey := proto.NewBaseKey("abbs")
lru := lru.NewLRUCache()
dao := NewDao(lru)
_, err := dao.Set(baseKey, "bbq")
require.NoError(t, err)
resp, err := dao.Get(baseKey)
require.NoError(t, err)
require.Equal(t, resp.Result, "bbq")
}
func TestDao_Add(t *testing.T) {
baseKey := proto.NewBaseKey("test")
lru := lru.NewLRUCache()
dao := NewDao(lru)
// 整数 add
dao.Set(baseKey, "1")
dao.Add(baseKey, 2)
resp, err := dao.Get(baseKey)
require.NoError(t, err)
require.Equal(t, resp.Result, "3")
// 浮点数
dao.Set(baseKey, "1.1")
dao.Add(baseKey, 2)
resp, err = dao.Get(baseKey)
require.NoError(t, err)
require.Equal(t, resp.Result, "3.10")
// 字符串
dao.Set(baseKey, "1awd.1")
_, err = dao.Add(baseKey, 2)
require.Error(t, err)
}
func TestDao_Reduce(t *testing.T) {
baseKey := proto.NewBaseKey("test")
lru := lru.NewLRUCache()
dao := NewDao(lru)
// 整数 add
dao.Set(baseKey, "1")
dao.Reduce(baseKey, 2)
resp, err := dao.Get(baseKey)
require.NoError(t, err)
require.Equal(t, resp.Result, "-1")
// 浮点数
dao.Set(baseKey, "1.1")
dao.Reduce(baseKey, 2)
resp, err = dao.Get(baseKey)
require.NoError(t, err)
require.Equal(t, resp.Result, "-0.90")
// 字符串
dao.Set(baseKey, "1awd.1")
_, err = dao.Reduce(baseKey, 2)
require.Error(t, err)
}
func TestDao_SetBit_GitBit(t *testing.T) {
baseKey := proto.NewBaseKey("s")
lru := lru.NewLRUCache()
dao := NewDao(lru)
_, err := dao.GetBit(baseKey, 8)
require.Error(t, err)
_, err = dao.SetBit(baseKey, true, 8)
require.NoError(t, err)
resp, err := dao.GetBit(baseKey, 8)
require.NoError(t, err)
require.Equal(t, resp.Val, true)
resp, err = dao.GetBit(baseKey, 7)
require.NoError(t, err)
require.Equal(t, resp.Val, false)
resp, err = dao.GetBit(baseKey, 9)
require.NoError(t, err)
require.Equal(t, resp.Val, false)
}
func TestDao_GetRange(t *testing.T) {
baseKey := proto.NewBaseKey("s")
lru := lru.NewLRUCache()
dao := NewDao(lru)
_, err := dao.GetRange(baseKey, 0, 5)
require.Error(t, err)
_, err = dao.Set(baseKey, "abcdef")
require.NoError(t, err)
resp, err := dao.GetRange(baseKey, 0, 3)
require.NoError(t, err)
require.Equal(t, resp.Result, "abc")
_, err = dao.GetRange(baseKey, 0, 7)
require.Error(t, err)
_, err = dao.Set(baseKey, "123456")
require.NoError(t, err)
resp, err = dao.GetRange(baseKey, 0, 3)
require.NoError(t, err)
require.Equal(t, resp.Result, "123")
}
func TestDao_GetSet(t *testing.T) {
baseKey := proto.NewBaseKey("s")
lru := lru.NewLRUCache()
dao := NewDao(lru)
_, err := dao.Set(baseKey, "a")
require.NoError(t, err)
resp, err := dao.GetSet(baseKey, "ab")
require.NoError(t, err)
require.Equal(t, resp.Result, "a")
resp, err = dao.GetSet(baseKey, "s")
require.NoError(t, err)
require.Equal(t, resp.Result, "a")
l := proto.NewBaseKey("l")
resp, err = dao.GetSet(l, "s")
require.NoError(t, err)
require.Equal(t, resp.Result, "")
}
func TestDao_StrLen(t *testing.T) {
baseKey := proto.NewBaseKey("s")
lru := lru.NewLRUCache()
dao := NewDao(lru)
_, err := dao.StrLen(baseKey)
require.Error(t, err)
_, err = dao.Set(baseKey, "abc")
require.NoError(t, err)
resp, err := dao.StrLen(baseKey)
require.NoError(t, err)
require.Equal(t, resp.Length, int32(3))
}
func TestDao_Setnx(t *testing.T) {
baseKey := proto.NewBaseKey("s")
lru := lru.NewLRUCache()
dao := NewDao(lru)
_, err := dao.Setnx(baseKey, "abc")
require.NoError(t, err)
resp, err := dao.Get(baseKey)
require.NoError(t, err)
require.Equal(t, resp.Result, "abc")
_, err = dao.Setnx(baseKey, "abc")
require.Error(t, err)
}

View File

@ -1,19 +0,0 @@
package external
import (
"sync"
"gitee.com/wheat-os/wheatCache/pkg/proto"
"github.com/golang/mock/gomock"
)
var (
oneGatewayClient sync.Once
gatewayClient proto.CommServerClient
)
var (
GateWayCtrl *gomock.Controller
mockGatewayClient proto.CommServerClient
oneMockGatewayClient sync.Once
)

View File

@ -1,41 +0,0 @@
package external
import (
"errors"
"gitee.com/wheat-os/wheatCache/client"
"gitee.com/wheat-os/wheatCache/client/middle"
_ "gitee.com/wheat-os/wheatCache/conf"
mockClient "gitee.com/wheat-os/wheatCache/mock/storage"
"gitee.com/wheat-os/wheatCache/pkg/errorx"
"gitee.com/wheat-os/wheatCache/pkg/proto"
"github.com/spf13/viper"
)
func NewGatewayClient() (proto.CommServerClient, error) {
if viper.GetString("env") == "dev" {
if GateWayCtrl == nil {
return nil, errorx.New("mock ctrl not init")
}
oneMockGatewayClient.Do(func() {
mockGatewayClient = mockClient.NewMockCommServerClient(GateWayCtrl)
})
return mockGatewayClient, nil
}
oneGatewayClient.Do(func() {
cli, err := client.NewWheatClient("127.0.0.1:5891", middle.WithUnaryColonyClient)
if err == nil {
gatewayClient = cli
}
})
if gatewayClient != nil {
return gatewayClient, nil
}
return nil, errors.New("get gateway err")
}

View File

@ -1,36 +0,0 @@
package external
import (
"context"
"testing"
_ "gitee.com/wheat-os/wheatCache/conf"
mockClient "gitee.com/wheat-os/wheatCache/mock/storage"
"gitee.com/wheat-os/wheatCache/pkg/proto"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
)
func TestNewGatewayClient(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
GateWayCtrl = ctrl
cli, err := NewGatewayClient()
require.NoError(t, err)
mockClient := cli.(*mockClient.MockCommServerClient)
ctx := context.Background()
mockClient.EXPECT().Get(ctx, gomock.Any()).Return(&proto.GetResponse{
Result: "mockData",
}, nil)
resp, err := mockClient.Get(ctx, nil)
require.NoError(t, err)
require.Equal(t, resp.Result, "mockData")
resp, err = mockClient.Get(ctx, nil)
require.NoError(t, err)
require.Equal(t, resp.Result, "mockData")
}

View File

@ -1,7 +1,22 @@
/*
Copyright © 2021 NAME HERE <EMAIL ADDRESS>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main package main
import ( import (
"gitee.com/wheat-os/wheatCache/storage/cmd" "gitee.com/timedb/wheatCache/storage/cmd"
) )
func main() { func main() {

Some files were not shown because too many files have changed in this diff Show More