rankfundef.java
来自「数据仓库展示程序」· Java 代码 · 共 468 行 · 第 1/2 页
JAVA
468 行
}
return new Double(j + 1); // 1-based
}
}
/**
* Expression which evaluates an expression to form a list of tuples,
* evaluates a scalar expression at each tuple, then sorts the list of
* values. The result is a value of type {@link SortResult}, and can be
* used to implement the <code>Rank</code> function efficiently.
*/
private static class SortExp extends ExpBase {
private final Exp listExp;
private final Exp sortExp;
public SortExp(Exp listExp, Exp sortExp) {
this.listExp = listExp;
this.sortExp = sortExp;
}
public Object clone() {
return this;
}
public int getCategory() {
throw new UnsupportedOperationException();
}
public Type getTypeX() {
// white lie -- the answer is not important
return new NumericType();
}
public Exp accept(Validator validator) {
return this;
}
public boolean dependsOn(Dimension dimension) {
// Similar dependency pattern to ORDER function (qv).
// Depends upon everything listExp and sortExp depend upon, except
// the dimensions of listExp.
if (listExp.dependsOn(dimension)) {
return true;
}
if (listExp.getTypeX().usesDimension(dimension)) {
return false;
}
return sortExp.dependsOn(dimension);
}
public Object evaluate(Evaluator evaluator) {
// Create a new evaluator so we don't corrupt the given one.
final Evaluator evaluator2 = evaluator.push();
// Construct an array containing the value of the expression
// for each member.
List members = (List) listExp.evaluate(evaluator2);
if (members == null) {
return new SortResult(true, null);
}
RuntimeException exception = null;
Object[] values = new Object[members.size()];
int j = 0;
for (int i = 0; i < members.size(); i++) {
final Object o = members.get(i);
if (o instanceof Member) {
Member member = (Member) o;
evaluator2.setContext(member);
} else {
evaluator2.setContext((Member[]) o);
}
final Object value = sortExp.evaluateScalar(evaluator2);
if (value instanceof RuntimeException) {
if (exception == null) {
exception = (RuntimeException) value;
}
} else if (value == Util.nullValue) {
;
} else {
values[j++] = value;
}
}
// If there were exceptions, quit now... we'll be back.
if (exception != null) {
return exception;
}
// If the array is shorter than we expected (because of null
// values) truncate it.
if (j < members.size()) {
final Object[] oldValues = values;
values = new Object[j];
System.arraycopy(oldValues, 0, values, 0, j);
}
// Sort the array.
FunUtil.sortValuesDesc(values);
return new SortResult(false, values);
}
}
/**
* Holder for the result of sorting a set of values.
*
* <p>todo: More optimal representation if a lot of the values are the
* same.
*/
private static class SortResult {
/**
* Whether the list of tuples was empty.
* If this is the case, the rank will always be null.
*
* <p>It's possible for there to be a positive number of tuples, all
* of whose values are null, in which case, empty will be false but
* values will be empty.
*/
final boolean empty;
/**
* Values in sorted order. Null values are not present: they would
* be at the end, anyway.
*/
final Object[] values;
public SortResult(boolean empty, Object[] values) {
this.empty = empty;
this.values = values;
}
public void print(PrintWriter pw) {
if (empty) {
pw.println("SortResult: empty");
} else {
pw.println("SortResult {");
for (int i = 0; i < values.length; i++) {
if (i > 0) {
pw.println(",");
}
Object value = values[i];
pw.print(value);
}
pw.println("}");
}
pw.flush();
}
}
/**
* Expression which evaluates an expression to form a list of tuples.
* The result is a value of type {@link RankedList}, or null if the list
* is empty.
*/
private static class RankedListExp extends ExpBase {
private final Exp listExp;
public RankedListExp(Exp listExp) {
this.listExp = listExp;
}
public Object clone() {
return this;
}
public int getCategory() {
return listExp.getCategory();
}
public Type getTypeX() {
return listExp.getTypeX();
}
public Exp accept(Validator validator) {
return this;
}
public boolean dependsOn(Dimension dimension) {
return listExp.dependsOn(dimension);
}
public Object evaluate(Evaluator evaluator) {
// Construct an array containing the value of the expression
// for each member.
List members = (List) listExp.evaluate(evaluator);
if (members == null) {
return null;
}
return new RankedList(members);
}
}
/**
* Data structure which contains a list and can return the position of an
* element in the list in O(log N).
*/
static class RankedList {
Map map = new HashMap();
RankedList(List members) {
for (int i = 0; i < members.size(); i++) {
Object o = (Object) members.get(i);
final Object key;
if (o instanceof Member) {
key = o;
} else if (o instanceof Member[]) {
key = Arrays.asList((Member []) o);
} else {
throw Util.newInternal("bad member/tuple " + o);
}
final Object value = map.put(key, new Integer(i));
if (value != null) {
// The list already contained a value for this key -- put
// it back.
map.put(key, value);
}
}
}
int indexOf(Member m) {
return indexOf((Object) m);
}
int indexOf(Member[] tuple) {
return indexOf(Arrays.asList(tuple));
}
private int indexOf(Object o) {
Integer integer = (Integer) map.get(o);
if (integer == null) {
return -1;
} else {
return integer.intValue();
}
}
}
}
// End RankFunDef.java
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?