Exemplo n.º 1
0
            public Branch SetMutate(IEqualityComparer <TKey> equalityComparer,
                                    int hash, int level, TKey key, TValue value, Builder.State builderState, out bool added, out bool mutated)
            {
                uint bitmask = GetBitMask(hash);

                if ((BitMaskBranches & bitmask) != 0)
                {
                    var branchIndex = PopCount(BitMaskBranches & (bitmask - 1));
                    var branch      = Branches[branchIndex];
                    var newBranch   = branch.SetMutate(equalityComparer,
                                                       hash >> 5, level + BitWidth, key, value, builderState, out added, out var newBranchMutated);

                    if (builderState.IsFrozen(OwnerToken))
                    {
                        mutated = false;
                        return(new Branch(builderState.OwnerToken, BitMaskValues, BitMaskBranches, Values,
                                          SetItem(Branches, branchIndex, newBranch)));
                    }

                    mutated = true;
                    if (!newBranchMutated)
                    {
                        Branches[branchIndex] = newBranch;
                    }

                    return(this);
                }

                var valueIndex = PopCount(BitMaskValues & (bitmask - 1));

                if ((BitMaskValues & bitmask) != 0)
                {
                    var node = Values[valueIndex];

                    if (equalityComparer.Equals(node.Key, key))
                    {
                        added = false;
                        if (builderState.IsFrozen(OwnerToken))
                        {
                            mutated = false;
                            return(new Branch(builderState.OwnerToken, BitMaskValues, BitMaskBranches,
                                              SetItem(Values, valueIndex, new ValueNode(key, value)), Branches));
                        }

                        mutated            = true;
                        Values[valueIndex] = new ValueNode(key, value);
                        return(this);
                    }

                    var branchIndex = PopCount(BitMaskBranches & (bitmask - 1));
                    var branch      = CreateFrom(equalityComparer, node, level + BitWidth, hash >> 5, key, value, builderState.OwnerToken);
                    added = true;

                    if (builderState.IsFrozen(OwnerToken))
                    {
                        mutated = false;
                        return(new Branch(builderState.OwnerToken, BitMaskValues & (~bitmask), BitMaskBranches | bitmask,
                                          RemoveAt(Values, valueIndex), Insert(Branches, branchIndex, branch)));
                    }

                    mutated          = true;
                    BitMaskValues   &= ~bitmask;
                    BitMaskBranches |= bitmask;
                    Values           = BuilderRemoveAt(Values, valueIndex, builderState.Values);
                    Branches         = BuilderInsert(Branches, branchIndex, branch, builderState.Branches);
                    return(this);
                }

                added = true;
                if (builderState.IsFrozen(OwnerToken))
                {
                    mutated = false;
                    return(new Branch(builderState.OwnerToken, BitMaskValues | bitmask, BitMaskBranches,
                                      Insert(Values, valueIndex, new ValueNode(key, value)), Branches));
                }

                mutated        = true;
                BitMaskValues |= bitmask;
                Values         = BuilderInsert(Values, valueIndex, new ValueNode(key, value), builderState.Values);
                return(this);
            }