新增 cache

This commit is contained in:
dragon
2024-12-27 17:32:02 +08:00
parent 161b49a47b
commit bf46501a10
4 changed files with 161 additions and 3 deletions

View File

@@ -6,6 +6,14 @@ import (
type ServerOptions struct {
Domain string
Cache services.Config
}
func DefaultOptions(domain string) *ServerOptions {
return &ServerOptions{
Domain: domain,
Cache: services.NewConfigMemory(),
}
}
type Server struct {

View File

@@ -1,7 +1,97 @@
package services
import (
"errors"
"io"
"sync"
"time"
)
type Cache interface {
Put(key string, value []byte) error
Get(key string) ([]byte, error)
Delete(key string) error
Put(key string, reader io.Reader) error
Get(key string) (io.ReadSeekCloser, error)
Delete(pattern string) error
io.Closer
}
var ErrCacheOutOfMemory = errors.New("内容无法被缓存,超过最大限定值")
type CacheMemory struct {
l sync.RWMutex
data map[string][]byte
maxAge time.Duration
sizeGl int
sizeOne int
current int
cache []byte
ordered []string
}
func NewCacheMemory(maxUsage, maxGlobalUsage int) *CacheMemory {
return &CacheMemory{
data: make(map[string][]byte),
l: sync.RWMutex{},
sizeGl: maxGlobalUsage,
sizeOne: maxUsage,
cache: make([]byte, maxUsage+1),
ordered: make([]string, 0),
}
}
func (c *CacheMemory) Put(key string, reader io.Reader) error {
c.l.Lock()
defer c.l.Unlock()
size, err := io.ReadAtLeast(reader, c.cache, 0)
if err != nil {
return err
}
if size == len(c.cache) {
return ErrCacheOutOfMemory
}
needed := c.sizeGl - c.current + size
if needed < 0 {
// 清理旧的内容
count := 0
for i, k := range c.ordered {
needed += len(c.data[k])
if needed > 0 {
break
}
count = i + 1
}
if needed < 0 {
// 清理全部内容也无法留出空间
return ErrCacheOutOfMemory
}
for _, s := range c.ordered[:count] {
delete(c.data, s)
c.current -= len(c.data)
}
c.ordered = c.ordered[count:]
}
dest := make([]byte, size)
copy(dest, c.cache[:size])
c.data[key] = dest
c.ordered = append(c.ordered, key)
c.current += len(dest)
return nil
}
func (c *CacheMemory) Get(key string) (io.ReadSeekCloser, error) {
//TODO implement me
panic("implement me")
}
func (c *CacheMemory) Delete(key string) error {
//TODO implement me
panic("implement me")
}
func (c *CacheMemory) Close() error {
//TODO implement me
panic("implement me")
}

58
pkg/services/config.go Normal file
View File

@@ -0,0 +1,58 @@
package services
import (
"io"
"os"
"sync"
)
type Config interface {
Put(key string, value string) error
Get(key string) (string, error)
Delete(key string) error
io.Closer
}
func NewConfigMemory() Config {
return &ConfigMemory{
data: make(map[string]string),
lock: sync.RWMutex{},
}
}
// ConfigMemory 一个简单的内存配置归档,仅用于测试
type ConfigMemory struct {
data map[string]string
lock sync.RWMutex
}
func (m *ConfigMemory) Put(key string, value string) error {
m.lock.Lock()
defer m.lock.Unlock()
m.data[key] = value
return nil
}
func (m *ConfigMemory) Get(key string) (string, error) {
m.lock.RLock()
defer m.lock.RUnlock()
v, ok := m.data[key]
if !ok {
return "", os.ErrNotExist
}
return v, nil
}
func (m *ConfigMemory) Delete(key string) error {
m.lock.Lock()
defer m.lock.Unlock()
delete(m.data, key)
return nil
}
func (m *ConfigMemory) Close() error {
m.lock.Lock()
defer m.lock.Unlock()
clear(m.data)
return nil
}