<commit_before>package filecache

import "container/list"

type Iterator interface {
	Next() Iterator
	Value() interface{}
}

type listElementIterator struct {
	le *list.Element
}

func (me listElementIterator) Next() Iterator {
	e := me.le.Next()
	if e == nil {
		return nil
	}
	return listElementIterator{e}
}

func (me listElementIterator) Value() interface{} {
	return me.le.Value
}

func newLRUItems() *lruItems {
	return &lruItems{list.New(), make(map[ItemInfo]*list.Element)}
}

type lruItems struct {
	list  *list.List
	elems map[ItemInfo]*list.Element
}

func (me *lruItems) Front() Iterator {
	e := me.list.Front()
	if e == nil {
		return nil
	}
	return listElementIterator{e}
}

func (me *lruItems) LRU() ItemInfo {
	return me.list.Front().Value.(ItemInfo)
}

func (me *lruItems) insertList(ii ItemInfo) *list.Element {
	for e := me.list.Back(); e != nil; e = e.Prev() {
		if ii.Accessed.After(e.Value.(ItemInfo).Accessed) {
			return me.list.InsertAfter(ii, e)
		}
	}
	return me.list.PushFront(ii)
}

func (me *lruItems) Insert(ii ItemInfo) {
	le := me.insertList(ii)
	me.elems[ii] = le
}

func (me *lruItems) Remove(ii ItemInfo) bool {
	e, ok := me.elems[ii]
	if !ok {
		return false
	}
	delete(me.elems, ii)
	if me.list.Remove(e).(ItemInfo) != ii {
		panic("f7u12")
	}
	return true
}<commit_msg>filecache: Store LRU items in a tree<commit_after>package filecache

import (
	"container/list"
	"io"

	"github.com/cznic/b"
)

type Iterator interface {
	Next() Iterator
	Value() interface{}
}

type listElementIterator struct {
	le *list.Element
}

func (me listElementIterator) Next() Iterator {
	e := me.le.Next()
	if e == nil {
		return nil
	}
	return listElementIterator{e}
}

func (me listElementIterator) Value() interface{} {
	return me.le.Value
}

func newLRUItems() *lruItems {
	return &lruItems{b.TreeNew(func(_a, _b interface{}) int {
		a := _a.(ItemInfo)
		b := _b.(ItemInfo)
		if a.Accessed != b.Accessed {
			if a.Accessed.Before(b.Accessed) {
				return -1
			} else {
				return 1
			}
		}
		if a.Path == b.Path {
			return 0
		}
		if a.Path < b.Path {
			return -1
		}
		return 1
	})}
}

type lruItems struct {
	tree *b.Tree
}

type bEnumeratorIterator struct {
	e *b.Enumerator
	v ItemInfo
}

func (me bEnumeratorIterator) Next() Iterator {
	_, v, err := me.e.Next()
	if err == io.EOF {
		return nil
	}
	return bEnumeratorIterator{me.e, v.(ItemInfo)}
}

func (me bEnumeratorIterator) Value() interface{} {
	return me.v
}

func (me *lruItems) Front() Iterator {
	e, _ := me.tree.SeekFirst()
	if e == nil {
		return nil
	}
	return bEnumeratorIterator{
		e: e,
	}.Next()
}

func (me *lruItems) LRU() ItemInfo {
	_, v := me.tree.First()
	return v.(ItemInfo)
}

func (me *lruItems) Insert(ii ItemInfo) {
	me.tree.Set(ii, ii)
}

func (me *lruItems) Remove(ii ItemInfo) bool {
	return me.tree.Delete(ii)
}
{'fraction_non_alphanumeric': 0.14932767162066526, 'fraction_numerical': 0.0028308563340410475, 'mean_word_length': 3.6496710526315788, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1266518', 'n_tokens_mistral': 1161, 'n_tokens_neox': 1118, 'n_words': 276}