Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement ChangeableOrderedSet #64

Open
luithefirst opened this issue Apr 16, 2020 · 1 comment
Open

implement ChangeableOrderedSet #64

luithefirst opened this issue Apr 16, 2020 · 1 comment
Assignees
Labels
feature a feature to be implemented
Milestone

Comments

@luithefirst
Copy link
Collaborator

luithefirst commented Apr 16, 2020

A changeable data structure like there is Aardvark.Base.Increment with ChangeableOrderedSet (ChangeableIndexSet?) allows precise expression on what an application state can be, can directly provide IAdaptiveHashSet and IAdaptiveIndexList views and has ideal runtime complexity when operating on item values.

Assuming the internal state contains a HashMap<'a, Index> and IndexList<'a> the data structure could provide the following runtime complexity compared to a ChangeableIndexList:

Add(item: 'a) // O(log N) vs O(log N)
AddBefore(before : 'a, item :'a) // O(log N) vs O(N)
AddAfter(after : 'a, item : 'a) // O(log N) vs O(N)
Remove(item: 'a) // O(log n) vs O(n)
Contains(item: 'a) // O(log n) vs O(n)

It would be nice to consider this as an extension to this library.

@krauthaufen krauthaufen self-assigned this Apr 20, 2020
@krauthaufen krauthaufen added the enhancement New feature or request label Apr 20, 2020
@krauthaufen krauthaufen added this to the 1.1.0 milestone Dec 17, 2020
@krauthaufen krauthaufen added feature a feature to be implemented and removed enhancement New feature or request labels Dec 17, 2020
@luithefirst
Copy link
Collaborator Author

To give an update, this is the substitute I have been using since the port to FSharp.Data.Adaptive:

public class ChangeableOrderedSet<T> : IList<T>
{
    ChangeableIndexList<T> m_list = new ChangeableIndexList<T>();
    HashSet<T> m_set = new HashSet<T>();
    IAdaptiveHashSet<T> m_adaptiveSet;

    public ChangeableOrderedSet()
    {
        m_adaptiveSet = m_list.ToAdaptiveHashSet();
    }

    public bool Contains(T item)
    {
        return m_set.Contains(item);
    }

    public bool Add(T item)
    {
        if (m_set.Add(item))
        {
            m_list.Add(item);
            return true;
        }
        return false;
    }

    public bool Remove(T item)
    {
        if(m_set.Remove(item))
        {
            m_list.Remove(item);
            return true;
        }
        return false;
    }

    public void Clear()
    {
        m_list.Clear();
        m_set.Clear();
    }

    public int IndexOf(T item)
    {
        return m_list.Value.IndexOf(item);
    }

    public void Insert(int index, T item)
    {
        m_list.InsertAt(index, item);
    }

    public void RemoveAt(int index)
    {
        m_list.RemoveAt(index);
    }

    void ICollection<T>.Add(T item)
    {
        Add(item);
    }

    public void CopyTo(T[] array, int arrayIndex)
    {
        ((IList<T>)m_list.Value).CopyTo(array, arrayIndex);
    }

    public IEnumerator<T> GetEnumerator()
    {
        return ((IEnumerable<T>)m_list.Value).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return ((IEnumerable)m_list.Value).GetEnumerator();
    }

    public int Count => m_set.Count;

    public IAdaptiveHashSet<T> Set => m_adaptiveSet;
    public IAdaptiveIndexList<T> List => m_list;

    /// <summary>
    /// ICollection view. Can be used for faster enumeration if the order does not matter.
    /// </summary>
    public ICollection<T> Collection => m_set;

    public bool IsReadOnly => false;

    public T this[int index]
    {
        get => m_list[index];
        set
        {
            if (index >= m_set.Count)
                throw new IndexOutOfRangeException();
            if (m_set.Contains(value))
                throw new InvalidOperationException("Item already contained in the ChangeableOrderedSet");

            var old = m_list[index];
            m_set.Remove(old);
            m_list[index] = value;
            m_set.Add(value);
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature a feature to be implemented
Projects
None yet
Development

No branches or pull requests

2 participants