Пример #1
0
            protected override unsafe void OnExecute(Tangle <T> tangle, out NoneType result)
            {
                result = NoneType.None;

                BTreeValue *pValue;
                ushort      keyType;
                long?       capacity = BytesToCopy.GetValueOrDefault(Input.Length - Input.Position);

                using (var nodeRange = tangle.BTree.LockValue(NodeIndex, ValueIndex, capacity, out pValue, out keyType))
                    using (var dataRange = tangle.BTree.DataStream.AccessRange(pValue->DataOffset, pValue->DataLength + pValue->ExtraDataBytes)) {
                        var stream = new UnmanagedMemoryStream(dataRange.Pointer, 0, dataRange.Size, FileAccess.ReadWrite);

                        if (BufferSize.HasValue)
                        {
                            Input.CopyTo(stream, BufferSize.Value);
                        }
                        else
                        {
                            Input.CopyTo(stream);
                        }

                        stream.Dispose();

                        tangle.BTree.UnlockValue(pValue, keyType);
                        tangle.BTree.UnlockNode(nodeRange);
                    }
            }
Пример #2
0
            protected override void OnExecute(Tangle <T> tangle, out T[] result)
            {
                var keys = Keys;

                var count = GetCountFast(Keys);

                if (!count.HasValue)
                {
                    var array = Keys.ToArray();
                    keys  = array;
                    count = array.Length;
                }

                var results = new T[count.Value];

                Parallel.ForEach(
                    keys, (rawKey, loopState, i) => {
                    T value;
                    if (tangle.InternalGet(KeyConverter(rawKey), out value))
                    {
                        results[i] = value;
                    }
                    else
                    {
                        results[i] = default(T);
                    }
                }
                    );

                result = results;
            }
Пример #3
0
            protected override unsafe void OnExecute(Tangle <T> tangle, out LockedData result)
            {
                BTreeValue *pValue;
                ushort      keyType;

                using (var nodeRange = tangle.BTree.LockValue(NodeIndex, ValueIndex, MinimumSize, out pValue, out keyType))
                    using (var dataRange = tangle.BTree.DataStream.AccessRange(pValue->DataOffset, pValue->DataLength + pValue->ExtraDataBytes)) {
                        result = new LockedData(
                            dataRange.Pointer, pValue->DataLength + pValue->ExtraDataBytes, DisposedSignal
                            );

                        // Complete our future early so that the locked region can be consumed
                        //  while we wait on the disposal signal
                        CompleteEarly(ref result);

                        DisposedSignal.Wait();

                        var oldLength = pValue->DataLength;
                        pValue->DataLength = (uint)MinimumSize.GetValueOrDefault(pValue->DataLength);
                        if (pValue->DataLength > oldLength)
                        {
                            pValue->ExtraDataBytes -= (pValue->DataLength - oldLength);
                        }

                        tangle.BTree.UnlockValue(pValue, keyType);
                        tangle.BTree.UnlockNode(nodeRange);
                    }
            }
Пример #4
0
            protected override unsafe void OnExecute(Tangle <T> tangle, out NoneType result)
            {
                result = NoneType.None;

                BTreeValue *pValue;
                ushort      keyType;

                using (var nodeRange = tangle.BTree.LockValue(NodeIndex, ValueIndex, null, out pValue, out keyType))
                    using (var dataRange = tangle.BTree.DataStream.AccessRange(pValue->DataOffset, pValue->DataLength + pValue->ExtraDataBytes)) {
                        var stream = new UnmanagedMemoryStream(dataRange.Pointer, pValue->DataLength);

                        if (BufferSize.HasValue)
                        {
                            stream.CopyTo(Output, BufferSize.Value);
                        }
                        else
                        {
                            stream.CopyTo(Output);
                        }

                        stream.Dispose();

                        tangle.BTree.UnlockValue(pValue, keyType);
                        tangle.BTree.UnlockNode(nodeRange);
                    }
            }
Пример #5
0
 protected override void OnExecute(Tangle <T> tangle, out FindResult result)
 {
     if (!tangle.InternalFind(Key, out result))
     {
         Fail(new KeyNotFoundException(Key));
     }
 }
