Files
EdgeNode/internal/caches/list_file_hash_map.go

179 lines
3.4 KiB
Go
Raw Normal View History

2022-08-20 11:47:57 +08:00
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package caches
import (
"github.com/TeaOSLab/EdgeNode/internal/utils"
2022-08-20 11:47:57 +08:00
"github.com/TeaOSLab/EdgeNode/internal/zero"
2022-08-22 09:44:09 +08:00
"math/big"
2022-08-20 11:47:57 +08:00
"sync"
)
2023-10-05 17:40:27 +08:00
const HashMapSharding = 11
var bigIntPool = sync.Pool{New: func() any {
return big.NewInt(0)
}}
// FileListHashMap 文件Hash列表
2022-08-20 11:47:57 +08:00
type FileListHashMap struct {
2023-10-05 17:40:27 +08:00
m []map[uint64]zero.Zero
lockers []*sync.RWMutex
isAvailable bool
isReady bool
2022-08-20 11:47:57 +08:00
}
func NewFileListHashMap() *FileListHashMap {
2023-10-05 17:40:27 +08:00
var m = make([]map[uint64]zero.Zero, HashMapSharding)
var lockers = make([]*sync.RWMutex, HashMapSharding)
for i := 0; i < HashMapSharding; i++ {
m[i] = map[uint64]zero.Zero{}
lockers[i] = &sync.RWMutex{}
}
2022-08-20 11:47:57 +08:00
return &FileListHashMap{
2023-10-05 17:40:27 +08:00
m: m,
lockers: lockers,
isAvailable: false,
isReady: false,
2022-08-20 11:47:57 +08:00
}
}
func (this *FileListHashMap) Load(db *FileListDB) error {
// 如果系统内存过小,我们不缓存
if utils.SystemMemoryGB() < 3 {
return nil
}
this.isAvailable = true
2022-08-20 11:47:57 +08:00
var lastId int64
var maxLoops = 50_000
2022-08-20 11:47:57 +08:00
for {
hashList, maxId, err := db.ListHashes(lastId)
if err != nil {
return err
}
if len(hashList) == 0 {
break
}
2022-08-22 09:44:09 +08:00
this.AddHashes(hashList)
2022-08-20 11:47:57 +08:00
lastId = maxId
maxLoops --
if maxLoops <= 0 {
break
}
2022-08-20 11:47:57 +08:00
}
this.isReady = true
return nil
}
func (this *FileListHashMap) Add(hash string) {
if !this.isAvailable {
return
}
2023-10-05 17:40:27 +08:00
hashInt, index := this.bigInt(hash)
this.lockers[index].Lock()
this.m[index][hashInt] = zero.New()
this.lockers[index].Unlock()
2022-08-22 09:44:09 +08:00
}
func (this *FileListHashMap) AddHashes(hashes []string) {
if !this.isAvailable {
return
}
for _, hash := range hashes {
2023-10-05 17:40:27 +08:00
hashInt, index := this.bigInt(hash)
this.lockers[index].Lock()
this.m[index][hashInt] = zero.New()
this.lockers[index].Unlock()
2022-08-22 09:44:09 +08:00
}
2022-08-20 11:47:57 +08:00
}
func (this *FileListHashMap) Delete(hash string) {
if !this.isAvailable {
return
}
2023-10-05 17:40:27 +08:00
hashInt, index := this.bigInt(hash)
this.lockers[index].Lock()
delete(this.m[index], hashInt)
this.lockers[index].Unlock()
2022-08-20 11:47:57 +08:00
}
func (this *FileListHashMap) Exist(hash string) bool {
if !this.isAvailable {
return true
}
2022-08-20 11:47:57 +08:00
if !this.isReady {
// 只有完全Ready时才能判断是否为false
return true
}
2023-10-05 17:40:27 +08:00
hashInt, index := this.bigInt(hash)
this.lockers[index].RLock()
_, ok := this.m[index][hashInt]
this.lockers[index].RUnlock()
2022-08-20 11:47:57 +08:00
return ok
}
func (this *FileListHashMap) Clean() {
2023-10-05 17:40:27 +08:00
for i := 0; i < HashMapSharding; i++ {
this.lockers[i].Lock()
}
this.m = make([]map[uint64]zero.Zero, HashMapSharding)
for i := HashMapSharding - 1; i >= 0; i-- {
this.lockers[i].Unlock()
}
2022-08-20 11:47:57 +08:00
}
func (this *FileListHashMap) IsReady() bool {
return this.isReady
}
2022-08-22 09:44:09 +08:00
2022-09-07 11:34:26 +08:00
func (this *FileListHashMap) Len() int {
2023-10-05 17:40:27 +08:00
for i := 0; i < HashMapSharding; i++ {
this.lockers[i].Lock()
}
var count = 0
for _, shard := range this.m {
count += len(shard)
}
for i := HashMapSharding - 1; i >= 0; i-- {
this.lockers[i].Unlock()
}
return count
2022-09-07 11:34:26 +08:00
}
2023-10-01 19:48:35 +08:00
func (this *FileListHashMap) SetIsAvailable(isAvailable bool) {
this.isAvailable = isAvailable
}
2023-10-05 17:40:27 +08:00
func (this *FileListHashMap) SetIsReady(isReady bool) {
this.isReady = isReady
}
func (this *FileListHashMap) bigInt(hash string) (hashInt uint64, index int) {
var bigInt = bigIntPool.Get().(*big.Int)
2022-08-22 09:44:09 +08:00
bigInt.SetString(hash, 16)
2023-10-05 17:40:27 +08:00
hashInt = bigInt.Uint64()
bigIntPool.Put(bigInt)
index = int(hashInt % HashMapSharding)
return
2022-08-22 09:44:09 +08:00
}