smartmemberreader.java

来自「数据仓库展示程序」· Java 代码 · 共 576 行 · 第 1/2 页

JAVA
576
字号
        return mapLevelToMembers.get(level) != null;
    }

    public synchronized void putChildren(RolapMember member, List children) {
        ChildrenList childrenList = new ChildrenList(member, children);
        SoftReference ref = new SoftReference(childrenList);
        mapMemberToChildren.put(member, ref);
    }

    // synchronization: Must synchronize, because uses mapMemberToChildren
    public synchronized RolapMember getLeadMember(RolapMember member, int n) {
        if (n == 0 || member.isNull()) {
            return member;
        } else {
            SiblingIterator iter = new SiblingIterator(this, member);
            if (n > 0) {
                RolapMember sibling = null;
                while (n-- > 0) {
                    if (!iter.hasNext()) {
                        return (RolapMember) member.getHierarchy().getNullMember();
                    }
                    sibling = iter.nextMember();
                }
                return sibling;
            } else {
                n = -n;
                RolapMember sibling = null;
                while (n-- > 0) {
                    if (!iter.hasPrevious()) {
                        return (RolapMember) member.getHierarchy().getNullMember();
                    }
                    sibling = iter.previousMember();
                }
                return sibling;
            }
        }
    }

    public void getMemberRange(RolapLevel level, 
                               RolapMember startMember, 
                               RolapMember endMember, 
                               List list) {
        Util.assertPrecondition(startMember != null, "startMember != null");
        Util.assertPrecondition(endMember != null, "endMember != null");
        Util.assertPrecondition(startMember.getLevel() == endMember.getLevel(),
                "startMember.getLevel() == endMember.getLevel()");

        if (compare(startMember, endMember, false) > 0) {
            return;
        }
        list.add(startMember);
        if (startMember == endMember) {
            return;
        }
        SiblingIterator siblings = new SiblingIterator(this, startMember);
        while (siblings.hasNext()) {
            final RolapMember member = siblings.nextMember();
            list.add(member);
            if (member == endMember) {
                return;
            }
        }
        throw Util.newInternal("sibling iterator did not hit end point, start="
                + startMember 
                + ", end=" 
                + endMember);
    }

    /*
    public void _getMemberRange(
            RolapLevel level, RolapMember startMember, RolapMember endMember, List list) {
        // todo: Use a more efficient algorithm, which makes less use of
        // bounds.
        Util.assertTrue(level == startMember.getLevel());
        Util.assertTrue(level == endMember.getLevel());
        // "m" is the lowest member which is an ancestor of both "startMember"
        // and "endMember". If "startMember" == "endMember", then "m" is
        // "startMember".
        RolapMember m = endMember;
        while (m != null) {
            if (compare(m, startMember, false) <= 0) {
                break;
            }
            m = (RolapMember) m.getParentMember();
        }
        _getDescendants(m, startMember.getLevel(), startMember, endMember, list);
    }
    */

    /**
     * Returns the descendants of <code>member</code> at <code>level</code>
     * whose ordinal is between <code>startOrdinal</code> and
     * <code>endOrdinal</code>.
     **/
    /*
    private void _getDescendants(
            RolapMember member, Level level, RolapMember startMember,
            RolapMember endMember, List result) {
        // todo: Make algortihm more efficient: Use binary search.
        List members = new ArrayList();
        members.add(member);
        while (true) {
            ArrayList children = new ArrayList();
            getMemberChildren(members, children);
            int count = children.size(),
                    start,
                    end;
            if (startMember == null) {
                start = 0;
            } else {
                start = count;
                for (int i = 0; i < count; i++) {
                    final RolapMember m = (RolapMember) children.get(i);
                    if (compare(m, startMember, false) >= 0) {
                        start = i;
                        break;
                    }
                }
            }
            if (endMember == null) {
                end = count;
            } else {
                end = count;
                for (int i = start; i < count; i++) {
                    final RolapMember m = (RolapMember) children.get(i);
                    if (compare(m, endMember, false) >= 0) {
                        end = i;
                        break;
                    }
                }
            }
            List trimmedChildren = children.subList(start, end);
            if (trimmedChildren.isEmpty() ||
                    ((RolapMember) children.get(0)).getLevel() == level) {
                result.addAll(trimmedChildren);
                return;
            }
            members = trimmedChildren;
        }
    }
    */

    public int getMemberCount() {
        return source.getMemberCount();
    }

    public int compare(RolapMember m1, 
                       RolapMember m2, 
                       boolean siblingsAreEqual) { 
        if (m1 == m2) {
            return 0;
        }
        if (m1.getParentMember() == m2.getParentMember()) {
            // including case where both parents are null
            if (siblingsAreEqual) {
                return 0;
            } else {
                List children = new ArrayList();
                getMemberChildren((RolapMember) m1.getParentMember(), children);
                int pos1 = -1, pos2 = -1;
                for (int i = 0, n = children.size(); i < n; i++) {
                    RolapMember child = (RolapMember) children.get(i);
                    if (child == m1) {
                        pos1 = i;
                    }
                    if (child == m2) {
                        pos2 = i;
                    }
                }
                if (pos1 == -1) {
                    throw Util.newInternal(m1 + " not found among siblings");
                }
                if (pos2 == -1) {
                    throw Util.newInternal(m2 + " not found among siblings");
                }
                Util.assertTrue(pos1 != pos2);
                return pos1 < pos2 ? -1 : 1;
            }
        }
        int levelDepth1 = m1.getLevel().getDepth();
        int levelDepth2 = m2.getLevel().getDepth();
        if (levelDepth1 < levelDepth2) {
            final int c = compare(m1, (RolapMember) m2.getParentMember(), false);
            return (c == 0) ? -1 : c;

        } else if (levelDepth1 > levelDepth2) {
            final int c = compare((RolapMember) m1.getParentMember(), m2, false);
            return (c == 0) ? 1 : c;

        } else {
            return compare((RolapMember) m1.getParentMember(), (RolapMember) m2.getParentMember(), false);
        }
    }

    public void getMemberDescendants(RolapMember member, 
                                     List result, 
                                     RolapLevel level, 
                                     boolean before, 
                                     boolean self, 
                                     boolean after) {
        RolapUtil.getMemberDescendants(this, member, level, result,
                before, self, after);
    }

    /**
     * <code>SiblingIterator</code> helps traverse a hierarchy of members, by
     * remembering the position at each level. Each SiblingIterator has a
     * parent, to which it defers when the last child of the current member is
     * reached.
     */
    class SiblingIterator {
        private final MemberReader reader;
        private final SiblingIterator parentIterator;
        private RolapMember[] siblings;
        private int position;

        SiblingIterator(MemberReader reader, RolapMember member) {
            this.reader = reader;
            RolapMember parent = (RolapMember) member.getParentMember();
            List siblingList;
            if (parent == null) {
                siblingList = reader.getRootMembers();
                this.parentIterator = null;
            } else {
                siblingList = new ArrayList();
                reader.getMemberChildren(parent, siblingList);
                this.parentIterator = new SiblingIterator(reader, parent);
            }
            this.siblings = RolapUtil.toArray(siblingList);
            this.position = -1;
            for (int i = 0; i < this.siblings.length; i++) {
                if (siblings[i] == member) {
                    this.position = i;
                    break;
                }
            }
            if (this.position == -1) {
                throw Util.newInternal(
                    "member " + member + " not found among its siblings");
            }
        }
        boolean hasNext() {
            return (this.position < this.siblings.length - 1) ||
                (parentIterator != null) &&
                parentIterator.hasNext();
        }
        Object next() {
            return nextMember();
        }
        RolapMember nextMember() {
            if (++this.position >= this.siblings.length) {
                if (parentIterator == null) {
                    throw Util.newInternal("there is no next member");
                }
                RolapMember parent = parentIterator.nextMember();
                List siblingList = new ArrayList();
                reader.getMemberChildren(parent, siblingList);
                this.siblings = RolapUtil.toArray(siblingList);
                this.position = 0;
            }
            return this.siblings[this.position];
        }
        boolean hasPrevious() {
            return (this.position > 0) ||
                (parentIterator != null) &&
                parentIterator.hasPrevious();
        }
        Object previous() {
            return previousMember();
        }
        RolapMember previousMember() {
            if (--this.position < 0) {
                if (parentIterator == null) {
                    throw Util.newInternal("there is no next member");
                }
                RolapMember parent = parentIterator.previousMember();
                List siblingList = new ArrayList();
                reader.getMemberChildren(parent, siblingList);
                this.siblings = RolapUtil.toArray(siblingList);
                this.position = this.siblings.length - 1;
            }
            return this.siblings[this.position];
        }
    }
}

// End SmartMemberReader.java

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?