private void Evict(LruNode <TValue> node) { node.Remove(); bool removed = _dict.Remove(node.Key); Debug.Assert(removed); }
public bool Add(ulong key, TValue value) { if (_dict.Count == _capacity) { Evict(); } var node = new LruNode <TValue>(key, value); if (!_dict.TryAdd(key, node)) { // although rare, this could happen if a state is not in the table during the initial lookup, but is // populated during a recursive call as it searches its children. afterwards, there will be a conflict // when it tries to call Add() with an existing key. our behavior is to favor the newer entry since it // probably contains information about a greater depth. // // this could also theoretically happen in the case of a hash collision, although that's very unlikely. var existingNode = _dict[key]; Log.Debug("(lru) Evicting node {0} in favor of {1}", existingNode, node); Evict(existingNode); _dict.Add(key, node); } _nodes.AddToTop(node); return(true); }
public void Remove() { Debug.Assert(Previous != null && Next != null); Previous.Next = Next; Next.Previous = Previous; Previous = null; Next = null; }
public bool Add(ulong key, TValue value) { int depth = value.Depth; if (_dict.Count == _capacity) { if (depth < _minDepth) { // If we're full, don't bother adding nodes below our minimum depth return(false); } Evict(); // Although very rare, this could happen if eviction caused _minDepth to increase if (depth < _minDepth) { _minDepth = depth; } } else if (_minDepth == null || depth < _minDepth) { _minDepth = depth; } EnsureDepth(depth); var node = new LruNode <TValue>(key, value); if (!_dict.TryAdd(key, node)) { var existingNode = _dict[key]; Log.Debug("(depth) Evicting node {0} in favor of {1}", existingNode, node); Evict(existingNode); _dict.Add(key, node); } _lists[depth].AddToTop(node); return(true); }