优化Partial Content配置编码速度

This commit is contained in:
GoEdgeLab
2022-11-19 23:11:05 +08:00
parent b1adc80c48
commit ee926e4dda
2 changed files with 83 additions and 33 deletions

View File

@@ -3,8 +3,9 @@
package caches package caches
import ( import (
"bytes"
"encoding/json" "encoding/json"
"errors" "github.com/iwind/TeaGo/types"
"os" "os"
) )
@@ -22,8 +23,37 @@ func NewPartialRanges(expiresAt int64) *PartialRanges {
} }
} }
// NewPartialRangesFromData 从数据中解析范围
func NewPartialRangesFromData(data []byte) (*PartialRanges, error) {
var rs = NewPartialRanges(0)
for {
var index = bytes.IndexRune(data, '\n')
if index < 0 {
break
}
var line = data[:index]
var colonIndex = bytes.IndexRune(line, ':')
if colonIndex > 0 {
switch string(line[:colonIndex]) {
case "e":
rs.ExpiresAt = types.Int64(line[colonIndex+1:])
case "r":
var commaIndex = bytes.IndexRune(line, ',')
if commaIndex > 0 {
rs.Ranges = append(rs.Ranges, [2]int64{types.Int64(line[colonIndex+1 : commaIndex]), types.Int64(line[commaIndex+1:])})
}
}
}
data = data[index+1:]
if len(data) == 0 {
break
}
}
return rs, nil
}
// NewPartialRangesFromJSON 从JSON中解析范围 // NewPartialRangesFromJSON 从JSON中解析范围
func NewPartialRangesFromJSON(data []byte) (*PartialRanges, error) { func newPartialRangesFromJSON(data []byte) (*PartialRanges, error) {
var rs = NewPartialRanges(0) var rs = NewPartialRanges(0)
err := json.Unmarshal(data, &rs) err := json.Unmarshal(data, &rs)
if err != nil { if err != nil {
@@ -38,7 +68,17 @@ func NewPartialRangesFromFile(path string) (*PartialRanges, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return NewPartialRangesFromJSON(data) if len(data) == 0 {
return NewPartialRanges(0), nil
}
// 兼容老的JSON格式
if data[0] == '{' {
return newPartialRangesFromJSON(data)
}
// 新的格式
return NewPartialRangesFromData(data)
} }
// Add 添加新范围 // Add 添加新范围
@@ -109,27 +149,22 @@ func (this *PartialRanges) Nearest(begin int64, end int64) (r [2]int64, ok bool)
return return
} }
// AsJSON 转换为JSON // 转换为字符串
func (this *PartialRanges) AsJSON() ([]byte, error) { func (this *PartialRanges) String() string {
return json.Marshal(this) var s = "e:" + types.String(this.ExpiresAt) + "\n"
for _, r := range this.Ranges {
s += "r:" + types.String(r[0]) + "," + types.String(r[1]) + "\n"
}
return s
}
func (this *PartialRanges) Bytes() []byte {
return []byte(this.String())
} }
// WriteToFile 写入到文件中 // WriteToFile 写入到文件中
func (this *PartialRanges) WriteToFile(path string) error { func (this *PartialRanges) WriteToFile(path string) error {
data, err := this.AsJSON() return os.WriteFile(path, this.Bytes(), 0666)
if err != nil {
return errors.New("convert to json failed: " + err.Error())
}
return os.WriteFile(path, data, 0666)
}
// ReadFromFile 从文件中读取
func (this *PartialRanges) ReadFromFile(path string) (*PartialRanges, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, err
}
return NewPartialRangesFromJSON(data)
} }
func (this *PartialRanges) Max() int64 { func (this *PartialRanges) Max() int64 {

View File

@@ -3,10 +3,12 @@
package caches_test package caches_test
import ( import (
"encoding/json"
"github.com/TeaOSLab/EdgeNode/internal/caches" "github.com/TeaOSLab/EdgeNode/internal/caches"
"github.com/iwind/TeaGo/assert" "github.com/iwind/TeaGo/assert"
"github.com/iwind/TeaGo/logs" "github.com/iwind/TeaGo/logs"
"testing" "testing"
"time"
) )
func TestNewPartialRanges(t *testing.T) { func TestNewPartialRanges(t *testing.T) {
@@ -133,36 +135,49 @@ func TestNewPartialRanges_Large_Range(t *testing.T) {
var r = caches.NewPartialRanges(0) var r = caches.NewPartialRanges(0)
r.Add(1, largeSize) r.Add(1, largeSize)
jsonData, err := r.AsJSON() var s = r.String()
if err != nil { t.Log(s)
t.Fatal(err)
}
t.Log(string(jsonData))
r2, err := caches.NewPartialRangesFromJSON(jsonData) r2, err := caches.NewPartialRangesFromData([]byte(s))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
a.IsTrue(largeSize == r2.Ranges[0][1]) a.IsTrue(largeSize == r2.Ranges[0][1])
logs.PrintAsJSON(r, t)
} }
func TestNewPartialRanges_AsJSON(t *testing.T) { func TestPartialRanges_Encode_JSON(t *testing.T) {
var r = caches.NewPartialRanges(0) var r = caches.NewPartialRanges(0)
for j := 0; j < 1000; j++ { r.ExpiresAt = time.Now().Unix()
r.Add(int64(j), int64(j+100)) for i := 0; i < 10; i++ {
r.Ranges = append(r.Ranges, [2]int64{int64(i * 100), int64(i*100 + 100)})
} }
data, err := r.AsJSON() var before = time.Now()
data, err := json.Marshal(r)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
t.Log(string(data)) t.Log(time.Since(before).Seconds()*1000, "ms")
t.Log(len(data))
}
r2, err := caches.NewPartialRangesFromJSON(data) func TestPartialRanges_Encode_String(t *testing.T) {
var r = caches.NewPartialRanges(0)
r.ExpiresAt = time.Now().Unix()
for i := 0; i < 10; i++ {
r.Ranges = append(r.Ranges, [2]int64{int64(i * 100), int64(i*100 + 100)})
}
var before = time.Now()
var data = r.String()
t.Log(time.Since(before).Seconds()*1000, "ms")
t.Log(len(data))
r2, err := caches.NewPartialRangesFromData([]byte(data))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
t.Log(r2.Ranges) logs.PrintAsJSON(r2, t)
} }
func BenchmarkNewPartialRanges(b *testing.B) { func BenchmarkNewPartialRanges(b *testing.B) {