Exemple #1
0
        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);
                }
            }
        }
Exemple #2
0
        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);
                }
            }
        }
Exemple #3
0
 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);
             }
         }
     }
 }
Exemple #4
0
 public static T Find <T>(T[] items, Satisfy <T> standard)
 {
     foreach (T item in items)
     {
         if (standard(item))
         {
             return(item);
         }
     }
     return(default(T));
 }
Exemple #5
0
        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));
                }
            });
        }
Exemple #6
0
        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));
                }
            }
        }
Exemple #7
0
        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);
                }
            }
        }