Пример #6
0
            public void Execute(Tangle <T> tangle)
            {
                if (!Future.Disposed)
                {
                    try {
                        U result;
                        OnExecute(tangle, out result);

                        if (!Future.Completed)
                        {
                            if (Failure != null)
                            {
                                Future.Fail(Failure);
                            }
                            else
                            {
                                Future.Complete(result);
                            }
                        }
                    } catch (Exception ex) {
                        if (!Future.Disposed && !Future.Completed)
                        {
                            try {
                                Future.Fail(ex);
                            } catch {
                            }
                        }
                    }
                }

                Dispose();
            }
Пример #7
0
            protected override unsafe void OnExecute(Tangle <TValue> tangle, out TValue[] result)
            {
                long nodeIndex;
                uint valueIndex;

                result = null;
                if (Index.BTree.FindKey(Key, false, out nodeIndex, out valueIndex))
                {
                    HashSet <TangleKey> keys;
                    using (var range = Index.BTree.AccessValue(nodeIndex, valueIndex))
                        Index.BTree.ReadData((BTreeValue *)range.Pointer, Index <TIndexKey, TValue> .DeserializeKeys, out keys);

                    result = new TValue[keys.Count];
                    int i = 0;
                    foreach (var key in keys)
                    {
                        tangle.InternalGet(key, out result[i]);
                        i += 1;
                    }
                }
                else
                {
                    Fail(new KeyNotFoundException(Key));
                }
            }
Пример #8
0
            protected override unsafe void OnExecute(Tangle <TValue> tangle, out TValue[] result)
            {
                long nodeIndex;
                uint valueIndex;

                var matchedKeys = new HashSet <TangleKey>();

                foreach (var key in Keys)
                {
                    if (Index.BTree.FindKey(key, false, out nodeIndex, out valueIndex))
                    {
                        HashSet <TangleKey> keys;
                        using (var range = Index.BTree.AccessValue(nodeIndex, valueIndex))
                            Index.BTree.ReadData((BTreeValue *)range.Pointer, Index <TIndexKey, TValue> .DeserializeKeys, out keys);

                        matchedKeys.UnionWith(keys);
                    }
                }

                // Maybe we should throw for missing keys or values?

                var resultArray = new TValue[matchedKeys.Count];

                Parallel.ForEach(matchedKeys, (key, loopState, i) => {
                    tangle.InternalGet(key, out resultArray[i]);
                });

                result = resultArray;
            }
Пример #9
0
            protected override void OnExecute(Tangle <T> tangle, out NoneType result)
            {
                ThunkSignal.Complete();
                OpenSignal.Wait();

                result = NoneType.None;
            }
Пример #10
0
            protected override unsafe void OnExecute(Tangle <TValue> tangle, out TangleKey result)
            {
                long nodeIndex;
                uint valueIndex;

                if (Index.BTree.FindKey(Key, false, out nodeIndex, out valueIndex))
                {
                    HashSet <TangleKey> keys;
                    using (var range = Index.BTree.AccessValue(nodeIndex, valueIndex))
                        Index.BTree.ReadData((BTreeValue *)range.Pointer, Index <TIndexKey, TValue> .DeserializeKeys, out keys);

                    if (keys.Count == 0)
                    {
                        Fail(new KeyNotFoundException(Key));
                        result = default(TangleKey);
                    }
                    else
                    {
                        result = keys.First();
                    }
                }
                else
                {
                    result = default(TangleKey);
                    Fail(new KeyNotFoundException(Key));
                }
            }
Пример #11
0
        protected Index(Tangle <TValue> tangle, string name, Delegate function)
        {
            IndexFunction         = function as IndexFunc <TIndexKey, TValue>;
            IndexMultipleFunction = function as IndexMultipleFunc <TIndexKey, TValue>;

            if ((IndexFunction == null) && (IndexMultipleFunction == null))
            {
                throw new InvalidOperationException("An index must have either an IndexFunc or IndexMultipleFunc");
            }

            Tangle       = tangle;
            Name         = name;
            KeyConverter = TangleKey.GetConverter <TIndexKey>();

            IndexBase <TValue> temp;

            if (tangle.Indices.TryGetValue(name, out temp))
            {
                throw new InvalidOperationException("An index with that name already exists");
            }

            BTree = new BTree(tangle.Storage, Name + "_");

            tangle.Indices.Add(name, this);

            if (tangle.Count != BTree.MutationSentinel)
            {
                Populate();
            }
        }
