@Override public DataBag exec(Tuple input) throws ExecException, FrontendException { if (input == null) { return null; } Iterable<Pair<Integer, Double>> vector = elgen.apply(input); List<Tuple> result = new ArrayList<Tuple>(N); for (Pair<Integer, Double> el : ordering.greatestOf(vector, N)) { result.add(tfac.newTuple(el.getFirst())); } return bfac.newDefaultBag(result); }
public DataBag exec(Tuple input) throws IOException { try { DataBag bag = BagFactory.getInstance().newDefaultBag(); for (int i = 0; i < input.size(); i++) { final Object object = input.get(i); if (object instanceof Tuple) { for (int j = 0; j < ((Tuple) object).size(); j++) { Tuple tp2 = TupleFactory.getInstance().newTuple(1); tp2.set(0, ((Tuple) object).get(j)); bag.add(tp2); } } else { Tuple tp2 = TupleFactory.getInstance().newTuple(1); tp2.set(0, object); bag.add(tp2); } } return bag; } catch (Exception ee) { throw new RuntimeException("Error while creating a bag", ee); } }
/** * Makes the specified tupleset the upper bound on the contents of the given relation. The lower * bound automatically becomen an empty tupleset with the same arity as the relation. * * @requires upper.arity = r.arity && upper.universe = this.universe * @ensures this.relations' = this.relations + r this.lowerBound' = this.lowerBound ++ r->{s: * TupleSet | s.universe = this.universe && s.arity = r.arity && no s.tuples} && * this.upperBound' = this.upperBound ++ r->upper * @throws NullPointerException r = null || upper = null * @throws IllegalArgumentException upper.arity != r.arity || upper.universe != this.universe */ public void bound(Relation r, TupleSet upper) { checkBound(r.arity(), upper); lowers.put(r, factory.noneOf(r.arity()).unmodifiableView()); uppers.put(r, upper.clone().unmodifiableView()); }
/** * @throws IllegalArgumentException arity != bound.arity * @throws IllegalArgumentException bound.universe != this.universe */ private void checkBound(int arity, TupleSet bound) { if (arity != bound.arity()) throw new IllegalArgumentException("bound.arity != r.arity"); if (!bound.universe().equals(factory.universe())) throw new IllegalArgumentException("bound.universe != this.universe"); }
/** * Returns this.universe. * * @return this.universe */ public Universe universe() { return factory.universe(); }
public static void main(String[] args) throws Exception { Relation x0 = Relation.unary("Int/min"); Relation x1 = Relation.unary("Int/zero"); Relation x2 = Relation.unary("Int/max"); Relation x3 = Relation.nary("Int/next", 2); Relation x4 = Relation.unary("seq/Int"); Relation x5 = Relation.unary("String"); Relation x6 = Relation.unary("this/A"); Relation x7 = Relation.unary("this/Relation"); Relation x8 = Relation.nary("this/Relation.r", 4); List<String> atomlist = Arrays.asList( "-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "0", "1", "2", "3", "4", "5", "6", "7", "A$0", "A$1", "A$2", "Relation$0", "unused0", "unused1"); Universe universe = new Universe(atomlist); TupleFactory factory = universe.factory(); Bounds bounds = new Bounds(universe); TupleSet x0_upper = factory.noneOf(1); x0_upper.add(factory.tuple("-8")); bounds.boundExactly(x0, x0_upper); TupleSet x1_upper = factory.noneOf(1); x1_upper.add(factory.tuple("0")); bounds.boundExactly(x1, x1_upper); TupleSet x2_upper = factory.noneOf(1); x2_upper.add(factory.tuple("7")); bounds.boundExactly(x2, x2_upper); TupleSet x3_upper = factory.noneOf(2); x3_upper.add(factory.tuple("-8").product(factory.tuple("-7"))); x3_upper.add(factory.tuple("-7").product(factory.tuple("-6"))); x3_upper.add(factory.tuple("-6").product(factory.tuple("-5"))); x3_upper.add(factory.tuple("-5").product(factory.tuple("-4"))); x3_upper.add(factory.tuple("-4").product(factory.tuple("-3"))); x3_upper.add(factory.tuple("-3").product(factory.tuple("-2"))); x3_upper.add(factory.tuple("-2").product(factory.tuple("-1"))); x3_upper.add(factory.tuple("-1").product(factory.tuple("0"))); x3_upper.add(factory.tuple("0").product(factory.tuple("1"))); x3_upper.add(factory.tuple("1").product(factory.tuple("2"))); x3_upper.add(factory.tuple("2").product(factory.tuple("3"))); x3_upper.add(factory.tuple("3").product(factory.tuple("4"))); x3_upper.add(factory.tuple("4").product(factory.tuple("5"))); x3_upper.add(factory.tuple("5").product(factory.tuple("6"))); x3_upper.add(factory.tuple("6").product(factory.tuple("7"))); bounds.boundExactly(x3, x3_upper); TupleSet x4_upper = factory.noneOf(1); x4_upper.add(factory.tuple("0")); x4_upper.add(factory.tuple("1")); x4_upper.add(factory.tuple("2")); bounds.boundExactly(x4, x4_upper); TupleSet x5_upper = factory.noneOf(1); bounds.boundExactly(x5, x5_upper); TupleSet x6_upper = factory.noneOf(1); x6_upper.add(factory.tuple("A$0")); x6_upper.add(factory.tuple("A$1")); x6_upper.add(factory.tuple("A$2")); bounds.boundExactly(x6, x6_upper); TupleSet x7_upper = factory.noneOf(1); x7_upper.add(factory.tuple("unused0")); x7_upper.add(factory.tuple("unused1")); x7_upper.add(factory.tuple("Relation$0")); bounds.bound(x7, x7_upper); TupleSet x8_upper = factory.noneOf(4); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$0")) .product(factory.tuple("A$0")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$0")) .product(factory.tuple("A$0")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$0")) .product(factory.tuple("A$0")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$0")) .product(factory.tuple("A$1")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$0")) .product(factory.tuple("A$1")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$0")) .product(factory.tuple("A$1")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$0")) .product(factory.tuple("A$2")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$0")) .product(factory.tuple("A$2")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$0")) .product(factory.tuple("A$2")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$1")) .product(factory.tuple("A$0")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$1")) .product(factory.tuple("A$0")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$1")) .product(factory.tuple("A$0")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$1")) .product(factory.tuple("A$1")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$1")) .product(factory.tuple("A$1")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$1")) .product(factory.tuple("A$1")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$1")) .product(factory.tuple("A$2")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$1")) .product(factory.tuple("A$2")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$1")) .product(factory.tuple("A$2")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$2")) .product(factory.tuple("A$0")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$2")) .product(factory.tuple("A$0")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$2")) .product(factory.tuple("A$0")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$2")) .product(factory.tuple("A$1")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$2")) .product(factory.tuple("A$1")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$2")) .product(factory.tuple("A$1")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$2")) .product(factory.tuple("A$2")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$2")) .product(factory.tuple("A$2")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("unused0") .product(factory.tuple("A$2")) .product(factory.tuple("A$2")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$0")) .product(factory.tuple("A$0")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$0")) .product(factory.tuple("A$0")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$0")) .product(factory.tuple("A$0")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$0")) .product(factory.tuple("A$1")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$0")) .product(factory.tuple("A$1")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$0")) .product(factory.tuple("A$1")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$0")) .product(factory.tuple("A$2")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$0")) .product(factory.tuple("A$2")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$0")) .product(factory.tuple("A$2")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$1")) .product(factory.tuple("A$0")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$1")) .product(factory.tuple("A$0")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$1")) .product(factory.tuple("A$0")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$1")) .product(factory.tuple("A$1")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$1")) .product(factory.tuple("A$1")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$1")) .product(factory.tuple("A$1")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$1")) .product(factory.tuple("A$2")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$1")) .product(factory.tuple("A$2")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$1")) .product(factory.tuple("A$2")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$2")) .product(factory.tuple("A$0")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$2")) .product(factory.tuple("A$0")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$2")) .product(factory.tuple("A$0")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$2")) .product(factory.tuple("A$1")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$2")) .product(factory.tuple("A$1")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$2")) .product(factory.tuple("A$1")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$2")) .product(factory.tuple("A$2")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$2")) .product(factory.tuple("A$2")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("unused1") .product(factory.tuple("A$2")) .product(factory.tuple("A$2")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$0")) .product(factory.tuple("A$0")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$0")) .product(factory.tuple("A$0")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$0")) .product(factory.tuple("A$0")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$0")) .product(factory.tuple("A$1")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$0")) .product(factory.tuple("A$1")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$0")) .product(factory.tuple("A$1")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$0")) .product(factory.tuple("A$2")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$0")) .product(factory.tuple("A$2")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$0")) .product(factory.tuple("A$2")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$1")) .product(factory.tuple("A$0")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$1")) .product(factory.tuple("A$0")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$1")) .product(factory.tuple("A$0")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$1")) .product(factory.tuple("A$1")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$1")) .product(factory.tuple("A$1")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$1")) .product(factory.tuple("A$1")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$1")) .product(factory.tuple("A$2")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$1")) .product(factory.tuple("A$2")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$1")) .product(factory.tuple("A$2")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$2")) .product(factory.tuple("A$0")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$2")) .product(factory.tuple("A$0")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$2")) .product(factory.tuple("A$0")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$2")) .product(factory.tuple("A$1")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$2")) .product(factory.tuple("A$1")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$2")) .product(factory.tuple("A$1")) .product(factory.tuple("A$2"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$2")) .product(factory.tuple("A$2")) .product(factory.tuple("A$0"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$2")) .product(factory.tuple("A$2")) .product(factory.tuple("A$1"))); x8_upper.add( factory .tuple("Relation$0") .product(factory.tuple("A$2")) .product(factory.tuple("A$2")) .product(factory.tuple("A$2"))); bounds.bound(x8, x8_upper); bounds.boundExactly(-8, factory.range(factory.tuple("-8"), factory.tuple("-8"))); bounds.boundExactly(-7, factory.range(factory.tuple("-7"), factory.tuple("-7"))); bounds.boundExactly(-6, factory.range(factory.tuple("-6"), factory.tuple("-6"))); bounds.boundExactly(-5, factory.range(factory.tuple("-5"), factory.tuple("-5"))); bounds.boundExactly(-4, factory.range(factory.tuple("-4"), factory.tuple("-4"))); bounds.boundExactly(-3, factory.range(factory.tuple("-3"), factory.tuple("-3"))); bounds.boundExactly(-2, factory.range(factory.tuple("-2"), factory.tuple("-2"))); bounds.boundExactly(-1, factory.range(factory.tuple("-1"), factory.tuple("-1"))); bounds.boundExactly(0, factory.range(factory.tuple("0"), factory.tuple("0"))); bounds.boundExactly(1, factory.range(factory.tuple("1"), factory.tuple("1"))); bounds.boundExactly(2, factory.range(factory.tuple("2"), factory.tuple("2"))); bounds.boundExactly(3, factory.range(factory.tuple("3"), factory.tuple("3"))); bounds.boundExactly(4, factory.range(factory.tuple("4"), factory.tuple("4"))); bounds.boundExactly(5, factory.range(factory.tuple("5"), factory.tuple("5"))); bounds.boundExactly(6, factory.range(factory.tuple("6"), factory.tuple("6"))); bounds.boundExactly(7, factory.range(factory.tuple("7"), factory.tuple("7"))); Variable x12 = Variable.unary("this"); Decls x11 = x12.oneOf(x7); Expression x16 = x12.join(x8); Expression x18 = x6.product(x6); Expression x17 = x6.product(x18); Formula x15 = x16.in(x17); Variable x21 = Variable.unary("x21"); Decls x20 = x21.oneOf(x6); Expression x25 = x21.join(x16); Expression x26 = x6.product(x6); Formula x24 = x25.in(x26); Variable x29 = Variable.unary("x29"); Decls x28 = x29.oneOf(x6); Expression x32 = x29.join(x25); Formula x31 = x32.one(); Formula x33 = x32.in(x6); Formula x30 = x31.and(x33); Formula x27 = x30.forAll(x28); Formula x23 = x24.and(x27); Variable x36 = Variable.unary("x36"); Decls x35 = x36.oneOf(x6); Expression x38 = x25.join(x36); Formula x37 = x38.in(x6); Formula x34 = x37.forAll(x35); Formula x22 = x23.and(x34); Formula x19 = x22.forAll(x20); Formula x14 = x15.and(x19); Variable x42 = Variable.unary("x42"); Decls x41 = x42.oneOf(Expression.UNIV); Variable x45 = Variable.unary("x45"); Decls x44 = x45.oneOf(Expression.UNIV); Decls x40 = x41.and(x44); Expression x50 = x42.product(x45); Expression x51 = x6.product(x6); Formula x49 = x50.in(x51); Variable x54 = Variable.unary("x54"); Decls x53 = x54.oneOf(x6); Expression x57 = x54.join(x50); Formula x56 = x57.one(); Formula x58 = x57.in(x6); Formula x55 = x56.and(x58); Formula x52 = x55.forAll(x53); Formula x48 = x49.and(x52); Variable x61 = Variable.unary("x61"); Decls x60 = x61.oneOf(x6); Expression x63 = x50.join(x61); Formula x62 = x63.in(x6); Formula x59 = x62.forAll(x60); Formula x47 = x48.and(x59); Expression x66 = x16.join(x45); Expression x65 = x66.join(x42); Formula x64 = x65.in(x6); Formula x46 = x47.implies(x64); Formula x39 = x46.forAll(x40); Formula x13 = x14.and(x39); Formula x10 = x13.forAll(x11); Expression x70 = x8.join(Expression.UNIV); Expression x69 = x70.join(Expression.UNIV); Expression x68 = x69.join(Expression.UNIV); Formula x67 = x68.in(x7); Formula x71 = x0.eq(x0); Formula x72 = x1.eq(x1); Formula x73 = x2.eq(x2); Formula x74 = x3.eq(x3); Formula x75 = x4.eq(x4); Formula x76 = x5.eq(x5); Formula x77 = x6.eq(x6); Formula x78 = x7.eq(x7); Formula x79 = x8.eq(x8); Formula x9 = Formula.compose(FormulaOperator.AND, x10, x67, x71, x72, x73, x74, x75, x76, x77, x78, x79); Solver solver = new Solver(); solver.options().setSolver(SATFactory.DefaultSAT4J); solver.options().setBitwidth(4); solver.options().setFlatten(false); solver.options().setIntEncoding(Options.IntEncoding.TWOSCOMPLEMENT); solver.options().setSymmetryBreaking(20); solver.options().setSkolemDepth(0); System.out.println(PrettyPrinter.print(x9, 0)); System.out.println(bounds); System.out.println("Solving..."); System.out.flush(); Solution sol = solver.solve(x9, bounds); System.out.println(sol.toString()); Instance inst = sol.instance(); Evaluator ev = new Evaluator(inst); System.out.println("Universe: " + ev.evaluate(Expression.UNIV)); Formula xx = x46.forAll(x40).forAll(x11); System.out.println(PrettyPrinter.print(xx, 2)); System.out.println(ev.evaluate(xx)); System.out.println(PrettyPrinter.print(x46, 4)); // Variable r = Variable.unary("this"); // Variable u1 = Variable.unary("u1"); // Variable u2 = Variable.unary("u2"); // // Formula ff = // u1.product(u2).in(x6.product(x6)).forAll(u1.oneOf(Expression.UNIV).and(u2.oneOf(Expression.UNIV))).forAll(r.oneOf(x7)); // System.out.println(PrettyPrinter.print(ff, 0)); // System.out.println(ev.evaluate(ff)); }
public static void main(String[] args) throws Exception { Relation x0 = Relation.unary("Int/min"); Relation x1 = Relation.unary("Int/zero"); Relation x2 = Relation.unary("Int/max"); Relation x3 = Relation.nary("Int/next", 2); Relation x4 = Relation.unary("seq/Int"); Relation x5 = Relation.unary("String"); Relation x6 = Relation.unary("this/Test"); Relation x7 = Relation.nary("this/Test.weight", 2); Relation x8 = Relation.nary("this/Test.x", 2); Relation x9 = Relation.nary("this/Test.y", 2); List<String> atomlist = Arrays.asList( "-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "0", "1", "2", "3", "4", "5", "6", "7", "Test$0", "Test$1", "Test$2"); Universe universe = new Universe(atomlist); TupleFactory factory = universe.factory(); Bounds bounds = new Bounds(universe); TupleSet x0_upper = factory.noneOf(1); x0_upper.add(factory.tuple("-8")); bounds.boundExactly(x0, x0_upper); TupleSet x1_upper = factory.noneOf(1); x1_upper.add(factory.tuple("0")); bounds.boundExactly(x1, x1_upper); TupleSet x2_upper = factory.noneOf(1); x2_upper.add(factory.tuple("7")); bounds.boundExactly(x2, x2_upper); TupleSet x3_upper = factory.noneOf(2); x3_upper.add(factory.tuple("-8").product(factory.tuple("-7"))); x3_upper.add(factory.tuple("-7").product(factory.tuple("-6"))); x3_upper.add(factory.tuple("-6").product(factory.tuple("-5"))); x3_upper.add(factory.tuple("-5").product(factory.tuple("-4"))); x3_upper.add(factory.tuple("-4").product(factory.tuple("-3"))); x3_upper.add(factory.tuple("-3").product(factory.tuple("-2"))); x3_upper.add(factory.tuple("-2").product(factory.tuple("-1"))); x3_upper.add(factory.tuple("-1").product(factory.tuple("0"))); x3_upper.add(factory.tuple("0").product(factory.tuple("1"))); x3_upper.add(factory.tuple("1").product(factory.tuple("2"))); x3_upper.add(factory.tuple("2").product(factory.tuple("3"))); x3_upper.add(factory.tuple("3").product(factory.tuple("4"))); x3_upper.add(factory.tuple("4").product(factory.tuple("5"))); x3_upper.add(factory.tuple("5").product(factory.tuple("6"))); x3_upper.add(factory.tuple("6").product(factory.tuple("7"))); bounds.boundExactly(x3, x3_upper); TupleSet x4_upper = factory.noneOf(1); x4_upper.add(factory.tuple("0")); x4_upper.add(factory.tuple("1")); x4_upper.add(factory.tuple("2")); x4_upper.add(factory.tuple("3")); bounds.boundExactly(x4, x4_upper); TupleSet x5_upper = factory.noneOf(1); bounds.boundExactly(x5, x5_upper); TupleSet x6_upper = factory.noneOf(1); x6_upper.add(factory.tuple("Test$0")); x6_upper.add(factory.tuple("Test$1")); x6_upper.add(factory.tuple("Test$2")); bounds.boundExactly(x6, x6_upper); TupleSet x7_upper = factory.noneOf(2); x7_upper.add(factory.tuple("Test$0").product(factory.tuple("-8"))); x7_upper.add(factory.tuple("Test$0").product(factory.tuple("-7"))); x7_upper.add(factory.tuple("Test$0").product(factory.tuple("-6"))); x7_upper.add(factory.tuple("Test$0").product(factory.tuple("-5"))); x7_upper.add(factory.tuple("Test$0").product(factory.tuple("-4"))); x7_upper.add(factory.tuple("Test$0").product(factory.tuple("-3"))); x7_upper.add(factory.tuple("Test$0").product(factory.tuple("-2"))); x7_upper.add(factory.tuple("Test$0").product(factory.tuple("-1"))); x7_upper.add(factory.tuple("Test$0").product(factory.tuple("0"))); x7_upper.add(factory.tuple("Test$0").product(factory.tuple("1"))); x7_upper.add(factory.tuple("Test$0").product(factory.tuple("2"))); x7_upper.add(factory.tuple("Test$0").product(factory.tuple("3"))); x7_upper.add(factory.tuple("Test$0").product(factory.tuple("4"))); x7_upper.add(factory.tuple("Test$0").product(factory.tuple("5"))); x7_upper.add(factory.tuple("Test$0").product(factory.tuple("6"))); x7_upper.add(factory.tuple("Test$0").product(factory.tuple("7"))); x7_upper.add(factory.tuple("Test$1").product(factory.tuple("-8"))); x7_upper.add(factory.tuple("Test$1").product(factory.tuple("-7"))); x7_upper.add(factory.tuple("Test$1").product(factory.tuple("-6"))); x7_upper.add(factory.tuple("Test$1").product(factory.tuple("-5"))); x7_upper.add(factory.tuple("Test$1").product(factory.tuple("-4"))); x7_upper.add(factory.tuple("Test$1").product(factory.tuple("-3"))); x7_upper.add(factory.tuple("Test$1").product(factory.tuple("-2"))); x7_upper.add(factory.tuple("Test$1").product(factory.tuple("-1"))); x7_upper.add(factory.tuple("Test$1").product(factory.tuple("0"))); x7_upper.add(factory.tuple("Test$1").product(factory.tuple("1"))); x7_upper.add(factory.tuple("Test$1").product(factory.tuple("2"))); x7_upper.add(factory.tuple("Test$1").product(factory.tuple("3"))); x7_upper.add(factory.tuple("Test$1").product(factory.tuple("4"))); x7_upper.add(factory.tuple("Test$1").product(factory.tuple("5"))); x7_upper.add(factory.tuple("Test$1").product(factory.tuple("6"))); x7_upper.add(factory.tuple("Test$1").product(factory.tuple("7"))); x7_upper.add(factory.tuple("Test$2").product(factory.tuple("-8"))); x7_upper.add(factory.tuple("Test$2").product(factory.tuple("-7"))); x7_upper.add(factory.tuple("Test$2").product(factory.tuple("-6"))); x7_upper.add(factory.tuple("Test$2").product(factory.tuple("-5"))); x7_upper.add(factory.tuple("Test$2").product(factory.tuple("-4"))); x7_upper.add(factory.tuple("Test$2").product(factory.tuple("-3"))); x7_upper.add(factory.tuple("Test$2").product(factory.tuple("-2"))); x7_upper.add(factory.tuple("Test$2").product(factory.tuple("-1"))); x7_upper.add(factory.tuple("Test$2").product(factory.tuple("0"))); x7_upper.add(factory.tuple("Test$2").product(factory.tuple("1"))); x7_upper.add(factory.tuple("Test$2").product(factory.tuple("2"))); x7_upper.add(factory.tuple("Test$2").product(factory.tuple("3"))); x7_upper.add(factory.tuple("Test$2").product(factory.tuple("4"))); x7_upper.add(factory.tuple("Test$2").product(factory.tuple("5"))); x7_upper.add(factory.tuple("Test$2").product(factory.tuple("6"))); x7_upper.add(factory.tuple("Test$2").product(factory.tuple("7"))); bounds.bound(x7, x7_upper); TupleSet x8_upper = factory.noneOf(2); x8_upper.add(factory.tuple("Test$0").product(factory.tuple("-8"))); x8_upper.add(factory.tuple("Test$0").product(factory.tuple("-7"))); x8_upper.add(factory.tuple("Test$0").product(factory.tuple("-6"))); x8_upper.add(factory.tuple("Test$0").product(factory.tuple("-5"))); x8_upper.add(factory.tuple("Test$0").product(factory.tuple("-4"))); x8_upper.add(factory.tuple("Test$0").product(factory.tuple("-3"))); x8_upper.add(factory.tuple("Test$0").product(factory.tuple("-2"))); x8_upper.add(factory.tuple("Test$0").product(factory.tuple("-1"))); x8_upper.add(factory.tuple("Test$0").product(factory.tuple("0"))); x8_upper.add(factory.tuple("Test$0").product(factory.tuple("1"))); x8_upper.add(factory.tuple("Test$0").product(factory.tuple("2"))); x8_upper.add(factory.tuple("Test$0").product(factory.tuple("3"))); x8_upper.add(factory.tuple("Test$0").product(factory.tuple("4"))); x8_upper.add(factory.tuple("Test$0").product(factory.tuple("5"))); x8_upper.add(factory.tuple("Test$0").product(factory.tuple("6"))); x8_upper.add(factory.tuple("Test$0").product(factory.tuple("7"))); x8_upper.add(factory.tuple("Test$1").product(factory.tuple("-8"))); x8_upper.add(factory.tuple("Test$1").product(factory.tuple("-7"))); x8_upper.add(factory.tuple("Test$1").product(factory.tuple("-6"))); x8_upper.add(factory.tuple("Test$1").product(factory.tuple("-5"))); x8_upper.add(factory.tuple("Test$1").product(factory.tuple("-4"))); x8_upper.add(factory.tuple("Test$1").product(factory.tuple("-3"))); x8_upper.add(factory.tuple("Test$1").product(factory.tuple("-2"))); x8_upper.add(factory.tuple("Test$1").product(factory.tuple("-1"))); x8_upper.add(factory.tuple("Test$1").product(factory.tuple("0"))); x8_upper.add(factory.tuple("Test$1").product(factory.tuple("1"))); x8_upper.add(factory.tuple("Test$1").product(factory.tuple("2"))); x8_upper.add(factory.tuple("Test$1").product(factory.tuple("3"))); x8_upper.add(factory.tuple("Test$1").product(factory.tuple("4"))); x8_upper.add(factory.tuple("Test$1").product(factory.tuple("5"))); x8_upper.add(factory.tuple("Test$1").product(factory.tuple("6"))); x8_upper.add(factory.tuple("Test$1").product(factory.tuple("7"))); x8_upper.add(factory.tuple("Test$2").product(factory.tuple("-8"))); x8_upper.add(factory.tuple("Test$2").product(factory.tuple("-7"))); x8_upper.add(factory.tuple("Test$2").product(factory.tuple("-6"))); x8_upper.add(factory.tuple("Test$2").product(factory.tuple("-5"))); x8_upper.add(factory.tuple("Test$2").product(factory.tuple("-4"))); x8_upper.add(factory.tuple("Test$2").product(factory.tuple("-3"))); x8_upper.add(factory.tuple("Test$2").product(factory.tuple("-2"))); x8_upper.add(factory.tuple("Test$2").product(factory.tuple("-1"))); x8_upper.add(factory.tuple("Test$2").product(factory.tuple("0"))); x8_upper.add(factory.tuple("Test$2").product(factory.tuple("1"))); x8_upper.add(factory.tuple("Test$2").product(factory.tuple("2"))); x8_upper.add(factory.tuple("Test$2").product(factory.tuple("3"))); x8_upper.add(factory.tuple("Test$2").product(factory.tuple("4"))); x8_upper.add(factory.tuple("Test$2").product(factory.tuple("5"))); x8_upper.add(factory.tuple("Test$2").product(factory.tuple("6"))); x8_upper.add(factory.tuple("Test$2").product(factory.tuple("7"))); bounds.bound(x8, x8_upper); TupleSet x9_upper = factory.noneOf(2); x9_upper.add(factory.tuple("Test$0").product(factory.tuple("-8"))); x9_upper.add(factory.tuple("Test$0").product(factory.tuple("-7"))); x9_upper.add(factory.tuple("Test$0").product(factory.tuple("-6"))); x9_upper.add(factory.tuple("Test$0").product(factory.tuple("-5"))); x9_upper.add(factory.tuple("Test$0").product(factory.tuple("-4"))); x9_upper.add(factory.tuple("Test$0").product(factory.tuple("-3"))); x9_upper.add(factory.tuple("Test$0").product(factory.tuple("-2"))); x9_upper.add(factory.tuple("Test$0").product(factory.tuple("-1"))); x9_upper.add(factory.tuple("Test$0").product(factory.tuple("0"))); x9_upper.add(factory.tuple("Test$0").product(factory.tuple("1"))); x9_upper.add(factory.tuple("Test$0").product(factory.tuple("2"))); x9_upper.add(factory.tuple("Test$0").product(factory.tuple("3"))); x9_upper.add(factory.tuple("Test$0").product(factory.tuple("4"))); x9_upper.add(factory.tuple("Test$0").product(factory.tuple("5"))); x9_upper.add(factory.tuple("Test$0").product(factory.tuple("6"))); x9_upper.add(factory.tuple("Test$0").product(factory.tuple("7"))); x9_upper.add(factory.tuple("Test$1").product(factory.tuple("-8"))); x9_upper.add(factory.tuple("Test$1").product(factory.tuple("-7"))); x9_upper.add(factory.tuple("Test$1").product(factory.tuple("-6"))); x9_upper.add(factory.tuple("Test$1").product(factory.tuple("-5"))); x9_upper.add(factory.tuple("Test$1").product(factory.tuple("-4"))); x9_upper.add(factory.tuple("Test$1").product(factory.tuple("-3"))); x9_upper.add(factory.tuple("Test$1").product(factory.tuple("-2"))); x9_upper.add(factory.tuple("Test$1").product(factory.tuple("-1"))); x9_upper.add(factory.tuple("Test$1").product(factory.tuple("0"))); x9_upper.add(factory.tuple("Test$1").product(factory.tuple("1"))); x9_upper.add(factory.tuple("Test$1").product(factory.tuple("2"))); x9_upper.add(factory.tuple("Test$1").product(factory.tuple("3"))); x9_upper.add(factory.tuple("Test$1").product(factory.tuple("4"))); x9_upper.add(factory.tuple("Test$1").product(factory.tuple("5"))); x9_upper.add(factory.tuple("Test$1").product(factory.tuple("6"))); x9_upper.add(factory.tuple("Test$1").product(factory.tuple("7"))); x9_upper.add(factory.tuple("Test$2").product(factory.tuple("-8"))); x9_upper.add(factory.tuple("Test$2").product(factory.tuple("-7"))); x9_upper.add(factory.tuple("Test$2").product(factory.tuple("-6"))); x9_upper.add(factory.tuple("Test$2").product(factory.tuple("-5"))); x9_upper.add(factory.tuple("Test$2").product(factory.tuple("-4"))); x9_upper.add(factory.tuple("Test$2").product(factory.tuple("-3"))); x9_upper.add(factory.tuple("Test$2").product(factory.tuple("-2"))); x9_upper.add(factory.tuple("Test$2").product(factory.tuple("-1"))); x9_upper.add(factory.tuple("Test$2").product(factory.tuple("0"))); x9_upper.add(factory.tuple("Test$2").product(factory.tuple("1"))); x9_upper.add(factory.tuple("Test$2").product(factory.tuple("2"))); x9_upper.add(factory.tuple("Test$2").product(factory.tuple("3"))); x9_upper.add(factory.tuple("Test$2").product(factory.tuple("4"))); x9_upper.add(factory.tuple("Test$2").product(factory.tuple("5"))); x9_upper.add(factory.tuple("Test$2").product(factory.tuple("6"))); x9_upper.add(factory.tuple("Test$2").product(factory.tuple("7"))); bounds.bound(x9, x9_upper); bounds.boundExactly(-8, factory.range(factory.tuple("-8"), factory.tuple("-8"))); bounds.boundExactly(-7, factory.range(factory.tuple("-7"), factory.tuple("-7"))); bounds.boundExactly(-6, factory.range(factory.tuple("-6"), factory.tuple("-6"))); bounds.boundExactly(-5, factory.range(factory.tuple("-5"), factory.tuple("-5"))); bounds.boundExactly(-4, factory.range(factory.tuple("-4"), factory.tuple("-4"))); bounds.boundExactly(-3, factory.range(factory.tuple("-3"), factory.tuple("-3"))); bounds.boundExactly(-2, factory.range(factory.tuple("-2"), factory.tuple("-2"))); bounds.boundExactly(-1, factory.range(factory.tuple("-1"), factory.tuple("-1"))); bounds.boundExactly(0, factory.range(factory.tuple("0"), factory.tuple("0"))); bounds.boundExactly(1, factory.range(factory.tuple("1"), factory.tuple("1"))); bounds.boundExactly(2, factory.range(factory.tuple("2"), factory.tuple("2"))); bounds.boundExactly(3, factory.range(factory.tuple("3"), factory.tuple("3"))); bounds.boundExactly(4, factory.range(factory.tuple("4"), factory.tuple("4"))); bounds.boundExactly(5, factory.range(factory.tuple("5"), factory.tuple("5"))); bounds.boundExactly(6, factory.range(factory.tuple("6"), factory.tuple("6"))); bounds.boundExactly(7, factory.range(factory.tuple("7"), factory.tuple("7"))); Variable x13 = Variable.unary("this"); Decls x12 = x13.oneOf(x6); Expression x16 = x13.join(x7); Formula x15 = x16.one(); Formula x17 = x16.in(Expression.INTS); Formula x14 = x15.and(x17); Formula x11 = x14.forAll(x12); Expression x20 = x7.join(Expression.UNIV); Formula x19 = x20.in(x6); Variable x24 = Variable.unary("this"); Decls x23 = x24.oneOf(x6); Expression x27 = x24.join(x8); Formula x26 = x27.lone(); Formula x28 = x27.in(Expression.INTS); Formula x25 = x26.and(x28); Formula x22 = x25.forAll(x23); Expression x30 = x8.join(Expression.UNIV); Formula x29 = x30.in(x6); Variable x33 = Variable.unary("this"); Decls x32 = x33.oneOf(x6); Expression x36 = x33.join(x9); Formula x35 = x36.one(); Formula x37 = x36.in(Expression.INTS); Formula x34 = x35.and(x37); Formula x31 = x34.forAll(x32); Expression x39 = x9.join(Expression.UNIV); Formula x38 = x39.in(x6); Variable x42 = Variable.unary("this"); Decls x41 = x42.oneOf(x6); Expression x44 = x42.join(x7); Expression x48 = x42.join(x8); IntExpression x47 = x48.sum(); Expression x50 = x42.join(x9); IntExpression x49 = x50.sum(); IntExpression x46 = x47.plus(x49); Expression x45 = x46.toExpression(); Formula x43 = x44.eq(x45); Formula x40 = x43.forAll(x41); Formula x51 = x0.eq(x0); Formula x52 = x1.eq(x1); Formula x53 = x2.eq(x2); Formula x54 = x3.eq(x3); Formula x55 = x4.eq(x4); Formula x56 = x5.eq(x5); Formula x57 = x6.eq(x6); Formula x58 = x7.eq(x7); Formula x59 = x8.eq(x8); Formula x60 = x9.eq(x9); IntExprReduction ier = new IntExprReduction(); Formula[] formulas = ier.reduceIntExpressions( x11, x19, x22, x29, x31, x38, x40, x51, x52, x53, x54, x55, x56, x57, x58, x59, x60); Formula newFormula = Formula.compose(FormulaOperator.AND, formulas); ier.solve(newFormula, bounds, factory, universe, 32); }
/** * An ordered collection of Tuples (possibly) with multiples. Data is stored unsorted as it comes * in, and only sorted when it is time to dump it to a file or when the first iterator is requested. * Experementation found this to be the faster than storing it sorted to begin with. * * <p>We allow a user defined comparator, but provide a default comparator in cases where the user * doesn't specify one. * * <p>This bag is not registered with SpillableMemoryManager. It calculates the number of tuples to * hold in memory and spill pro-actively into files. */ public class InternalSortedBag extends SortedSpillBag { /** */ private static final long serialVersionUID = 2L; private static TupleFactory gTupleFactory = TupleFactory.getInstance(); private static final Log log = LogFactory.getLog(InternalSortedBag.class); private transient Comparator<Tuple> mComp; private transient boolean mReadStarted = false; private static class DefaultComparator implements Comparator<Tuple> { @SuppressWarnings("unchecked") public int compare(Tuple t1, Tuple t2) { return t1.compareTo(t2); } public boolean equals(Object o) { return (o == this); } public int hashCode() { return 42; } } public InternalSortedBag() { this(null); } public InternalSortedBag(Comparator<Tuple> comp) { this(1, comp); } public InternalSortedBag(int bagCount, Comparator<Tuple> comp) { this(bagCount, -1.0f, comp); } public InternalSortedBag(int bagCount, float percent, Comparator<Tuple> comp) { super(bagCount, percent); init(bagCount, percent, comp); } /** @param comp Comparator to use to do the sorting. If null, DefaultComparator will be used. */ private void init(int bagCount, double percent, Comparator<Tuple> comp) { mComp = (comp == null) ? new DefaultComparator() : comp; mContents = new ArrayList<Tuple>(); } public void add(Tuple t) { if (mReadStarted) { throw new IllegalStateException("InternalSortedBag is closed for adding new tuples"); } if (mContents.size() > memLimit.getCacheLimit()) { proactive_spill(mComp); } mContents.add(t); // check how many tuples memory can hold by getting average // size of first 100 tuples if (mSize < 100 && (mSpillFiles == null || mSpillFiles.isEmpty()) && t != null) { memLimit.addNewObjSize(t.getMemorySize()); } mSize++; } public void addAll(DataBag b) { Iterator<Tuple> iter = b.iterator(); while (iter.hasNext()) { add(iter.next()); } } public void addAll(Collection<Tuple> c) { Iterator<Tuple> iter = c.iterator(); while (iter.hasNext()) { add(iter.next()); } } public boolean isSorted() { return true; } public boolean isDistinct() { return false; } public Iterator<Tuple> iterator() { return new SortedDataBagIterator(); } /** * An iterator that handles getting the next tuple from the bag. Data can be stored in a * combination of in memory and on disk. */ private class SortedDataBagIterator implements Iterator<Tuple> { /** * A container to hold tuples in a priority queue. Stores the file number the tuple came from, * so that when the tuple is read out of the queue, we know which file to read its replacement * tuple from. */ private class PQContainer implements Comparable<PQContainer> { public Tuple tuple; public int fileNum; public int compareTo(PQContainer other) { return mComp.compare(tuple, other.tuple); } public boolean equals(Object obj) { if (obj instanceof PQContainer) { return compareTo((PQContainer) obj) == 0; } return false; } public int hashCode() { return tuple.hashCode(); } } // We have to buffer a tuple because there's no easy way for next // to tell whether or not there's another tuple available, other // than to read it. private Tuple mBuf = null; private int mMemoryPtr = 0; private PriorityQueue<PQContainer> mMergeQ = null; private ArrayList<DataInputStream> mStreams = null; private int mCntr = 0; SortedDataBagIterator() { // If this is the first read, we need to sort the data. if (!mReadStarted) { preMerge(); Collections.sort((ArrayList<Tuple>) mContents, mComp); mReadStarted = true; } } public boolean hasNext() { // See if we can find a tuple. If so, buffer it. mBuf = next(); return mBuf != null; } public Tuple next() { // This will report progress every 1024 times through next. // This should be much faster than using mod. if ((mCntr++ & 0x3ff) == 0) reportProgress(); // If there's one in the buffer, use that one. if (mBuf != null) { Tuple t = mBuf; mBuf = null; return t; } if (mSpillFiles == null || mSpillFiles.size() == 0) { return readFromMemory(); } // We have spill files, so we need to read the next tuple from // one of those files or from memory. return readFromPriorityQ(); } /** Not implemented. */ public void remove() {} private Tuple readFromPriorityQ() { if (mMergeQ == null) { // First read, we need to set up the queue and the array of // file streams // Add one to the size for the list in memory. mMergeQ = new PriorityQueue<PQContainer>(mSpillFiles.size() + 1); // Add one to the size in case we spill later. mStreams = new ArrayList<DataInputStream>(mSpillFiles.size() + 1); Iterator<File> i = mSpillFiles.iterator(); while (i.hasNext()) { try { DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(i.next()))); mStreams.add(in); // Add the first tuple from this file into the // merge queue. addToQueue(null, mStreams.size() - 1); } catch (FileNotFoundException fnfe) { // We can't find our own spill file? That should // never happen. String msg = "Unable to find our spill file."; log.fatal(msg, fnfe); throw new RuntimeException(msg, fnfe); } } // Prime one from memory too if (mContents.size() > 0) { addToQueue(null, -1); } } // Pop the top one off the queue PQContainer c = mMergeQ.poll(); if (c == null) return null; // Add the next tuple from whereever we read from into the // queue. Buffer the tuple we're returning, as we'll be // reusing c. Tuple t = c.tuple; addToQueue(c, c.fileNum); return t; } private void addToQueue(PQContainer c, int fileNum) { if (c == null) { c = new PQContainer(); } c.fileNum = fileNum; if (fileNum == -1) { // Need to read from memory. c.tuple = readFromMemory(); if (c.tuple != null) { mMergeQ.add(c); } return; } // Read the next tuple from the indicated file DataInputStream in = mStreams.get(fileNum); if (in != null) { // There's still data in this file c.tuple = gTupleFactory.newTuple(); try { c.tuple.readFields(in); mMergeQ.add(c); } catch (EOFException eof) { // Out of tuples in this file. Set our slot in the // array to null so we don't keep trying to read from // this file. try { in.close(); } catch (IOException e) { log.warn("Failed to close spill file.", e); } mStreams.set(fileNum, null); } catch (IOException ioe) { String msg = "Unable to find our spill file."; log.fatal(msg, ioe); throw new RuntimeException(msg, ioe); } } } // Function assumes that the reader lock is already held before we enter // this function. private Tuple readFromMemory() { if (mContents.size() == 0) return null; if (mMemoryPtr < mContents.size()) { return ((ArrayList<Tuple>) mContents).get(mMemoryPtr++); } else { return null; } } /** * Pre-merge if there are too many spill files. This avoids the issue of having too large a fan * out in our merge. Experimentation by the hadoop team has shown that 100 is about the optimal * number of spill files. This function modifies the mSpillFiles array and assumes the write * lock is already held. It will not unlock it. * * <p>Tuples are reconstituted as tuples, evaluated, and rewritten as tuples. This is expensive, * but I need to do this in order to use the sort spec that was provided to me. */ private void preMerge() { if (mSpillFiles == null || mSpillFiles.size() <= MAX_SPILL_FILES) { return; } // While there are more than max spill files, gather max spill // files together and merge them into one file. Then remove the others // from mSpillFiles. The new spill files are attached at the // end of the list, so I can just keep going until I get a // small enough number without too much concern over uneven // size merges. Convert mSpillFiles to a linked list since // we'll be removing pieces from the middle and we want to do // it efficiently. try { LinkedList<File> ll = new LinkedList<File>(mSpillFiles); LinkedList<File> filesToDelete = new LinkedList<File>(); while (ll.size() > MAX_SPILL_FILES) { ListIterator<File> i = ll.listIterator(); mStreams = new ArrayList<DataInputStream>(MAX_SPILL_FILES); mMergeQ = new PriorityQueue<PQContainer>(MAX_SPILL_FILES); for (int j = 0; j < MAX_SPILL_FILES; j++) { try { File f = i.next(); DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(f))); mStreams.add(in); addToQueue(null, mStreams.size() - 1); i.remove(); filesToDelete.add(f); } catch (FileNotFoundException fnfe) { // We can't find our own spill file? That should // neer happen. String msg = "Unable to find our spill file."; log.fatal(msg, fnfe); throw new RuntimeException(msg, fnfe); } } // Get a new spill file. This adds one to the end of // the spill files list. So I need to append it to my // linked list as well so that it's still there when I // move my linked list back to the spill files. try { DataOutputStream out = getSpillFile(); ll.add(mSpillFiles.get(mSpillFiles.size() - 1)); Tuple t; while ((t = readFromPriorityQ()) != null) { t.write(out); } out.flush(); out.close(); } catch (IOException ioe) { String msg = "Unable to find our spill file."; log.fatal(msg, ioe); throw new RuntimeException(msg, ioe); } } // delete files that have been merged into new files for (File f : filesToDelete) { if (f.delete() == false) { log.warn("Failed to delete spill file: " + f.getPath()); } } // clear the list, so that finalize does not delete any files, // when mSpillFiles is assigned a new value mSpillFiles.clear(); // Now, move our new list back to the spill files array. mSpillFiles = new FileList(ll); } finally { // Reset mStreams and mMerge so that they'll be allocated // properly for regular merging. mStreams = null; mMergeQ = null; } } } public long spill() { return proactive_spill(mComp); } }