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); } }
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; }
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); } }
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); } }
protected override void OnExecute(Tangle <T> tangle, out FindResult result) { if (!tangle.InternalFind(Key, out result)) { Fail(new KeyNotFoundException(Key)); } }
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(); }
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)); } }
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; }
protected override void OnExecute(Tangle <T> tangle, out NoneType result) { ThunkSignal.Complete(); OpenSignal.Wait(); result = NoneType.None; }
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)); } }
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(); } }
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; }
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); }
internal FindResult(Tangle <T> owner, TangleKey key, long nodeIndex, uint valueIndex) { Tangle = owner; Key = key; Version = owner.Version; NodeIndex = nodeIndex; ValueIndex = valueIndex; }
/// <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) )); }
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(); } }
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)); } }
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>(); }
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(); } }
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; } } }
/// <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 ))); }
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(); } }
/// <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))); }
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(); }
public static Future <Index <TIndexKey, TValue> > Create(Tangle <TValue> tangle, string name, IndexMultipleFunc <TIndexKey, TValue> function) { return(tangle.QueueWorkItem(new CreateThunk(name, function))); }
/// <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]; }
protected override void OnExecute(Tangle <TValue> tangle, out Index <TIndexKey, TValue> result) { result = new Index <TIndexKey, TValue>(tangle, Name, Function); }
internal Barrier(Tangle <T> tangle, bool opened) { OpenSignal = new ManualResetEventSlim(opened); ThunkSignal = tangle.QueueWorkItem(this); }
protected override void OnExecute(Tangle <T> tangle, out NoneType result) { tangle.InternalSetFoundValue(NodeIndex, ValueIndex, ref Value); result = NoneType.None; }
protected override void OnExecute(Tangle <T> tangle, out T result) { tangle.InternalGetFoundValue(NodeIndex, ValueIndex, out result); }