Пример #12
0
            protected override void OnExecute(Tangle <T> tangle, out NoneType result)
            {
                var keys = Keys;

                var count = GetCountFast(Keys);

                if (!count.HasValue)
                {
                    var array = Keys.ToArray();
                    keys  = array;
                    count = array.Length;
                }

                Parallel.ForEach(
                    keys, (rawKey) => {
                    T value;
                    if (tangle.InternalGet(KeyConverter(rawKey), out value))
                    {
                        Function(rawKey, value);
                    }
                }
                    );

                result = NoneType.None;
            }
Пример #13
0
            protected override void OnExecute(Tangle <T> tangle, out TMapped result)
            {
                var keys = Keys;

                var count = GetCountFast(Keys);

                if (!count.HasValue)
                {
                    var array = Keys.ToArray();
                    keys  = array;
                    count = array.Length;
                }

                Func <TKey, TMapped> adapter = (rawKey) => {
                    T value;
                    if (tangle.InternalGet(KeyConverter(rawKey), out value))
                    {
                        return(Map(rawKey, value));
                    }

                    return(DefaultValue);
                };

                result =
                    (from k in keys.AsParallel().AsOrdered() select adapter(k))
                    .Aggregate(InitialValue, Reduce);
            }
Пример #14
0
 internal FindResult(Tangle <T> owner, TangleKey key, long nodeIndex, uint valueIndex)
 {
     Tangle     = owner;
     Key        = key;
     Version    = owner.Version;
     NodeIndex  = nodeIndex;
     ValueIndex = valueIndex;
 }
Пример #15
0
 /// <summary>
 /// Reads multiple values from the tangle, looking them up based on a provided sequence of keys,
 ///  and then uses those values to perform a lookup within a second tangle.
 /// </summary>
 /// <param name="keys">The keys to look up in this tangle.</param>
 /// <param name="right">The tangle to join against.</param>
 /// <param name="keySelector">A delegate that takes a value from this tangle and produces a key to use for a lookup in the other tangle.</param>
 /// <returns>A future that will contain the join results.</returns>
 public Future <KeyValuePair <T, TRight>[]> Join <TLeftKey, TRightKey, TRight> (
     Tangle <TRight> right, IEnumerable <TLeftKey> keys,
     Func <T, TRightKey> keySelector
     )
 {
     return(Join(
                right, keys,
                (TLeftKey leftKey, ref T leftValue)
                => keySelector(leftValue),
                (TLeftKey leftKey, ref T leftValue, TRightKey rightKey, ref TRight rightValue)
                => new KeyValuePair <T, TRight>(leftValue, rightValue)
                ));
 }
Пример #16
0
            protected override void OnExecute(Tangle <T> tangle, out T[] result)
            {
                var keys = Keys;

                var count = GetCountFast(Keys);

                if (!count.HasValue)
                {
                    var array = Keys.ToArray();
                    keys  = array;
                    count = array.Length;
                }

                var results = new T[count.Value];

                foreach (var barrier in Barriers)
                {
                    barrier.ReadyForJoinSignal.Wait();
                }

                Parallel.ForEach(
                    keys, (rawKey, loopState, i) => {
                    T value;
                    var key = KeyConverter(rawKey);

                    results[i] = default(T);
                    if (tangle.InternalGet(key, out value))
                    {
                        results[i] = value;
                    }
                    else
                    {
                        foreach (var cascade in Cascades)
                        {
                            if (cascade.InternalGet(key, out value))
                            {
                                results[i] = value;
                                break;
                            }
                        }
                    }
                }
                    );

                result = results;

                foreach (var barrier in Barriers)
                {
                    barrier.JoinCompleteSignal.Set();
                }
            }
