Esempio n. 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);
                }
            }
        }
Esempio n. 2
0
        public void EvalPage(RCRunner runner, RCClosure closure, RCSymbol symbol, RCLong right)
        {
            int pageNumber = 0;

            if (right.Count > 0)
            {
                pageNumber = (int)right[0];
            }
            int pageSize = int.MaxValue;

            if (right.Count > 1)
            {
                pageSize = (int)right[1];
            }

            // Page lets you access the blackboard by page number and page size, rather than row
            // numbers.
            // Good for building tools for looking at blackboard contents.
            lock (_readWriteLock)
            {
                Section  s         = GetSection(symbol);
                int      skipFirst = pageNumber * pageSize;
                int      stopAfter = pageSize;
                ReadSpec spec      = new ReadSpec(s._counter, symbol, skipFirst, stopAfter, false);
                RCCube   result    = s._blackboard.Read(spec, s._counter, true, s._blackboard.Count);
                runner.Yield(closure, result);
            }
        }
Esempio n. 3
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);
                }
            }
        }
Esempio n. 4
0
        public void EvalSelect(RCRunner runner, RCClosure closure, RCSymbol left, RCCube right)
        {
            RCLong      args    = new RCLong(0, 0);
            ReadCounter counter = new ReadCounter(right);
            ReadSpec    spec    = new ReadSpec(counter, left, args, 0, false, false, true, false);
            RCCube      result  = right.Read(spec, counter, true, right.Count);

            runner.Yield(closure, result);
        }
Esempio n. 5
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);
             }
         }
     }
 }
Esempio n. 6
0
 public void EvalPoll(RCRunner runner, RCClosure closure, RCSymbol symbol, RCLong starts)
 {
     // Poll is like read but it will never block.
     lock (_readWriteLock)
     {
         Section  s      = GetSection(symbol);
         ReadSpec spec   = s._counter.GetReadSpec(symbol, starts, false, true);
         RCCube   result = s._blackboard.Read(spec, s._counter, true, s._blackboard.Count);
         runner.Yield(closure, result);
     }
 }
Esempio n. 7
0
 public void EvalSnap(RCRunner runner, RCClosure closure, RCSymbol left, RCLong right)
 {
     // With snap, the read instructions apply to each symbol in a family of symbols.
     // Not only to the symbol explcitly noted in the left argument.
     lock (_readWriteLock)
     {
         Section s = GetSection(left);
         // This line with the ConcreteSymbols should be added to other operators
         // RCSymbol concretes = s._counter.ConcreteSymbols (left, false);
         ReadSpec spec = new ReadSpec(s._counter, left, right, -1, false, false, true, false);
         // RCCube result = s._blackboard.Read (spec, s._counter, true,
         // s._blackboard.Count);
         RCCube result = s._blackboard.Read(spec, s._counter, true, s._blackboard.Count);
         runner.Yield(closure, result);
     }
 }
Esempio n. 8
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));
                }
            }
        }
Esempio n. 9
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);
                }
            }
        }