示例#1
0
        private ulong?NextLabelRelativeToBase(LinkedListNode <OrderingNode> record)
        {
            var next = record.GetNextCircular();

            if (next == BaseRecord)
            {
                return(null);                   // return M
            }
            else
            {
                return(LabelRelativeToBase(next));
            }
        }
示例#2
0
        private void InsertAfter(T newElement, LinkedListNode <OrderingNode> afterNode)
        {
            if (newElement == null)
            {
                throw new ArgumentNullException("newElement", "Collection does not support null entries.");
            }
            // Find the starting point for our possible relabeling.

            //afterNode can't currently be null - as long as BaseRecord exists.

            ++Insertions;

            ulong j = 1UL;
            LinkedListNode <OrderingNode> current = afterNode.GetNextCircular();

            ///string debugInfo1 = $"Comparing labels relative to {afterNode.Value.Label}";
            //string debugInfo2 = "";

            while (LabelDistance(afterNode, current) != null && LabelDistance(afterNode, current).Value <= j * j)
            {
                //debugInfo2 += $"Label diff {LabelDistance(afterNode, current).Value} <= {j}*{j}   ({j * j})\r\n";
                ++j;
                current = current.GetNextCircular();
            }


            // NEXT:

            //status:  just changed this finalLabel to handle the M case.
            //next is to correct the handling of the finalLabel.Value * k / j part.
            //this can be done easily,I think, because ulong_max fits into decimal.
            //

            ulong?finalLabel = LabelDistance(afterNode, current);

            Relabelings += (int)(j - 1);

            // Now, relabel (j-1) records:
            current = afterNode.GetNextCircular();
            for (ulong k = 1UL; k < j; ++k)
            {
                ulong relabel;
                if (finalLabel == null)
                {
                    //relabel = GetPortionOfM((double)k)
                    unchecked
                    {
                        relabel = (GetFractionOfM(k, j) + afterNode.Value.Label);
                    }
                }
                else
                {
                    unchecked
                    {
                        //relabel = MOD_M(finalLabel.Value * k / j + afterNode.Value.Label);
                        relabel = (GetFraction(finalLabel.Value, k, j) + afterNode.Value.Label);
                    }
                }
                //string debugInfo3 = $"Relabeling {current.Value.Label} to {relabel}";
                current.Value.Label = relabel;
                current             = current.GetNextCircular();
            }

            // Insert the new element:
            const ulong halfM = 1UL << 63; // 2^63, half of 2^64
                                           //const ulong halfM = M / 2; //todo, replace after testing

            ulong newLabelRelativeToBase;

            if (NextLabelRelativeToBase(afterNode) == null)
            {
                // Averaging with M, so use halfM:
                newLabelRelativeToBase = (LabelRelativeToBase(afterNode) / 2UL) + halfM;
            }
            else
            {
                // Carefully avoid off-by-one errors here...
                newLabelRelativeToBase = (NextLabelRelativeToBase(afterNode).Value - LabelRelativeToBase(afterNode)) / 2UL
                                         + LabelRelativeToBase(afterNode);
            }
            ulong newLabel;

            unchecked
            {
                newLabel = (newLabelRelativeToBase + BaseRecord.Value.Label);
            }
            var newNode = new LinkedListNode <OrderingNode>(new OrderingNode(newElement, newLabel));

            list.AddAfter(afterNode, newNode);
            dict[newElement] = newNode;



            // If afterNode is null, we're inserting at the start of the list, and startLabel will be 0:
            //ulong startLabel = afterNode?.Value.Label ?? 0L;
        }