Пример #17
0
            bool IReplaceCallback <T> .ShouldReplace(Tangle <T> tangle, ref BTreeValue btreeValue, ushort keyType, ref T newValue)
            {
                T oldValue;

                tangle.ReadData(ref btreeValue, keyType, out oldValue);

                if (Callback != null)
                {
                    newValue = Callback(oldValue);
                    return(true);
                }
                else
                {
                    return(DecisionCallback(ref oldValue, ref newValue));
                }
            }
Пример #18
0
 public JoinThunk(
     Tangle <TRight> .JoinBarrierThunk rightBarrier,
     Tangle <TRight> right,
     IEnumerable <TLeftKey> keys,
     JoinKeySelector <TLeftKey, T, TRightKey> keySelector,
     JoinValueSelector <TLeftKey, T, TRightKey, TRight, TOut> valueSelector
     )
 {
     RightBarrier      = rightBarrier;
     Right             = right;
     Keys              = keys;
     KeySelector       = keySelector;
     ValueSelector     = valueSelector;
     LeftKeyConverter  = TangleKey.GetConverter <TLeftKey>();
     RightKeyConverter = TangleKey.GetConverter <TRightKey>();
 }
Пример #19
0
            protected override void OnExecute(Tangle <T> tangle, out TOut[] result)
            {
                var keys = Keys;

                var count = GetCountFast(Keys);

                if (!count.HasValue)
                {
                    var array = Keys.ToArray();
                    keys  = array;
                    count = array.Length;
                }

                var results = new TOut[count.Value];

                if (RightBarrier != null)
                {
                    RightBarrier.ReadyForJoinSignal.Wait();
                }

                Parallel.ForEach(
                    keys, (leftKey, loopState, i) => {
                    T leftValue;
                    TRight rightValue;

                    if (!tangle.InternalGet(LeftKeyConverter(leftKey), out leftValue))
                    {
                        return;
                    }

                    var rightKey = KeySelector(leftKey, ref leftValue);
                    if (!Right.InternalGet(RightKeyConverter(rightKey), out rightValue))
                    {
                        return;
                    }

                    results[i] = ValueSelector(leftKey, ref leftValue, rightKey, ref rightValue);
                }
                    );

                result = results;

                if (RightBarrier != null)
                {
                    RightBarrier.JoinCompleteSignal.Set();
                }
            }
Пример #20
0
            protected override void OnExecute(Tangle <T> tangle, out int result)
            {
                result = 0;

                var items = Batch.Buffer;

                for (int i = 0, c = Batch.Count; i < c; i++)
                {
                    ShouldReplace    = items[i].AllowReplacement;
                    Callback         = items[i].Callback;
                    DecisionCallback = items[i].DecisionCallback;
                    if (tangle.InternalSet(items[i].Key, ref items[i].Value, this))
                    {
                        result += 1;
                    }
                }
            }
Пример #21
0
        /// <summary>
        /// Reads multiple values from the tangle, looking them up based on a provided sequence of keys,
        ///  and then uses those values to perform a lookup within a second tangle.
        /// </summary>
        /// <param name="keys">The keys to look up in this tangle.</param>
        /// <param name="right">The tangle to join against.</param>
        /// <param name="keySelector">A delegate that takes a key/value pair from this tangle and produces a key to use for a lookup in the other tangle.</param>
        /// <param name="valueSelector">A delegate that takes key/value pairs from both tangles and produces a result for the join.</param>
        /// <returns>A future that will contain the join results.</returns>
        public Future <TOut[]> Join <TLeftKey, TRightKey, TRight, TOut> (
            Tangle <TRight> right, IEnumerable <TLeftKey> keys,
            JoinKeySelector <TLeftKey, T, TRightKey> keySelector,
            JoinValueSelector <TLeftKey, T, TRightKey, TRight, TOut> valueSelector
            )
        {
            Tangle <TRight> .JoinBarrierThunk rightBarrier = null;
            if (!Object.Equals(right, this))
            {
                rightBarrier = new Tangle <TRight> .JoinBarrierThunk();

                right.QueueWorkItem(rightBarrier);
            }

            return(QueueWorkItem(new JoinThunk <TLeftKey, TRightKey, TRight, TOut>(
                                     rightBarrier, right, keys, keySelector, valueSelector
                                     )));
        }
