rolaputil.java
来自「数据仓库展示程序」· Java 代码 · 共 443 行 · 第 1/2 页
JAVA
443 行
getQuerySemaphore().leave();
}
}
/**
* Loads a set of JDBC drivers.
*
* @param jdbcDrivers A string consisting of the comma-separated names
* of JDBC driver classes. For example
* <code>"sun.jdbc.odbc.JdbcOdbcDriver,com.mysql.jdbc.Driver"</code>.
*/
public static synchronized void loadDrivers(String jdbcDrivers) {
StringTokenizer tok = new StringTokenizer(jdbcDrivers, ",");
while (tok.hasMoreTokens()) {
String jdbcDriver = tok.nextToken();
if (loadedDrivers.add(jdbcDriver)) {
try {
Class.forName(jdbcDriver);
LOGGER.info("Mondrian: JDBC driver "
+ jdbcDriver + " loaded successfully");
} catch (ClassNotFoundException e) {
LOGGER.error("Mondrian: Warning: JDBC driver "
+ jdbcDriver + " not found");
}
}
}
}
/**
* Writes to a string and also to an underlying writer.
*/
public static class TeeWriter extends FilterWriter {
StringWriter buf = new StringWriter();
public TeeWriter(Writer out) {
super(out);
}
/**
* Returns everything which has been written so far.
*/
public String toString() {
return buf.toString();
}
/**
* Returns the underlying writer.
*/
public Writer getWriter() {
return out;
}
public void write(int c) throws IOException {
super.write(c);
buf.write(c);
}
public void write(char cbuf[]) throws IOException {
super.write(cbuf);
buf.write(cbuf);
}
public void write(char cbuf[], int off, int len) throws IOException {
super.write(cbuf, off, len);
buf.write(cbuf, off, len);
}
public void write(String str) throws IOException {
super.write(str);
buf.write(str);
}
public void write(String str, int off, int len) throws IOException {
super.write(str, off, len);
buf.write(str, off, len);
}
}
/**
* Writer which throws away all input.
*/
private static class NullWriter extends Writer {
public void write(char cbuf[], int off, int len) throws IOException {
}
public void flush() throws IOException {
}
public void close() throws IOException {
}
}
/**
* Creates a {@link TeeWriter} which captures everything which goes through
* {@link #debugOut} from now on.
*/
public static synchronized TeeWriter startTracing() {
TeeWriter tw;
if (debugOut == null) {
tw = new TeeWriter(new NullWriter());
} else {
tw = new TeeWriter(RolapUtil.debugOut);
}
debugOut = new PrintWriter(tw);
return tw;
}
/**
* Gets the semaphore which controls how many people can run queries
* simultaneously.
*/
static synchronized Semaphore getQuerySemaphore() {
if (querySemaphore == null) {
int queryCount = MondrianProperties.instance().QueryLimit.get();
querySemaphore = new Semaphore(queryCount);
}
return querySemaphore;
}
static void getMemberDescendants(MemberReader memberReader,
RolapMember ancestor,
RolapLevel level,
List result,
boolean before,
boolean self,
boolean after) {
// We find the descendants of a member by making breadth-first passes
// down the hierarchy. Initially the list just contains the ancestor.
// Then we find its children. We add those children to the result if
// they fulfill the before/self/after conditions relative to the level.
//
// We add a child to the "fertileMembers" list if some of its children
// might be in the result. Again, this depends upon the
// before/self/after conditions.
//
// Note that for some member readers -- notably the
// RestrictedMemberReader, when it is reading a ragged hierarchy -- the
// children of a member do not always belong to the same level. For
// example, the children of USA include WA (a state) and Washington
// (a city). This is why we repeat the before/self/after logic for
// each member.
final int levelDepth = level.getDepth();
List members = new ArrayList();
members.add(ancestor);
// Each pass, "fertileMembers" has the same contents as "members",
// except that we omit members whose children we are not interested
// in. We allocate it once, and clear it each pass, to save a little
// memory allocation.
List fertileMembers = new ArrayList();
do {
fertileMembers.clear();
for (int i = 0; i < members.size(); i++) {
RolapMember member = (RolapMember) members.get(i);
final int currentDepth = member.getLevel().getDepth();
if (currentDepth == levelDepth) {
if (self) {
result.add(member);
}
if (after) {
// we are interested in member's children
fertileMembers.add(member);
}
} else if (currentDepth < levelDepth) {
if (before) {
result.add(member);
}
fertileMembers.add(member);
} else {
if (after) {
result.add(member);
fertileMembers.add(member);
}
}
}
members.clear();
memberReader.getMemberChildren(fertileMembers, members);
}
while (members.size() > 0);
}
/**
* A <code>Semaphore</code> is a primitive for process synchronization.
*
* <p>Given a semaphore initialized with <code>count</code>, no more than
* <code>count</code> threads can acquire the semaphore using the
* {@link #enter} method. Waiting threads block until enough threads have
* called {@link #leave}.
*/
static class Semaphore {
private int count;
Semaphore(int count) {
if (count < 0) {
count = Integer.MAX_VALUE;
}
this.count = count;
}
synchronized void enter() {
if (count == Integer.MAX_VALUE) {
return;
}
if (count == 0) {
try {
wait();
} catch (InterruptedException e) {
throw Util.newInternal(e, "while waiting for semaphore");
}
}
Util.assertTrue(count > 0);
count--;
}
synchronized void leave() {
if (count == Integer.MAX_VALUE) {
return;
}
count++;
notify();
}
}
}
// End RolapUtil.java
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?