segment.java
来自「数据仓库展示程序」· Java 代码 · 共 438 行 · 第 1/2 页
JAVA
438 行
* when it finishes loading.
**/
boolean wouldContain(Object[] keys) {
Util.assertTrue(keys.length == axes.length);
for (int i = 0; i < keys.length; i++) {
Object key = keys[i];
if (!axes[i].contains(key)) {
return false;
}
}
return true;
}
/**
* Reads a segment of <code>measure</code>, where <code>columns</code> are
* constrained to <code>values</code>. Each entry in <code>values</code>
* can be null, meaning don't constrain, or can have several values. For
* example, <code>getSegment({Unit_sales}, {Region, State, Year}, {"West"},
* {"CA", "OR", "WA"}, null})</code> returns sales in states CA, OR and WA
* in the Western region, for all years.
*
* @pre segments[i].aggregation == aggregation
**/
static void load(final Segment[] segments,
final BitKey bitKey,
final boolean isDistinct,
final Collection pinnedSegments,
final Aggregation.Axis[] axes) {
String sql = AggregationManager.instance().generateSQL(segments,
bitKey,
isDistinct);
Segment segment0 = segments[0];
RolapStar star = segment0.aggregation.getStar();
RolapStar.Column[] columns = segment0.aggregation.getColumns();
int arity = columns.length;
// execute
ResultSet resultSet = null;
final int measureCount = segments.length;
java.sql.Connection jdbcConnection = star.getJdbcConnection();
try {
resultSet = RolapUtil.executeQuery(
jdbcConnection, sql, "Segment.load");
List rows = new ArrayList();
while (resultSet.next()) {
Object[] row = new Object[arity + measureCount];
// get the columns
int k = 1;
for (int i = 0; i < arity; i++) {
Object o = resultSet.getObject(k++);
if (o == null) {
o = RolapUtil.sqlNullValue;
}
Integer offsetInteger = axes[i].getOffset(o);
if (offsetInteger == null) {
axes[i].addNextOffset(o);
}
row[i] = o;
}
// get the measure
for (int i = 0; i < measureCount; i++) {
Object o = resultSet.getObject(k++);
if (o == null) {
o = Util.nullValue; // convert to placeholder
}
row[arity + i] = o;
}
rows.add(row);
}
// figure out size of dense array, and allocate it (todo: use
// sparse array sometimes)
boolean sparse = false;
int n = 1;
for (int i = 0; i < arity; i++) {
Aggregation.Axis axis = axes[i];
int size = axis.loadKeys();
int previous = n;
n *= size;
if ((n < previous) || (n < size)) {
// Overflow has occurred.
n = Integer.MAX_VALUE;
sparse = true;
}
}
SegmentDataset[] datas = new SegmentDataset[segments.length];
sparse = sparse || useSparse((double) n, (double) rows.size());
for (int i = 0; i < segments.length; i++) {
datas[i] = sparse
? (SegmentDataset) new SparseSegmentDataset(segments[i])
: new DenseSegmentDataset(segments[i], new Object[n]);
}
// now convert the rows into a sparse array
int[] pos = new int[arity];
for (int i = 0, count = rows.size(); i < count; i++) {
Object[] row = (Object[]) rows.get(i);
int k = 0;
for (int j = 0; j < arity; j++) {
k *= axes[j].getKeys().length;
Object o = row[j];
Aggregation.Axis axis = axes[j];
Integer offsetInteger = axis.getOffset(o);
int offset = offsetInteger.intValue();
pos[j] = offset;
k += offset;
}
CellKey key = null;
if (sparse) {
key = new CellKey((int[]) pos.clone());
}
for (int j = 0; j < segments.length; j++) {
final Object o = row[arity + j];
if (sparse) {
((SparseSegmentDataset) datas[j]).put(key, o);
} else {
((DenseSegmentDataset) datas[j]).set(k, o);
}
}
}
for (int i = 0; i < segments.length; i++) {
segments[i].setData(datas[i], pinnedSegments);
}
} catch (SQLException e) {
throw Util.newInternal(e,
"Error while loading segment; sql=[" + sql + "]");
} finally {
try {
if (resultSet != null) {
resultSet.getStatement().close();
resultSet.close();
}
} catch (SQLException e) {
// ignore
}
try {
jdbcConnection.close();
} catch (SQLException e) {
//ignore
}
// Any segments which are still loading have failed.
for (int i = 0; i < segments.length; i++) {
segments[i].setFailed();
}
}
}
/**
* Decides whether to use a sparse representation for this segment, using
* the formula described
* {@link MondrianProperties#SparseSegmentCountThreshold here}.
*
* @param possibleCount Number of values in the space.
* @param actualCount Actual number of values.
* @return Whether to use a sparse representation.
*/
private static boolean useSparse(
final double possibleCount,
final double actualCount) {
final MondrianProperties properties = MondrianProperties.instance();
double densityThreshold = properties.SparseSegmentDensityThreshold.get();
if (densityThreshold < 0) {
densityThreshold = 0;
}
if (densityThreshold > 1) {
densityThreshold = 1;
}
int countThreshold = properties.SparseSegmentCountThreshold.get();
if (countThreshold < 0) {
countThreshold = 0;
}
boolean sparse =
(possibleCount - countThreshold) * densityThreshold > actualCount;
if (possibleCount < countThreshold) {
assert !sparse :
"Should never use sparse if count is less " +
"than threshold, possibleCount=" + possibleCount +
", actualCount=" + actualCount +
", countThreshold=" + countThreshold +
", densityThreshold=" + densityThreshold;
}
if (possibleCount == actualCount) {
assert !sparse :
"Should never use sparse if result is 100% dense: " +
"possibleCount=" + possibleCount +
", actualCount=" + actualCount +
", countThreshold=" + countThreshold +
", densityThreshold=" + densityThreshold;
}
return sparse;
}
/**
* Blocks until this segment has finished loading; if this segment has
* already loaded, returns immediately.
*/
public synchronized void waitUntilLoaded() {
if (!isReady()) {
try {
wait();
} catch (InterruptedException e) {
}
switch (state) {
case State.Ready:
return; // excellent!
case State.Failed:
throw Util.newError("Pending segment failed to load: "
+ toString());
default:
throw State.instance.badValue(state);
}
}
}
}
// End Segment.java
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?