新增 cache
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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
58
pkg/services/config.go
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user