the image cache is now limited to 16mb

This commit is contained in:
Thomas Friedel 2020-02-14 16:28:12 +01:00
parent 0d915f7178
commit 7f7efd5a8a

View file

@ -7,15 +7,45 @@ import (
"image" "image"
"io/ioutil" "io/ioutil"
"os" "os"
"sort"
"strings" "strings"
"time"
"github.com/tfriedel6/canvas/backend/backendbase" "github.com/tfriedel6/canvas/backend/backendbase"
) )
type Image struct { type Image struct {
src interface{}
cv *Canvas cv *Canvas
img backendbase.Image img backendbase.Image
deleted bool deleted bool
lastUsed time.Time
}
func (cv *Canvas) reduceCache(keepSize int) {
var total int
for _, img := range cv.images {
w, h := img.img.Size()
total += w * h
}
if total <= keepSize {
return
}
list := make([]*Image, 0, len(cv.images))
for _, img := range cv.images {
list = append(list, img)
}
sort.Slice(list, func(i, j int) bool {
return list[i].lastUsed.Before(list[j].lastUsed)
})
pos := 0
for total > keepSize {
img := list[pos]
pos++
delete(cv.images, img.src)
w, h := img.img.Size()
total -= w * h
}
} }
// LoadImage loads an image. The src parameter can be either an image from the // LoadImage loads an image. The src parameter can be either an image from the
@ -24,12 +54,15 @@ type Image struct {
// import the required format packages // import the required format packages
func (cv *Canvas) LoadImage(src interface{}) (*Image, error) { func (cv *Canvas) LoadImage(src interface{}) (*Image, error) {
if img, ok := src.(*Image); ok { if img, ok := src.(*Image); ok {
img.lastUsed = time.Now()
return img, nil return img, nil
} else if _, ok := src.([]byte); !ok { } else if _, ok := src.([]byte); !ok {
if img, ok := cv.images[src]; ok { if img, ok := cv.images[src]; ok {
img.lastUsed = time.Now()
return img, nil return img, nil
} }
} }
cv.reduceCache(16_000_000)
var srcImg image.Image var srcImg image.Image
switch v := src.(type) { switch v := src.(type) {
case image.Image: case image.Image:
@ -59,7 +92,7 @@ func (cv *Canvas) LoadImage(src interface{}) (*Image, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
cvimg := &Image{cv: cv, img: backendImg} cvimg := &Image{cv: cv, img: backendImg, lastUsed: time.Now(), src: src}
if _, ok := src.([]byte); !ok { if _, ok := src.([]byte); !ok {
cv.images[src] = cvimg cv.images[src] = cvimg
} }
@ -72,6 +105,7 @@ func (cv *Canvas) getImage(src interface{}) *Image {
} else if img, ok := cv.images[src]; ok { } else if img, ok := cv.images[src]; ok {
return img return img
} }
cv.reduceCache(16_000_000)
switch v := src.(type) { switch v := src.(type) {
case *Image: case *Image:
return v return v