代码拉取完成,页面将自动刷新
package datacache
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
"strings"
"sync"
"time"
"gitee.com/haodreams/golib/logs"
"gitee.com/haodreams/libs/routine"
"gitee.com/haodreams/libs/ee"
)
// Cache 缓存文件
type Cache struct {
path string
lock *sync.RWMutex
mapItem map[int32]*Item
routine.Routine
saveFile *os.File
createTime int64
saveDays int //当天数为0时不开启缓存
}
// Reset 复位
func (me *Cache) Reset() {
me.lock.Lock()
me.mapItem = map[int32]*Item{}
me.lock.Unlock()
}
// Setup 初始化设置
func (me *Cache) Setup() (err error) {
me.lock = new(sync.RWMutex)
me.mapItem = map[int32]*Item{}
me.saveDays = 10
me.SetSavePath("cache")
me.AddFuncAfterStart(me.afterStart)
me.AddFuncBeforStop(me.beforeStop)
go me.autoDeleteTimeoutFile()
return
}
// afterStart 启动前执行的操作
func (me *Cache) afterStart() (err error) {
go me.autoFlush()
return
}
// beforeStop 停止前执行的操作
func (me *Cache) beforeStop() (err error) {
return
}
// GetSavePath 获取保存的路径
func (me *Cache) GetSavePath() string {
return me.path
}
// SetSavePath 设置数据保存的路径
func (me *Cache) SetSavePath(path string) (err error) {
path = strings.Replace(path, "\\", "/", -1)
if !strings.HasSuffix(path, "/") {
path += "/"
}
me.path = path
return os.MkdirAll(me.path, 0775)
}
// SetSaveDays 设置保存的天数
func (me *Cache) SetSaveDays(days int) {
if days < 0 {
days = 0
}
me.saveDays = days
logs.Info("历史数据保存天数", days)
}
// Update 更新内存数据
func (me *Cache) Update(id int32, value float64, status byte, time int64) {
if me.saveDays == 0 {
return
}
me.lock.RLock()
item, ok := me.mapItem[id]
me.lock.RUnlock()
if !ok {
item = new(Item)
item.ID = id
item.Deadband = DeadbandConst
item.Status = 0xff
me.lock.Lock()
me.mapItem[id] = item
me.lock.Unlock()
}
item.Value = value
item.Status = status
item.Time = int32(time)
}
// UpdateWithDeadband 更新内存数据
func (me *Cache) UpdateWithDeadband(id int32, value float64, status byte, time int64, deadband float64) {
if me.saveDays == 0 {
return
}
me.lock.RLock()
item, ok := me.mapItem[id]
me.lock.RUnlock()
if !ok {
item = new(Item)
item.ID = id
item.Deadband = deadband
item.Status = 0xff
me.lock.Lock()
me.mapItem[id] = item
me.lock.Unlock()
}
item.Deadband = deadband
item.Value = value
item.Status = status
item.Time = int32(time)
}
func (me *Cache) save(t int64, all bool) (err error) {
if me.saveDays == 0 {
return
}
if me.saveFile != nil {
t -= t%600 + 120
me.lock.RLock()
defer me.lock.RUnlock()
ok := false
if all {
for _, item := range me.mapItem {
if item != nil {
if item.Time < int32(t) {
continue
}
ok = true
_, e := me.saveFile.Write(item.Encode())
if e != nil {
err = ee.New(e).Once2(logs.Errorf)
me.saveFile.Close()
me.saveFile = nil
return
}
}
}
} else {
for _, item := range me.mapItem {
if item != nil {
if item.Time < int32(t) {
continue
}
if !Deadband(item.LastValue, item.Value, item.Deadband) || item.LastStatus != item.Status {
item.LastValue = item.Value
item.LastStatus = item.Status
_, e := me.saveFile.Write(item.Encode())
if e != nil {
err = ee.New(e).Once2(logs.Errorf)
me.saveFile.Close()
me.saveFile = nil
return
}
ok = true
}
}
}
}
if ok {
me.saveFile.Sync()
}
}
return
}
// GetItems 获取一个文件的全部点
func (me *Cache) GetItems(t int64) (items []*Item, err error) {
ft := time.Unix(t-t%600, 0)
path := fmt.Sprintf("%s%s/%s", me.path, ft.Format("20060102"), ft.Format("1504.dat"))
//logs.Info("path:", path)
f, e := os.Open(path)
if e != nil {
err = ee.New(e)
return
}
defer f.Close()
buf := bufio.NewReader(f)
line := make([]byte, 17)
for n, err := io.ReadFull(buf, line); n == 17 && err == nil; n, err = io.ReadFull(buf, line) {
item := new(Item)
e := item.Decode(line)
if e != nil {
e.Once2(logs.Errorf)
continue
}
items = append(items, item)
}
return
}
// flush 保存内存中的数据到文件
func (me *Cache) flush() (err error) {
if me.saveDays == 0 {
return
}
t := time.Now()
if (t.Unix()-600) >= me.createTime || (me.createTime > t.Unix()) {
if me.saveFile != nil {
//保存一次全部数据
me.save(t.Unix(), true)
me.saveFile.Close()
me.saveFile = nil
return
}
var e error
t = time.Unix(t.Unix()-t.Unix()%600, 0)
path := fmt.Sprintf("%s%s/", me.path, t.Format("20060102"))
os.Mkdir(path, 0775)
path += t.Format("1504.dat")
me.saveFile, e = os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
//logs.Info(t.Unix(), path, me.path)
if e != nil {
err = ee.New(e).Once2(logs.Errorf)
me.saveFile = nil
return
}
//保存一次全部数据
me.save(t.Unix(), true)
me.createTime = t.Unix()
} else {
me.save(t.Unix(), false)
}
return
}
// autoFlush 保存内存中的数据到文件
func (me *Cache) autoFlush() {
if me.saveDays == 0 {
return
}
for me.IsRunning() {
me.flush()
//time.Sleep(time.Millisecond * 800)
time.Sleep(time.Second)
}
}
func (me *Cache) autoDeleteTimeoutFile() {
if me.saveDays == 0 {
return
}
t := time.NewTicker(time.Second * 7200)
//t := time.NewTicker(time.Second * 30)
for range t.C {
st := time.Now().Unix() - int64(86400*time.Duration(me.saveDays))
timeout := time.Unix(st, 0).Format("20060102")
fs, err := ioutil.ReadDir(me.path)
if err != nil {
continue
}
for _, f := range fs {
if f.IsDir() {
if f.Name() < timeout {
err = os.RemoveAll(me.path + f.Name())
if err != nil {
logs.Error(err.Error())
}
}
}
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。