Files
EdgeNode/internal/caches/writer_memory.go

193 lines
4.1 KiB
Go
Raw Normal View History

2020-10-05 19:15:35 +08:00
package caches
import (
"errors"
2024-07-27 15:42:50 +08:00
"sync"
"sync/atomic"
"github.com/TeaOSLab/EdgeNode/internal/utils/fasttime"
2024-04-18 18:25:33 +08:00
"github.com/cespare/xxhash/v2"
"github.com/iwind/TeaGo/types"
2020-10-05 19:15:35 +08:00
)
type MemoryWriter struct {
storage *MemoryStorage
key string
expiredAt int64
headerSize int64
bodySize int64
status int
isDirty bool
2023-10-01 15:06:58 +08:00
expectedBodySize int64
maxSize int64
hash uint64
item *MemoryItem
2023-10-01 14:11:48 +08:00
endFunc func(valueItem *MemoryItem)
once sync.Once
2020-10-05 19:15:35 +08:00
}
2023-10-01 15:06:58 +08:00
func NewMemoryWriter(memoryStorage *MemoryStorage, key string, expiredAt int64, status int, isDirty bool, expectedBodySize int64, maxSize int64, endFunc func(valueItem *MemoryItem)) *MemoryWriter {
var valueItem = &MemoryItem{
ExpiresAt: expiredAt,
ModifiedAt: fasttime.Now().Unix(),
2023-10-01 15:06:58 +08:00
Status: status,
}
2023-10-09 12:48:30 +08:00
2024-04-04 09:30:41 +08:00
if expectedBodySize > 0 {
valueItem.BodyValue = make([]byte, 0, expectedBodySize)
2023-10-01 15:06:58 +08:00
}
2024-04-04 09:30:41 +08:00
2023-10-01 14:11:48 +08:00
var w = &MemoryWriter{
2023-10-01 15:06:58 +08:00
storage: memoryStorage,
key: key,
expiredAt: expiredAt,
item: valueItem,
status: status,
isDirty: isDirty,
expectedBodySize: expectedBodySize,
maxSize: maxSize,
endFunc: endFunc,
2020-10-05 19:15:35 +08:00
}
2023-10-01 14:11:48 +08:00
w.hash = w.calculateHash(key)
return w
2020-10-05 19:15:35 +08:00
}
// WriteHeader 写入数据
2021-01-13 12:02:50 +08:00
func (this *MemoryWriter) WriteHeader(data []byte) (n int, err error) {
this.headerSize += int64(len(data))
this.item.HeaderValue = append(this.item.HeaderValue, data...)
2021-01-13 12:02:50 +08:00
return len(data), nil
}
// Write 写入数据
2020-10-05 19:15:35 +08:00
func (this *MemoryWriter) Write(data []byte) (n int, err error) {
2023-10-01 15:06:58 +08:00
var l = len(data)
if l == 0 {
return
}
if this.item.IsPrepared {
if this.item.WriteOffset+int64(l) > this.expectedBodySize {
err = ErrWritingUnavailable
return
}
copy(this.item.BodyValue[this.item.WriteOffset:], data)
this.item.WriteOffset += int64(l)
} else {
this.item.BodyValue = append(this.item.BodyValue, data...)
}
this.bodySize += int64(l)
// 检查尺寸
if this.maxSize > 0 && this.bodySize > this.maxSize {
err = ErrEntityTooLarge
this.storage.IgnoreKey(this.key, this.maxSize)
2023-10-01 15:06:58 +08:00
return l, err
}
2023-10-01 15:06:58 +08:00
return l, nil
2020-10-05 19:15:35 +08:00
}
// WriteAt 在指定位置写入数据
func (this *MemoryWriter) WriteAt(offset int64, b []byte) error {
_ = b
_ = offset
return errors.New("not supported")
}
// HeaderSize 数据尺寸
2021-01-13 12:02:50 +08:00
func (this *MemoryWriter) HeaderSize() int64 {
return this.headerSize
}
// BodySize 主体内容尺寸
2021-01-13 12:02:50 +08:00
func (this *MemoryWriter) BodySize() int64 {
return this.bodySize
2020-10-05 19:15:35 +08:00
}
// Close 关闭
2020-10-05 19:15:35 +08:00
func (this *MemoryWriter) Close() error {
// 需要在Locker之外
defer this.once.Do(func() {
2023-10-01 14:11:48 +08:00
this.endFunc(this.item)
})
if this.item == nil {
return nil
}
// check content length
if this.expectedBodySize > 0 && this.bodySize != this.expectedBodySize {
this.storage.locker.Lock()
delete(this.storage.valuesMap, this.hash)
this.storage.locker.Unlock()
return ErrUnexpectedContentLength
}
this.storage.locker.Lock()
this.item.IsDone = true
var err error
if this.isDirty {
if this.storage.parentStorage != nil {
2023-10-03 11:39:28 +08:00
this.storage.valuesMap[this.hash] = this.item
select {
case this.storage.dirtyChan <- types.String(this.bodySize) + "@" + this.key:
atomic.AddInt64(&this.storage.totalDirtySize, this.bodySize)
default:
2023-10-03 11:39:28 +08:00
// remove from values map
delete(this.storage.valuesMap, this.hash)
err = ErrWritingQueueFull
}
} else {
this.storage.valuesMap[this.hash] = this.item
}
} else {
this.storage.valuesMap[this.hash] = this.item
}
this.storage.locker.Unlock()
return err
2020-10-05 19:15:35 +08:00
}
// Discard 丢弃
2020-10-05 19:15:35 +08:00
func (this *MemoryWriter) Discard() error {
// 需要在Locker之外
defer this.once.Do(func() {
2023-10-02 08:18:43 +08:00
this.endFunc(this.item)
})
2021-06-13 17:37:57 +08:00
this.storage.locker.Lock()
delete(this.storage.valuesMap, this.hash)
this.storage.locker.Unlock()
2020-10-05 19:15:35 +08:00
return nil
}
// Key 获取Key
2020-10-05 19:15:35 +08:00
func (this *MemoryWriter) Key() string {
return this.key
}
// ExpiredAt 过期时间
2020-10-05 19:15:35 +08:00
func (this *MemoryWriter) ExpiredAt() int64 {
return this.expiredAt
}
// ItemType 内容类型
func (this *MemoryWriter) ItemType() ItemType {
return ItemTypeMemory
}
2020-10-05 19:15:35 +08:00
// 计算Key Hash
func (this *MemoryWriter) calculateHash(key string) uint64 {
2020-11-21 22:29:57 +08:00
return xxhash.Sum64String(key)
2020-10-05 19:15:35 +08:00
}