Package net.fortytwo.ripple.libs.stream

Source Code of net.fortytwo.ripple.libs.stream.Intersect$IntersectInner

package net.fortytwo.ripple.libs.stream;

import net.fortytwo.flow.Sink;
import net.fortytwo.ripple.ListMemoizer;
import net.fortytwo.ripple.RippleException;
import net.fortytwo.ripple.model.ModelConnection;
import net.fortytwo.ripple.model.NullStackMapping;
import net.fortytwo.ripple.model.Operator;
import net.fortytwo.ripple.model.PrimitiveStackMapping;
import net.fortytwo.ripple.model.RippleList;
import net.fortytwo.ripple.model.RippleValue;
import net.fortytwo.ripple.model.StackMapping;


/**
* A filter which drops any stack which has already been transmitted and behaves
* like the identity filter otherwise, making a stream of stacks into a set of
* stacks.
*
* @author Joshua Shinavier (http://fortytwo.net)
*/
public class Intersect extends PrimitiveStackMapping {
    private static final String MEMO = "memo";

    private static final String[] IDENTIFIERS = {
            StreamLibrary.NS_2013_03 + "intersect",
            StreamLibrary.NS_2008_08 + "intersect"};

    public String[] getIdentifiers() {
        return IDENTIFIERS;
    }

    public Intersect() throws RippleException {
        super();
    }

    public Parameter[] getParameters() {
        return new Parameter[]{
                new Parameter("r1", null, true),
                new Parameter("r2", null, true)};
    }

    public String getComment() {
        return "r1 r2 => applied intersection of relations r1 and r2";
    }

    public void apply(final RippleList arg,
                      final Sink<RippleList> solutions,
                      final ModelConnection mc) throws RippleException {
        RippleList stack = arg;

        RippleValue rtrue = stack.getFirst();
        stack = stack.getRest();
        RippleValue rfalse = stack.getFirst();
        stack = stack.getRest();

        Operator inner = new Operator(new IntersectInner());
        solutions.put(
                stack.push(rtrue).push(Operator.OP).push(mc.valueOf(true)).push(inner));
        solutions.put(
                stack.push(rfalse).push(Operator.OP).push(mc.valueOf(false)).push(inner));
    }

    protected class IntersectInner implements StackMapping {
        private ListMemoizer<RippleValue, String> trueMemoizer = null;
        private ListMemoizer<RippleValue, String> falseMemoizer = null;

        public int arity() {
            // Require that the remainder of the stack (below the marker) is
            // in normal form.  This is somewhat arbitrary.
            return 2;
        }

        public void apply(final RippleList arg,
                          final Sink<RippleList> solutions,
                          final ModelConnection mc) throws RippleException {
            RippleValue marker = arg.getFirst();

            if (mc.toBoolean(marker)) {
                applyTrue(arg, solutions, mc);
            } else {
                applyFalse(arg, solutions, mc);
            }
        }

        private void applyTrue(final RippleList arg,
                               final Sink<RippleList> sink,
                               final ModelConnection mc) throws RippleException {
            RippleList stack = arg.getRest();

            if (null == trueMemoizer) {
                trueMemoizer = new ListMemoizer<RippleValue, String>(mc.getComparator());
            }

            trueMemoizer.put(stack, MEMO);

            if (null != falseMemoizer && null != falseMemoizer.get(stack)) {
                sink.put(stack);
            }
        }

        private void applyFalse(final RippleList arg,
                                final Sink<RippleList> sink,
                                final ModelConnection mc) throws RippleException {
            RippleList stack = arg.getRest();

            if (null == falseMemoizer) {
                falseMemoizer = new ListMemoizer<RippleValue, String>(mc.getComparator());
            }

            falseMemoizer.put(stack, MEMO);

            if (null != trueMemoizer && null != trueMemoizer.get(stack)) {
                sink.put(stack);
            }
        }

        public boolean isTransparent() {
            return true;
        }

        // TODO
        public StackMapping getInverse() throws RippleException {
            return new NullStackMapping();
        }
    }
}
TOP

Related Classes of net.fortytwo.ripple.libs.stream.Intersect$IntersectInner

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.