mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-06 01:50:26 +08:00
优化Partial Content配置编码速度
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user