SchemafulAArraySet.java
package com.github.dakusui.jcunitx.testsuite;
import com.github.dakusui.jcunitx.core.AArray;
import com.github.dakusui.jcunitx.utils.TupleUtils;
import com.github.dakusui.jcunitx.core.TupleSet;
import com.github.dakusui.jcunitx.exceptions.FrameworkException;
import com.github.dakusui.pcond.functions.Functions;
import java.util.*;
import static com.github.dakusui.jcunitx.pipeline.PipelineException.checkIfStrengthIsInRange;
import static com.github.dakusui.pcond.Assertions.that;
import static com.github.dakusui.pcond.functions.Functions.chain;
import static com.github.dakusui.pcond.functions.Predicates.*;
import static java.util.Collections.unmodifiableList;
/**
* A list of tuples all of whose entries have the same attribute names. An implementation
* of this interface must also guarantee that it doesn't have the same element.
*
* [ditaa]
* ----
* +-----+ +-----+
* |hello|<>-->|world|
* +-----+ +-----+
* ----
*/
public interface SchemafulAArraySet extends List<AArray> {
static SchemafulAArraySet fromRows(List<AArray> rows) {
Objects.requireNonNull(rows);
FrameworkException.check(rows, r -> !r.isEmpty());
return new Builder(new ArrayList<>(rows.get(0).keySet()))
.addAll(rows)
.build();
}
static SchemafulAArraySet empty(List<String> attributeNames) {
return new Builder(attributeNames).build();
}
List<String> getAttributeNames();
int width();
/**
* Returns all t-way tuples in this {@code SchemafulTupleSet} where t is {@code strength}.
*
* @param strength Strength of t-way tuples to be returned.
* @return A set of sub-tuples of this.
*/
TupleSet subtuplesOf(int strength);
class Builder {
private final List<String> attributeNames;
private final List<AArray> rows;
public Builder(List<String> attributeNames) {
assert that(attributeNames, allOf(
isNotNull(),
transform(Functions.size()).check(equalTo(toSet(attributeNames).size()))
));
this.attributeNames = unmodifiableList(attributeNames);
this.rows = new LinkedList<>();
}
private static HashSet<String> toSet(final List<String> list) {
return new HashSet<String>() {{
this.addAll(list);
}};
}
public Builder add(AArray row) {
////
// Make sure all the tuples in this suite object have the same set of attribute
// names.
assert that(row, allOf(
isNotNull(),
transform(chain("keySet")).check(isEqualTo(toSet(attributeNames)))));
this.rows.add(row);
return this;
}
public Builder addAll(List<AArray> tuples) {
tuples.forEach(this::add);
return this;
}
public SchemafulAArraySet build() {
class Impl extends AbstractList<AArray> implements SchemafulAArraySet {
private final List<AArray> rows;
private final List<String> attributeNames;
private Impl(List<String> attributeNames, List<AArray> rows) {
this.rows = rows;
this.attributeNames = unmodifiableList(attributeNames);
}
@Override
public AArray get(int index) {
return rows.get(index);
}
@Override
public int size() {
return rows.size();
}
@Override
public List<String> getAttributeNames() {
return attributeNames;
}
@Override
public int width() {
return getAttributeNames().size();
}
@Override
public TupleSet subtuplesOf(int strength) {
checkIfStrengthIsInRange(strength, attributeNames);
TupleSet.Builder builder = new TupleSet.Builder();
for (AArray each : this) {
builder.addAll(TupleUtils.subtuplesOf(each, strength));
}
return builder.build();
}
}
return new Impl(
new ArrayList<>(this.attributeNames),
this.rows);
}
}
}