Пример #22
0
            protected override void OnExecute(Tangle <T> tangle, out TangleKey[] result)
            {
                var nodeCount = tangle.BTree.NodeCount;
                var count     = tangle.Count;
                int position  = 0;

                result = new TangleKey[count];

                for (int node = 0; node < nodeCount; node++)
                {
                    position += tangle.BTree.GetNodeKeys(node, result, position);
                }

                if (position != count)
                {
                    throw new InvalidDataException();
                }
            }
Пример #23
0
        /// <summary>
        /// Reads multiple values from the tangle, looking them up based on a provided sequence of keys.
        /// If a provided key is not found in this tangle, each of the tangles in the sequence of cascades is tried.
        /// </summary>
        /// <param name="keys">The keys to look up in this tangle.</param>
        /// <param name="cascades">The tangles to search if this tangle does not contain a key.</param>
        /// <returns>A future that will contain the retrieved values.</returns>
        public Future <T[]> CascadingSelect <TKey> (IEnumerable <Tangle <T> > cascades, IEnumerable <TKey> keys)
        {
            var seen     = new HashSet <Tangle <T> >();
            var barriers = new List <Tangle <T> .JoinBarrierThunk>();

            foreach (var tangle in cascades)
            {
                if (Object.Equals(tangle, this) || seen.Contains(tangle))
                {
                    throw new InvalidOperationException("Cannot cascade a tangle with itself");
                }

                var barrier = new Tangle <T> .JoinBarrierThunk();

                tangle.QueueWorkItem(barrier);
                barriers.Add(barrier);
                seen.Add(tangle);
            }

            return(QueueWorkItem(new CascadingGetMultipleThunk <TKey>(barriers, cascades, keys)));
        }
Пример #24
0
            protected override unsafe void OnExecute(Tangle <TValue> tangle, out TangleKey[] result)
            {
                long nodeIndex;
                uint valueIndex;

                var resultSet = new HashSet <TangleKey>();

                foreach (var key in Keys)
                {
                    if (Index.BTree.FindKey(key, false, out nodeIndex, out valueIndex))
                    {
                        HashSet <TangleKey> keys;
                        using (var range = Index.BTree.AccessValue(nodeIndex, valueIndex))
                            Index.BTree.ReadData((BTreeValue *)range.Pointer, Index <TIndexKey, TValue> .DeserializeKeys, out keys);

                        resultSet.UnionWith(keys);
                    }
                }

                // Maybe we should throw for missing keys?

                result = resultSet.ToArray();
            }
Пример #25
0
 public static Future <Index <TIndexKey, TValue> > Create(Tangle <TValue> tangle, string name, IndexMultipleFunc <TIndexKey, TValue> function)
 {
     return(tangle.QueueWorkItem(new CreateThunk(name, function)));
 }
Пример #26
0
 /// <summary>
 /// Creates a batch.
 /// </summary>
 /// <param name="tangle">The tangle against which to issue the batch's commands.</param>
 /// <param name="capacity">The maximum number of modifications that the batch can contain.</param>
 public Batch(Tangle <T> tangle, int capacity)
 {
     Tangle   = tangle;
     Capacity = capacity;
     Buffer   = new BatchItem <T> [capacity];
 }
Пример #27
0
 protected override void OnExecute(Tangle <TValue> tangle, out Index <TIndexKey, TValue> result)
 {
     result = new Index <TIndexKey, TValue>(tangle, Name, Function);
 }
Пример #28
0
 internal Barrier(Tangle <T> tangle, bool opened)
 {
     OpenSignal  = new ManualResetEventSlim(opened);
     ThunkSignal = tangle.QueueWorkItem(this);
 }
Пример #29
0
 protected override void OnExecute(Tangle <T> tangle, out NoneType result)
 {
     tangle.InternalSetFoundValue(NodeIndex, ValueIndex, ref Value);
     result = NoneType.None;
 }
Пример #30
0
 protected override void OnExecute(Tangle <T> tangle, out T result)
 {
     tangle.InternalGetFoundValue(NodeIndex, ValueIndex, out result);
 }