public void EvalGawk(RCRunner runner, RCClosure closure, RCSymbol symbol, RCLong right) { int limit = (int)right[0]; lock (_readWriteLock) { Section s = GetSection(symbol); ReadSpec spec = s._counter.GetReadSpec(symbol, limit, false, true); Satisfy canSatisfy = s._counter.CanSatisfy(spec); RCCube result = s._blackboard.Read(spec, s._counter, true, s._blackboard.Count); if ((spec.SymbolUnlimited && result.Count > 0) || (!spec.SymbolUnlimited && result.Count >= symbol.Count * Math.Abs(spec.SymbolLimit))) { if (canSatisfy != Satisfy.Yes) { throw new Exception(); } runner.Yield(closure, result); } else { if (canSatisfy != Satisfy.No) { throw new Exception(); } s._dispatchWaiters.Enqueue(symbol, closure); } } }
public void EvalPeek(RCRunner runner, RCClosure closure, RCSymbol left, RCLong right) { int limit = (int)right[0]; lock (_readWriteLock) { Section s = GetSection(left); ReadSpec spec = s._counter.GetReadSpec(left, limit, false, true); Satisfy canSatisfy = s._counter.CanSatisfy(spec); RCCube result = s._blackboard.Read(spec, s._counter, true, s._blackboard.Count); if ((spec.SymbolUnlimited && result.Count > 0) || (!spec.SymbolUnlimited && result.Count >= left.Count * Math.Abs(spec.SymbolLimit))) { // If dispatch would yield, return lines. if (canSatisfy != Satisfy.Yes) { throw new Exception(); } runner.Yield(closure, RCBoolean.True); } else { if (canSatisfy != Satisfy.No) { throw new Exception(); } runner.Yield(closure, RCBoolean.False); } } }
public void Read(RCRunner runner, RCClosure closure, RCSymbol symbol, ReadSpec spec) { lock (_readWriteLock) { // Make abstract symbols concrete Section section = GetSection(symbol); Satisfy canSatisfy = section._counter.CanSatisfy(spec); RCCube result = section._blackboard.Read(spec, section._counter, true, section._blackboard.Count); if (spec.SymbolUnlimited) { if (result.Count > 0) { // Notice the canSatisfy constraints here are less strict. // If the start point is greater than zero then we have to // do the full read and then just see if there were enough // rows to satisfy the constraints. if (canSatisfy == Satisfy.No) { throw new Exception(); } runner.Yield(closure, result); } else { if (canSatisfy == Satisfy.Yes) { throw new Exception(); } section._readWaiters.Enqueue(symbol, closure); } } else { if (result.Count >= symbol.Count * Math.Abs(spec.SymbolLimit)) { if (canSatisfy == Satisfy.No) { throw new Exception(); } runner.Yield(closure, result); } else { if (canSatisfy == Satisfy.Yes) { throw new Exception(); } section._readWaiters.Enqueue(symbol, closure); } } } }
public static T Find <T>(T[] items, Satisfy <T> standard) { foreach (T item in items) { if (standard(item)) { return(item); } } return(default(T)); }
protected internal P <TInput, TValue> Satisfy <TValue>(Predicate <TInput> pred, TValue result) { return(input => { var consumed = Satisfy(pred)(input); if (consumed.ParseResult.Succeeded) { return new Consumed <TInput, TValue>( consumed.HasConsumedInput, new ParseResult <TInput, TValue>( result, consumed.ParseResult.RemainingInput)); } else { return new Consumed <TInput, TValue>( false, new ParseResult <TInput, TValue>( consumed.ParseResult.ErrorInfo)); } }); }
public void EvalThrottle(RCRunner runner, RCClosure closure, RCSymbol symbol, RCLong right) { int limit = (int)right[0]; lock (_readWriteLock) { Section s = GetSection(symbol); ReadSpec spec = s._counter.GetReadSpec(symbol, limit, false, true); Satisfy canSatisfy = s._counter.CanSatisfy(spec); RCCube result = s._blackboard.Read(spec, s._counter, true, s._blackboard.Count); if ((spec.SymbolUnlimited && result.Count > 0) || (!spec.SymbolUnlimited && result.Count >= symbol.Count * Math.Abs(spec.SymbolLimit))) { // If dispatch would yield, suspend. if (canSatisfy != Satisfy.Yes) { throw new Exception(); } s._throttleWaiters.Enqueue(symbol, closure); } else { // Return the count of the result set for now. // wny not just return the whole thing? // Because I want to write a version of this that can // know, in near constant time whether dispatch would yield, // without actually producing a result set. // That method can be used by dispatch, peek, and throttle. // So keep the interface locked down. if (canSatisfy != Satisfy.No) { throw new Exception(); } runner.Yield(closure, new RCLong(result.Lines)); } } }
public void EvalDispatch(RCRunner runner, RCClosure closure, RCSymbol symbol, RCLong right) { int limit = (int)right[0]; lock (_readWriteLock) { Section s = GetSection(symbol); ReadSpec spec = s._counter.GetReadSpec(symbol, limit, false, true); Satisfy canSatisfy = s._counter.CanSatisfy(spec); RCCube result = s._blackboard.Read(spec, s._counter, true, s._blackboard.Count); if ((spec.SymbolUnlimited && result.Count > 0) || (!spec.SymbolUnlimited && result.Count >= symbol.Count * Math.Abs(spec.SymbolLimit))) { if (canSatisfy != Satisfy.Yes) { throw new Exception(); } s._counter.Dispatch(s._blackboard, result.AcceptedLines); runner.Yield(closure, result); Dictionary <long, RCClosure> throttlers = null; s._throttleWaiters.GetReadersForSymbol(ref throttlers, result.AcceptedSymbols); ContinueWaiters(runner, throttlers); } else { if (canSatisfy != Satisfy.No) { throw new Exception(); } s._dispatchWaiters.Enqueue(symbol, closure); } } }