001    /*
002    // $Id: //open/mondrian/src/main/mondrian/rolap/agg/AggregationKey.java#3 $
003    // This software is subject to the terms of the Common Public License
004    // Agreement, available at the following URL:
005    // http://www.opensource.org/licenses/cpl.html.
006    // Copyright (C) 2005-2008 Julian Hyde and others
007    // All Rights Reserved.
008    // You must accept the terms of that agreement to use this software.
009    */
010    package mondrian.rolap.agg;
011    
012    import java.util.ArrayList;
013    import java.util.List;
014    import java.util.Map;
015    
016    import mondrian.rolap.BitKey;
017    import mondrian.rolap.RolapStar;
018    import mondrian.rolap.StarPredicate;
019    
020    /**
021     * This class defines the column context that an Aggregation is computed for.
022     * Column context has two components:
023     *   -- the column constraints which define the dimentionality of an
024     *   Aggregation
025     *   -- an orthogonal context for which the measures are defined. This context
026     *   is sometimes referred to as the compound member predicates, and usually of
027     *   the shape:
028     *      OR(AND(column predicates))
029     *   Any column is only used in either column context or compound context, not
030     *   both.
031     * @author Rushan Chen
032     * @version $Id: //open/mondrian/src/main/mondrian/rolap/agg/AggregationKey.java#3 $
033     */
034    public class AggregationKey
035    {
036        /**
037         * This is needed because for a Virtual Cube: two CellRequests
038         * could have the same BitKey but have different underlying
039         * base cubes. Without this, one get the result in the
040         * SegmentArrayQuerySpec addMeasure Util.assertTrue being
041         * triggered (which is what happened).
042         */
043        private final RolapStar star;
044    
045        private final BitKey constrainedColumnsBitKey;
046    
047        /*
048        * This map must be deternimistic; otherwise different runs generate SQL
049        * statements in different orders.
050        *
051         * TODO: change this to SortedMap to speed up comparison.
052         */
053        private final Map<BitKey, StarPredicate> compoundPredicateMap;
054    
055        public AggregationKey(CellRequest request) {
056            this.constrainedColumnsBitKey = request.getConstrainedColumnsBitKey();
057            this.star = request.getMeasure().getStar();
058            compoundPredicateMap = request.getCompoundPredicateMap();
059        }
060    
061        public int hashCode() {
062            int retCode =
063                constrainedColumnsBitKey.hashCode() ^ star.hashCode();
064            if (compoundPredicateMap != null) {
065                for (BitKey bitKey : compoundPredicateMap.keySet()) {
066                    retCode ^= bitKey.hashCode();
067                }
068            }
069            return retCode;
070        }
071    
072        public boolean hasSameCompoundPredicate(AggregationKey otherKey) {
073            boolean isEqual = false;
074            if (compoundPredicateMap.size() ==
075                    otherKey.compoundPredicateMap.size()) {
076                isEqual = true;
077                for (BitKey bitKey : compoundPredicateMap.keySet()) {
078                    StarPredicate thisPred =
079                        compoundPredicateMap.get(bitKey);
080                    StarPredicate otherPred =
081                        otherKey.compoundPredicateMap.get(bitKey);
082                    if (thisPred == null || otherPred == null ||
083                        !thisPred.equalConstraint(otherPred)) {
084                        isEqual = false;
085                        break;
086                    }
087                }
088            }
089            return isEqual;
090        }
091    
092        public boolean equals(Object other) {
093            if (other instanceof AggregationKey) {
094                AggregationKey otherKey = (AggregationKey) other;
095                if (constrainedColumnsBitKey.equals(otherKey.constrainedColumnsBitKey) &&
096                    star.equals(otherKey.star) &&
097                    hasSameCompoundPredicate(otherKey)) {
098                    return true;
099                }
100            }
101            return false;
102        }
103    
104        public String toString() {
105            return
106                star.getFactTable().getTableName() + " " +
107                constrainedColumnsBitKey.toString() + "\n" +
108                compoundPredicateMap.toString();
109        }
110    
111        public BitKey getConstrainedColumnsBitKey() {
112            return constrainedColumnsBitKey;
113        }
114    
115        public RolapStar getStar() {
116            return star;
117        }
118    
119        /**
120         * Get the set of compound predicates
121         * @return list of predicates
122         */
123        public List<StarPredicate> getCompoundPredicateList() {
124            return (new ArrayList<StarPredicate>(compoundPredicateMap.values()));
125        }
126    
127    }
128    
129    // End AggregationKey.java