Wiki
Version 2 (modified by todd.a, 6 years ago)

--

The Sandbox

This is just a page to practice and learn WikiFormatting.

Go ahead, edit it freely.

class MruList<of T> implements ICollection<of T>
    """
    Store a "most recently used" list of items.
    Calling .add puts the item at the front of the list.
    Also, .add will not grow the list when it already contains a given item.
    An MruList is enumerable, so you can use for loops on it, .toList, .numbered, .reversed, etc.

    Because an MruList uses a dictionary internally for some caching, the item T should implement
    both .equals and .getHashCode.
    
    to-do: support a max capacity
    """

    var _list = LinkedList<of T>()
    var _dict = Dictionary<of T, LinkedListNode<of T>>()

    def add(item as T)
        if _list.count <= 4  # to-do: test what the real switchover should be
            _list.remove(item)
        else
            lln as LinkedListNode<of T>?
            if _dict.tryGetValue(item, out lln), _list.remove(lln)
        _dict[item] = _list.addFirst(item) to !
        assert _list.count == _dict.count

    def clear
        _list.clear
        _dict.clear
        assert _list.count == _dict.count

    def contains(item as T) as bool
        return _list.contains(item)

    def copyTo(array as T[], arrayIndex as int)
        _list.copyTo(array, arrayIndex)

    get count as int
        return _list.count

    def getEnumerator as IEnumerator<of T>
        return _list.getEnumerator

    def getEnumerator as System.Collections.IEnumerator
        implements System.Collections.IEnumerable
        return .getEnumerator

    get isReadOnly as bool
        return false

    def remove(item as T) as bool
        _dict.remove(item)
        r = _list.remove(item)
        assert _list.count == _dict.count
        return r

    def set(items as IList<of T>)
        """
        Set all the items in the MRU list.
        There is no reversal of the items like if you called .add for each item.
        Repeated items are forbidden and will cause an exception.
        """
        .clear
        for item in items, _dict[item] = _list.addLast(item) to !
        trace _dict.count, _list.count
        if _dict.count <> _list.count, throw InvalidOperationException('repeated items in set list')


class TestMruList

    test
        ml = MruList<of String>()
        assert ml.count == 0
        ml.add('foo')
        assert ml.count == 1
        assert ml.contains('foo')
        assert not ml.contains('bar')
        assert ml.toList == ['foo']
        ml.clear
        assert ml.count == 0
        
        ml = MruList<of String>()
        ml.add('foo')
        ml.add('bar')
        assert ml.contains('foo')
        assert ml.contains('bar')
        assert ml.toList == ['bar', 'foo']  # note the mru order
        ml.add('bar')
        assert ml.toList == ['bar', 'foo']
        ml.add('bar')
        assert ml.toList == ['bar', 'foo']
        ml.add('foo')
        assert ml.toList == ['foo', 'bar']
        ml.add('baz')
        assert ml.toList == ['baz', 'foo', 'bar']

        ml = MruList<of String>()
        ml.set(['foo', 'bar', 'baz'])
        assert ml.toList == ['foo', 'bar', 'baz']
        ml.add('buzz')
        assert ml.toList == ['buzz', 'foo', 'bar', 'baz']
        ml.set(['foo', 'bar', 'baz'])
        assert ml.toList == ['foo', 'bar', 'baz']

Attachments