/**
* Copyright (C) 2009-2013 FoundationDB, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.foundationdb.sql.optimizer.rule.join_enum;
import com.foundationdb.sql.optimizer.plan.Joinable;
import com.foundationdb.sql.optimizer.plan.PlanNode;
import java.util.List;
/**
* A set of {@link Joinable}s is represented as a bit vector,
* implemented directly as a <code>long</code> and not even wrapped in
* a small class. Hence this class is all static methods.
*/
public class JoinableBitSet
{
/** The empty set. */
public static long empty() {
return 0;
}
public static boolean isEmpty(long s) {
return (s == 0);
}
/** A set containing a single element with the given index. */
public static long of(int i) {
return (1L << i);
}
public static int count(long s) {
return Long.bitCount(s);
}
/** Are these two sets equal (same members)? */
public static boolean equals(long s1, long s2) {
return (s1 == s2);
}
/** Union of the two sets. */
public static long union(long s1, long s2) {
return s1 | s2;
}
/** Intersection of the two sets. */
public static long intersection(long s1, long s2) {
return s1 & s2;
}
/** Set difference: elements of <code>s1</code> not in <code>s2</code>. */
public static long difference(long s1, long s2) {
return s1 & ~s2;
}
/** Set complement: elements not in <code>s</code>. */
public static long complement(long s) {
return ~s;
}
/** Do the two sets overlap? */
public static boolean overlaps(long s1, long s2) {
return ((s1 & s2) != 0);
}
/** Is <code>sub</code> a subset (not necessarily proper) of <code>sup</code>? */
public static boolean isSubset(long sub, long sup) {
return ((sub & sup) == sub);
}
/** Given a subset <code>sub</code> of <code>sup</code>, return the next subset.
* Repeated application of this method, starting with {@link empty}
* will enumerate all subsets of the given set, ending with <code>sup</code> itself.
*/
public static long nextSubset(long sub, long sup) {
return (sup & (sub - sup));
}
/** The index of the smallest element of the given set. */
public static int min(long s) {
return Long.numberOfTrailingZeros(s);
}
/** The single element subset of the given set containing just the
* element with the samllest index. */
public static long minSubset(long s) {
return Long.lowestOneBit(s);
}
/** A set of all elements with index up to and including the given index. */
public static long through(int i) {
return ((1 << (i+1)) - 1);
}
/** Printed representation of the given set for debugging. */
public static String toString(long s, List<Joinable> items) {
StringBuilder str = new StringBuilder("[");
boolean first = true;
for (int i = 0; i < 64; i++) {
if (overlaps(s, of(i))) {
if (first)
first = false;
else
str.append(", ");
str.append(items.get(i).summaryString(PlanNode.SummaryConfiguration.DEFAULT));
}
}
str.append("]");
return str.toString();
}
private JoinableBitSet() {
}
}