Skip to content

Commit

Permalink
Change queue management
Browse files Browse the repository at this point in the history
  • Loading branch information
MircoT committed Jul 2, 2020
1 parent 078dd8e commit 2e5628e
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 78 deletions.
2 changes: 1 addition & 1 deletion SmartCache/sim/cache/aiNN.go
Expand Up @@ -78,7 +78,7 @@ func (cache *AINN) Dumps(fileAndStats bool) [][]byte {
if fileAndStats {
// ----- Files -----
logger.Info("Dump cache files")
for file := range cache.files.Get(LRUQueue) {
for file := range cache.files.Get() {
dumpInfo, _ := json.Marshal(DumpInfo{Type: "FILES"})
dumpFile, _ := json.Marshal(file)
record, _ := json.Marshal(DumpRecord{
Expand Down
4 changes: 2 additions & 2 deletions SmartCache/sim/cache/aiRL.go
Expand Up @@ -100,7 +100,7 @@ func (cache *AIRL) Dumps(fileAndStats bool) [][]byte {
if fileAndStats {
// ----- Files -----
logger.Info("Dump cache files")
for file := range cache.files.Get(LRUQueue) {
for file := range cache.files.Get() {
dumpInfo, _ := json.Marshal(DumpInfo{Type: "FILES"})
dumpFile, _ := json.Marshal(file)
record, _ := json.Marshal(DumpRecord{
Expand Down Expand Up @@ -276,7 +276,7 @@ func (cache *AIRL) updateCategoryStates() {
idxWeights := cache.evictionFeatureManager.FileFeatureIdxWeights()
fileFeatureIndexes := cache.evictionFeatureManager.FileFeatureIdexMap()

for file := range cache.files.Get(NoQueue) {
for file := range cache.files.Get() {
// fmt.Println(file.Filename)
cache.bufferIdxVector = cache.bufferIdxVector[:0]
for feature := range cache.evictionFeatureManager.FileFeatureIter() {
Expand Down
88 changes: 35 additions & 53 deletions SmartCache/sim/cache/queue.go
Expand Up @@ -95,14 +95,15 @@ const (
type Manager struct {
files map[int64]*FileSupportData
queue []*FileSupportData
qType queueType
FrequencySum float64
FrequencySumSquare float64
SizeSum float64
SizeSumSquare float64
}

// Init initialize the struct
func (man *Manager) Init() {
func (man *Manager) Init(qType queueType) {
man.files = make(map[int64]*FileSupportData, 0)
man.queue = make([]*FileSupportData, 0)
}
Expand All @@ -124,55 +125,17 @@ func (man Manager) GetFile(id int64) *FileSupportData {
}

// Get values from a queue
func (man Manager) Get(queue queueType) chan *FileSupportData {
func (man Manager) Get() chan *FileSupportData {
ch := make(chan *FileSupportData)
go func() {
defer close(ch)
// Filtering trick
// https://github.com/golang/go/wiki/SliceTricks#filtering-without-allocating
switch queue {
case LRUQueue:
var curQueue ByRecency = man.queue
if !sort.IsSorted(curQueue) {
sort.Sort(curQueue)
}
for _, file := range curQueue {
ch <- file
}
case LFUQueue:
var curQueue ByFrequency = man.queue
if !sort.IsSorted(curQueue) {
sort.Sort(curQueue)
}
for _, file := range curQueue {
ch <- file
}
case SizeBigQueue:
var curQueue ByBigSize = man.queue
if !sort.IsSorted(curQueue) {
sort.Sort(curQueue)
}
for _, file := range curQueue {
ch <- file
}
case SizeSmallQueue:
var curQueue BySmallSize = man.queue
if !sort.IsSorted(curQueue) {
sort.Sort(curQueue)
}
for _, file := range curQueue {
if man.qType != NoQueue {
for _, file := range man.queue {
ch <- file
}
case WeightQueue:
var curQueue ByWeight = man.queue
if !sort.IsSorted(curQueue) {
sort.Sort(curQueue)
}
for _, file := range curQueue {
ch <- file
}
default:
logger.Debug("No queue requested, only files...")
} else {
for _, file := range man.files {
ch <- file
}
Expand All @@ -184,15 +147,13 @@ func (man Manager) Get(queue queueType) chan *FileSupportData {
// Remove a file already in queue
func (man *Manager) Remove(files []int64) {
for _, file := range files {
for idx := len(man.queue) - 1; idx > -1; idx-- {
// https://github.com/golang/go/wiki/SliceTricks#delete
if man.queue[idx].Filename == file {
copy(man.queue[idx:], man.queue[idx+1:])
man.queue[len(man.queue)-1] = nil // or the zero value of T
man.queue = man.queue[:len(man.queue)-1]
break
}
}
removeIdx := sort.Search(len(man.queue), func(idx int) bool { return man.queue[idx].Filename > file })
// Delete trick
// https://github.com/golang/go/wiki/SliceTricks#delete
copy(man.queue[removeIdx:], man.queue[removeIdx+1:])
man.queue[len(man.queue)-1] = nil // or the zero value of T
man.queue = man.queue[:len(man.queue)-1]

curFile := man.files[file]
man.SizeSum -= curFile.Size
man.SizeSumSquare -= (curFile.Size * curFile.Size)
Expand All @@ -205,11 +166,32 @@ func (man *Manager) Remove(files []int64) {
// Insert a file into the queue manager
func (man *Manager) Insert(file FileSupportData) {
man.files[file.Filename] = &file
man.queue = append(man.queue, &file)
man.SizeSum += file.Size
man.SizeSumSquare += (file.Size * file.Size)
man.FrequencySum += float64(file.Frequency)
man.FrequencySumSquare += float64(file.Frequency * file.Frequency)
var insertIdx = -1
switch man.qType {
case LRUQueue:
insertIdx = sort.Search(len(man.queue), func(idx int) bool { return man.queue[idx].Recency > file.Recency })
case LFUQueue:
insertIdx = sort.Search(len(man.queue), func(idx int) bool { return man.queue[idx].Frequency > file.Frequency })
case SizeBigQueue:
insertIdx = sort.Search(len(man.queue), func(idx int) bool { return man.queue[idx].Size > file.Size || man.queue[idx].Recency > file.Recency })
case SizeSmallQueue:
insertIdx = sort.Search(len(man.queue), func(idx int) bool { return man.queue[idx].Size < file.Size || man.queue[idx].Recency > file.Recency })
case WeightQueue:
insertIdx = sort.Search(len(man.queue), func(idx int) bool { return man.queue[idx].Recency > file.Recency })
}
if insertIdx == len(man.queue) {
man.queue = append(man.queue, &file)
} else {
// Trick
// https://github.com/golang/go/wiki/SliceTricks#insert
man.queue = append(man.queue, nil)
copy(man.queue[insertIdx+1:], man.queue[insertIdx:])
man.queue[insertIdx] = &file
}
}

// Update a file into the queue manager
Expand Down
22 changes: 7 additions & 15 deletions SmartCache/sim/cache/queue_test.go
Expand Up @@ -18,7 +18,7 @@ func BenchmarkQueue(b *testing.B) {
r := rand.New(rand.NewSource(42))

man := Manager{}
man.Init()
man.Init(LRUQueue)

for idx := 0; idx < numTests; idx++ {
man.Insert(
Expand Down Expand Up @@ -47,7 +47,7 @@ func BenchmarkQueue(b *testing.B) {
func TestLRUQueue(t *testing.T) {
r := rand.New(rand.NewSource(42))
man := Manager{}
man.Init()
man.Init(LRUQueue)

insertedFiles := []int64{}

Expand All @@ -72,7 +72,7 @@ func TestLRUQueue(t *testing.T) {
})

prevRecency := int64(numTests + 1)
for file := range man.Get(LRUQueue) {
for file := range man.Get() {
// fmt.Println(file.Filename, file.Recency, prevRecency)
if prevRecency < file.Recency {
t.Log("LRU order not valid")
Expand All @@ -93,7 +93,7 @@ func TestLRUQueue(t *testing.T) {
func TestLFUQueue(t *testing.T) {
r := rand.New(rand.NewSource(42))
man := Manager{}
man.Init()
man.Init(LFUQueue)

insertedFiles := []int64{}

Expand All @@ -118,7 +118,7 @@ func TestLFUQueue(t *testing.T) {
})

prevFrequency := int64(-1)
for file := range man.Get(LFUQueue) {
for file := range man.Get() {
// fmt.Println(file.Filename, file.Frequency, prevFrequency)
if prevFrequency > file.Frequency {
t.Log("LFU order not valid")
Expand All @@ -139,7 +139,7 @@ func TestLFUQueue(t *testing.T) {
func TestSizeQueue(t *testing.T) {
r := rand.New(rand.NewSource(42))
man := Manager{}
man.Init()
man.Init(SizeBigQueue)

insertedFiles := []int64{}

Expand All @@ -164,22 +164,14 @@ func TestSizeQueue(t *testing.T) {
})

prevSize := float64(-1.0)
for file := range man.Get(SizeBigQueue) {
for file := range man.Get() {
// fmt.Println(file.Filename, file.Size, prevSize)
if prevSize > file.Size {
t.Log("Big size order not valid")
t.Fatal()
}
prevSize = file.Size
}
for file := range man.Get(SizeSmallQueue) {
// fmt.Println(file.Filename, file.Size, prevSize)
if prevSize < file.Size {
t.Log("Small size order not valid")
t.Fatal()
}
prevSize = file.Size
}

man.Remove(insertedFiles)

Expand Down
12 changes: 6 additions & 6 deletions SmartCache/sim/cache/simpleCache.go
Expand Up @@ -54,7 +54,7 @@ func (cache *SimpleCache) Init(vars ...interface{}) interface{} {
}

cache.stats.Init()
cache.files.Init()
cache.files.Init(cache.ordType)

if cache.HighWaterMark == 0.0 {
cache.HighWaterMark = 95.0
Expand Down Expand Up @@ -82,7 +82,7 @@ func (cache *SimpleCache) SetBandwidth(bandwidth float64) {

// ClearFiles remove the cache files
func (cache *SimpleCache) ClearFiles() {
cache.files.Init()
cache.files.Init(cache.ordType)
cache.stats.Clear()
cache.size = 0.
}
Expand Down Expand Up @@ -134,7 +134,7 @@ func (cache *SimpleCache) Dumps(fileAndStats bool) [][]byte {
if fileAndStats {
// ----- Files -----
logger.Info("Dump cache files")
for file := range cache.files.Get(LRUQueue) {
for file := range cache.files.Get() {
dumpInfo, _ := json.Marshal(DumpInfo{Type: "FILES"})
dumpFile, _ := json.Marshal(file)
record, _ := json.Marshal(DumpRecord{
Expand Down Expand Up @@ -358,7 +358,7 @@ func (cache *SimpleCache) Free(amount float64, percentage bool) float64 {
}
if sizeToDelete > 0. {
deletedFiles := make([]int64, 0)
for curFile := range cache.files.Get(cache.ordType) {
for curFile := range cache.files.Get() {
logger.Debug("delete",
zap.Int64("filename", curFile.Filename),
zap.Float64("fileSize", curFile.Size),
Expand Down Expand Up @@ -534,7 +534,7 @@ func (cache *SimpleCache) MeanFrequency() float64 {
func (cache *SimpleCache) MeanRecency() float64 {
totRecency := 0.0
curTick := float64(cache.tick)
for file := range cache.files.Get(NoQueue) {
for file := range cache.files.Get() {
totRecency += (curTick - float64(file.Recency))
}
return totRecency / float64(cache.files.Len())
Expand All @@ -557,7 +557,7 @@ func (cache *SimpleCache) StdDevFreq() float64 {
func (cache *SimpleCache) StdDevRec() float64 {
mean := cache.MeanRecency()
sum := 0.0
for file := range cache.files.Get(NoQueue) {
for file := range cache.files.Get() {
sum += math.Pow(float64(file.Recency)-mean, 2)
}
return math.Sqrt(sum / (float64(cache.files.Len()) - 1.0))
Expand Down
2 changes: 1 addition & 1 deletion SmartCache/sim/cache/weightFunLRU.go
Expand Up @@ -34,7 +34,7 @@ func (cache *WeightFunLRU) Dumps(fileAndStats bool) [][]byte {
if fileAndStats {
// ----- Files -----
logger.Info("Dump cache files")
for file := range cache.files.Get(LRUQueue) {
for file := range cache.files.Get() {
dumpInfo, _ := json.Marshal(DumpInfo{Type: "FILES"})
dumpFile, _ := json.Marshal(file)
record, _ := json.Marshal(DumpRecord{
Expand Down

0 comments on commit 2e5628e

Please sign in to comment.