コード例 #1
0
 public UpdateThunk(TangleKey key, ref T value, DecisionUpdateCallback <T> callback)
 {
     Key              = key;
     Value            = value;
     Callback         = null;
     DecisionCallback = callback;
 }
コード例 #2
0
 public CascadingGetMultipleThunk(IEnumerable <Tangle <T> .JoinBarrierThunk> barriers, IEnumerable <Tangle <T> > cascades, IEnumerable <TKey> keys)
 {
     Barriers     = barriers;
     Cascades     = cascades;
     Keys         = keys;
     KeyConverter = TangleKey.GetConverter <TKey>();
 }
コード例 #3
0
ファイル: Tangle.cs プロジェクト: sq/DataMangler
 internal FindResult(Tangle <T> owner, TangleKey key, long nodeIndex, uint valueIndex)
 {
     Tangle     = owner;
     Key        = key;
     Version    = owner.Version;
     NodeIndex  = nodeIndex;
     ValueIndex = valueIndex;
 }
コード例 #4
0
ファイル: Tangle.cs プロジェクト: sq/DataMangler
        private bool InternalFind(TangleKey key, out FindResult result)
        {
            long nodeIndex;
            uint valueIndex;

            if (!BTree.FindKey(key, false, out nodeIndex, out valueIndex))
            {
                result = default(FindResult);
                return(false);
            }

            result = new FindResult(this, key, nodeIndex, valueIndex);
            return(true);
        }
コード例 #5
0
ファイル: Tangle.cs プロジェクト: sq/DataMangler
        internal bool InternalGet(TangleKey key, out T value)
        {
            long nodeIndex;
            uint valueIndex;

            if (!BTree.FindKey(key, false, out nodeIndex, out valueIndex))
            {
                value = default(T);
                return(false);
            }

            using (var range = BTree.AccessValue(nodeIndex, valueIndex)) {
                var pEntry = (BTreeValue *)range.Pointer;
                BTree.ReadData(ref *pEntry, Deserializer, out value);
            }

            return(true);
        }
コード例 #6
0
 public ForEachThunk(IEnumerable <TKey> keys, Action <TKey, T> function)
 {
     Keys         = keys;
     KeyConverter = TangleKey.GetConverter <TKey>();
     Function     = function;
 }
コード例 #7
0
 public GetMultipleThunk(IEnumerable <TKey> keys)
 {
     Keys         = keys;
     KeyConverter = TangleKey.GetConverter <TKey>();
 }
コード例 #8
0
 public GetThunk(TangleKey key)
 {
     Key = key;
 }
コード例 #9
0
 public SetThunk(TangleKey key, ref T value, bool shouldReplace)
 {
     Key           = key;
     Value         = value;
     ShouldReplace = shouldReplace;
 }
コード例 #10
0
ファイル: Tangle.cs プロジェクト: sq/DataMangler
        private bool InternalSet(TangleKey key, ref T value, IReplaceCallback <T> replacementCallback)
        {
            unchecked { _Version++; }

            long nodeIndex;
            uint valueIndex;

            Exception serializerException = null;
            bool      foundExisting       = BTree.FindKey(key, true, out nodeIndex, out valueIndex);

            StreamRange range;

            if (foundExisting)
            {
                range = BTree.AccessNode(nodeIndex, true);
            }
            else
            {
                // Prepare BTree for insert. Note that once we have done this, we must successfully insert or
                //  the index will be left in an invalid state!
                range = BTree.PrepareForInsert(nodeIndex, valueIndex);
            }

            using (range) {
                var pEntry = BTree.LockValue(range, valueIndex, foundExisting ? key.OriginalTypeId : (ushort)0);

                if (foundExisting)
                {
                    bool shouldContinue = replacementCallback.ShouldReplace(this, ref *pEntry, key.OriginalTypeId, ref value);

                    if (!shouldContinue)
                    {
                        BTree.UnlockValue(pEntry, key.OriginalTypeId);
                        BTree.UnlockNode(range);
                        return(false);
                    }
                }
                else
                {
                    BTree.WriteNewKey(pEntry, key);
                }

                // It is very important that the entry be properly initialized at this point.
                // Serializers can request the key of the value being serialized, in which case the
                //  SerializationContext will attempt to read information from the IndexEntry.
                // Note that since a KeyType of 0 is used to indicate that an entry is being modified,
                //  we pass the actual KeyType to the serializer.

                ArraySegment <byte> segment = default(ArraySegment <byte>);
                try {
                    segment = BTree.Serialize(pEntry, Serializer, key.OriginalTypeId, ref value);
                } catch (Exception ex) {
                    serializerException = ex;
                }

                if ((Indices.Count > 0) && foundExisting)
                {
                    T oldValue;
                    ReadData(ref *pEntry, key.OriginalTypeId, out oldValue);

                    foreach (var index in Indices.Values)
                    {
                        index.OnValueRemoved(key, ref oldValue);
                    }
                }

                BTree.WriteData(pEntry, segment);

                BTree.UnlockValue(pEntry, key.OriginalTypeId);

                if (foundExisting)
                {
                    BTree.UnlockNode(range);
                }
                else
                {
                    BTree.FinalizeInsert(range);
                }
            }

            foreach (var index in Indices.Values)
            {
                index.OnValueAdded(key, ref value);
            }

            // If the user's serializer throws, we wait until now to rethrow the exception so that
            //  we do not leave the index in an invalid state (in the case of a BTree insert).
            if (serializerException != null)
            {
                throw new SerializerThrewException(key, serializerException);
            }

            return(true);
        }