253 lines
4.5 KiB
Go
253 lines
4.5 KiB
Go
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
|
//go:build plus
|
|
|
|
package mmap_test
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/md5"
|
|
"fmt"
|
|
"github.com/TeaOSLab/EdgeNode/internal/utils/bytepool"
|
|
"github.com/TeaOSLab/EdgeNode/internal/utils/mmap"
|
|
"github.com/TeaOSLab/EdgeNode/internal/utils/testutils"
|
|
_ "github.com/iwind/TeaGo/bootstrap"
|
|
"io"
|
|
"os"
|
|
"sync"
|
|
"testing"
|
|
)
|
|
|
|
func TestOpenSharedMMAP(t *testing.T) {
|
|
for i := 0; i < 3; i++ {
|
|
func() {
|
|
fp, err := mmap.OpenSharedMMAP("./shared_mmap.go")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
defer func() {
|
|
_ = fp.Close()
|
|
}()
|
|
|
|
var buf = make([]byte, fp.Size())
|
|
n, err := fp.ReadAt(buf, 0)
|
|
if err != nil && err != io.EOF {
|
|
t.Fatal(err)
|
|
}
|
|
t.Log(len(buf[:n]), fp.Stat())
|
|
}()
|
|
}
|
|
}
|
|
|
|
func TestOpenSharedMMAP_Memory(t *testing.T) {
|
|
var isSingleTesting = testutils.IsSingleTesting()
|
|
|
|
var count = 10
|
|
if isSingleTesting {
|
|
count = 10_000
|
|
}
|
|
|
|
var stat1 = testutils.ReadMemoryStat()
|
|
|
|
var fps []*mmap.SharedMMAP
|
|
|
|
var buf = make([]byte, 1024)
|
|
for i := 0; i < count; i++ {
|
|
//if i > 0 && i%100 == 0 {
|
|
// t.Log(i)
|
|
//}
|
|
fp, openErr := mmap.OpenSharedMMAP("./shared_mmap.go")
|
|
if openErr != nil {
|
|
t.Fatal(openErr)
|
|
}
|
|
fps = append(fps, fp)
|
|
|
|
var off int64
|
|
for {
|
|
n, err := fp.ReadAt(buf, off)
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
t.Fatal(err)
|
|
}
|
|
off += int64(n)
|
|
}
|
|
}
|
|
|
|
var stat2 = testutils.ReadMemoryStat()
|
|
t.Log((stat2.HeapInuse-stat1.HeapInuse)>>20, "MB")
|
|
|
|
for _, fp := range fps {
|
|
_ = fp.Close()
|
|
}
|
|
}
|
|
|
|
func TestOpenSharedMMAP_Concurrent(t *testing.T) {
|
|
const filename = "./shared_mmap.go"
|
|
|
|
data, err := os.ReadFile(filename)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
var rawMdString string
|
|
{
|
|
var md = md5.New()
|
|
md.Write(data)
|
|
rawMdString = fmt.Sprintf("%x", md.Sum(nil))
|
|
}
|
|
t.Log(rawMdString)
|
|
|
|
fp, err := mmap.OpenSharedMMAP(filename)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
const concurrent = 2048
|
|
var wg = &sync.WaitGroup{}
|
|
wg.Add(concurrent)
|
|
|
|
for i := 0; i < concurrent; i++ {
|
|
go func() {
|
|
defer wg.Done()
|
|
|
|
var buf = bytes.NewBuffer(nil)
|
|
n, readErr := fp.Write(buf, 0)
|
|
if readErr != nil && readErr != io.EOF {
|
|
t.Log(readErr)
|
|
return
|
|
}
|
|
var md = md5.New()
|
|
md.Write(buf.Bytes()[:n])
|
|
var mdString = fmt.Sprintf("%x", md.Sum(nil))
|
|
if mdString != rawMdString {
|
|
t.Log("md not equal")
|
|
return
|
|
}
|
|
}()
|
|
}
|
|
|
|
wg.Wait()
|
|
}
|
|
|
|
func TestOpenSharedMMAP_Close(t *testing.T) {
|
|
fp, err := mmap.OpenSharedMMAP("./shared_mmap.go")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
for i := 0; i < 10; i++ {
|
|
_ = fp.Close()
|
|
}
|
|
}
|
|
|
|
func TestCountSharedMMAP(t *testing.T) {
|
|
t.Log(mmap.CountSharedMMAP())
|
|
}
|
|
|
|
func BenchmarkMMAP_Shared(b *testing.B) {
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
for pb.Next() {
|
|
func() {
|
|
reader, err := mmap.OpenSharedMMAP("../kvstore/query.go")
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
defer func() {
|
|
_ = reader.Close()
|
|
}()
|
|
|
|
var data = make([]byte, reader.Size())
|
|
n, readErr := reader.ReadAt(data, 0)
|
|
if readErr != nil {
|
|
b.Fatal(readErr)
|
|
}
|
|
if int64(n) != reader.Size() {
|
|
b.Fatal("size not equal")
|
|
}
|
|
}()
|
|
}
|
|
})
|
|
}
|
|
|
|
func BenchmarkMMAP_Shared2(b *testing.B) {
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
for pb.Next() {
|
|
func() {
|
|
reader, err := mmap.OpenSharedMMAP("../kvstore/query.go")
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
defer func() {
|
|
_ = reader.Close()
|
|
}()
|
|
|
|
var writer = &bytes.Buffer{}
|
|
n, readErr := reader.Write(writer, 0)
|
|
if readErr != nil {
|
|
b.Fatal(readErr)
|
|
}
|
|
if int64(n) != reader.Size() {
|
|
b.Fatal("size not equal")
|
|
}
|
|
}()
|
|
}
|
|
})
|
|
}
|
|
|
|
func BenchmarkMMAP_MMAP(b *testing.B) {
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
for pb.Next() {
|
|
func() {
|
|
fp, err := os.Open("../kvstore/query.go")
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
|
|
stat, err := fp.Stat()
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
|
|
reader, err := mmap.OpenFile(fp, stat.Size())
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
defer func() {
|
|
_ = reader.Close()
|
|
}()
|
|
|
|
_, _ = reader.Write(io.Discard, 0)
|
|
}()
|
|
}
|
|
})
|
|
}
|
|
|
|
func BenchmarkMMAP_FP_Read(b *testing.B) {
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
for pb.Next() {
|
|
func() {
|
|
fp, err := os.Open("../kvstore/query.go")
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
|
|
defer func() {
|
|
_ = fp.Close()
|
|
}()
|
|
|
|
var buf = bytepool.Pool1k.Get()
|
|
defer bytepool.Pool1k.Put(buf)
|
|
|
|
for {
|
|
_, readErr := fp.Read(buf.Bytes)
|
|
if readErr != nil {
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
})
|
|
}
|