Пример #1
0
        /// <summary>
        /// Detaches the node's tail, clears the node's value, and releases the node to the pool.
        ///
        /// Note: Nodes should generally not be released one at a time as it will incur much greater overhead than batching releases using LinkedHeadTail<T>s.
        /// </summary>
        public void TrimAndDispose()
        {
            value = default(T);

            lock (poolLock) {
                next = pool;
                pool = this;
            }
        }
Пример #2
0
        /// <summary>
        ///     Returns a Slinq that enumerates the values contained in the list.
        ///     Ownership of the nodes contained in the list is transferred to the Slinq.  When the Slinq is disposed, the nodes will be added to the
        ///     disposal queue.
        /// </summary>
        public Slinq <T, LinkedContext <T> > SlinqAndDispose()
        {
            var slinq = LinkedContext <T> .Slinq(this, true);

            head  = null;
            tail  = null;
            count = 0;

            return(slinq);
        }
Пример #3
0
 /// <summary>
 ///     Releases the head of the list to the node pool.
 ///     The list must be well formed when calling this method or the program will enter an invalid state, resulting in unspecified behaviour.
 /// </summary>
 public void Dispose()
 {
     if (head != null)
     {
         head.Dispose();
     }
     head  = null;
     tail  = null;
     count = 0;
 }
Пример #4
0
 /// <summary>
 ///     Adds the head of the list to the disposal queue.
 ///     The list must be well formed when calling this method or the program will enter an invalid state, resulting in unspecified behaviour.
 /// </summary>
 public void DisposeInBackground()
 {
     if (head != null)
     {
         head.DisposeInBackground();
     }
     head  = null;
     tail  = null;
     count = 0;
 }
Пример #5
0
        /// <summary>
        ///     Appends the specified value to the value list for the specified key.  If the key was previously unmapped it is appended to the key
        ///     list.
        ///     Calling this method transfers ownership of the specified node and any linked nodes to the lookup.
        /// </summary>
        public void Add(K key, Linked <T> value)
        {
            LinkedHeadTail <T> values;

            if (!dictionary.TryGetValue(key, out values))
            {
                keys.Append(key);
            }
            values.Append(value);
            dictionary[key] = values;
        }
Пример #6
0
        /// <summary>
        /// Adds the nodes in the list to the specified lookup using the specified key selector.
        ///
        /// Ownership of the nodes contained in this list is transerred to the lookup.
        /// </summary>
        public Lookup <K, T> AddTo <K, P>(Lookup <K, T> lookup, DelegateFunc <T, P, K> selector, P parameter)
        {
            while (head != null)
            {
                var node = head;
                head      = head.next;
                node.next = null;

                lookup.Add(selector(node.value, parameter), node);
            }
            tail  = null;
            count = 0;
            return(lookup);
        }
Пример #7
0
        /// <summary>
        ///     Adds the nodes in the list to the specified lookup using the specified key selector.
        ///     Ownership of the nodes contained in this list is transerred to the lookup.
        /// </summary>
        public Lookup <K, T> AddTo <K>(Lookup <K, T> lookup, Func <T, K> selector)
        {
            while (head != null)
            {
                var node = head;
                head      = head.next;
                node.next = null;

                lookup.Add(selector(node.value), node);
            }

            tail  = null;
            count = 0;
            return(lookup);
        }
Пример #8
0
        /// <summary>
        ///     Appends a pooled node with with specified value to the end of the list.
        /// </summary>
        public void Append(T value)
        {
            var node = Linked <T> .Borrow(value);

            if (head == null)
            {
                head = node;
            }
            else
            {
                tail.next = node;
            }
            tail = node;
            ++count;
        }
Пример #9
0
 /// <summary>
 ///     Appends the specified list to the end of this list.
 ///     This list and the specified list must be well formed when calling this method or the program will enter an invalid state, resulting in
 ///     unspecified behaviour.
 ///     Calling this method will invalidate the specified list and any variables containing its nodes.
 /// </summary>
 public void Append(LinkedHeadTail <T> other)
 {
     if (other.count == 0)
     {
         // noop
     }
     else if (head == null)
     {
         head  = other.head;
         tail  = other.tail;
         count = other.count;
     }
     else
     {
         tail.next = other.head;
         tail      = other.tail;
         count    += other.count;
     }
 }
Пример #10
0
        /// <summary>
        /// Traverses the node list that starts with this node, clears the value of each node, and releases the resulting node list to the pool.
        /// </summary>
        public void Dispose()
        {
            var dt = default(T);

            value = dt;

            var runner = this;

            while (runner.next != null)
            {
                runner       = runner.next;
                runner.value = dt;
            }

            lock (poolLock) {
                runner.next = pool;
                pool        = this;
            }
        }
Пример #11
0
        /// <summary>
        /// Returns a pooled list node with the specified value.
        /// </summary>
        public static Linked <T> Borrow(T value)
        {
            Linked <T> node;

            lock (poolLock) {
                if (pool == null)
                {
                    node = new Linked <T>();
                }
                else
                {
                    node      = pool;
                    pool      = pool.next;
                    node.next = null;
                }
            }
            node.value = value;
            return(node);
        }
Пример #12
0
        private static bool DetectResetLoop(Linked <T> head)
        {
            Linked <T> slow = head, prefFast = head, fast = head;

            while (slow != null && fast?.next != null)
            {
                slow     = slow.next;
                prefFast = fast.next;
                fast     = prefFast.next;
                if (slow == fast)
                {
                    // remove loop
                    // prefFast.next = null;
                    Debug.Log("Detect Loop");
                    return(true);
                }
            }
            return(false);
        }
Пример #13
0
        /// <summary>
        ///     Returns a list that starts with the specified node.
        ///     The constructor will traverse the node links to set the tail and count fields.
        ///     If the specified node is null, the resulting list will be empty.
        /// </summary>
        public LinkedHeadTail(Linked <T> head)
        {
            if (head == null)
            {
                this.head = null;
                tail      = null;
                count     = 0;
            }
            else
            {
                this.head = head;
                tail      = head;
                count     = 1;

                while (tail.next != null)
                {
                    tail = tail.next;
                    ++count;
                }
            }
        }
Пример #14
0
        /// <summary>
        ///     Appends the specified node to the end of the list.
        ///     The node links will be traversed to determine the new tail and count.
        ///     If the specified node is null, the list will not be modified.
        /// </summary>
        public void Append(Linked <T> node)
        {
            if (node != null)
            {
                if (head == null)
                {
                    head = node;
                }
                else
                {
                    tail.next = node;
                }
                tail = node;
                ++count;

                while (tail.next != null)
                {
                    tail = tail.next;
                    ++count;
                }
            }
        }
Пример #15
0
 /// <summary>
 ///     Sorts the lookup's keys using the specified comparison and ordering.
 ///     This method uses an introspective merge sort algorithm that will optimally sort rather than split lists with 3 or fewer nodes.
 /// </summary>
 public Lookup <K, T> SortKeys(Comparison <K> comparison, bool ascending)
 {
     keys = Linked.Sort(keys, comparison, ascending);
     return(this);
 }
Пример #16
0
 /// <summary>
 ///     Returns a list containing a single node with the specified value.
 /// </summary>
 public LinkedHeadTail(T value) : this(Linked <T> .Borrow(value))
 {
 }