001/*
002// This software is subject to the terms of the Eclipse Public License v1.0
003// Agreement, available at the following URL:
004// http://www.eclipse.org/legal/epl-v10.html.
005// You must accept the terms of that agreement to use this software.
006//
007// Copyright (C) 2011-2013 Pentaho and others
008// All Rights Reserved.
009*/
010package mondrian.rolap.cache;
011
012import mondrian.rolap.BitKey;
013import mondrian.rolap.agg.SegmentBuilder;
014import mondrian.server.Execution;
015import mondrian.spi.*;
016import mondrian.util.ByteString;
017
018import java.io.PrintWriter;
019import java.sql.Statement;
020import java.util.List;
021import java.util.Map;
022import java.util.concurrent.Future;
023
024/**
025 * Data structure that identifies which segments contain cells.
026 *
027 * <p>Not thread-safe.</p>
028 *
029 * @author Julian Hyde
030 */
031public interface SegmentCacheIndex {
032    /**
033     * Identifies the segment headers that contain a given cell.
034     *
035     * @param schemaName Schema name
036     * @param schemaChecksum Schema checksum
037     * @param cubeName Cube name
038     * @param measureName Measure name
039     * @param rolapStarFactTableName Fact table table
040     * @param constrainedColsBitKey Bit key
041     * @param coordinates Coordinates
042     * @param compoundPredicates Compound predicates
043     * @return Empty list if not found; never null
044     */
045    List<SegmentHeader> locate(
046        String schemaName,
047        ByteString schemaChecksum,
048        String cubeName,
049        String measureName,
050        String rolapStarFactTableName,
051        BitKey constrainedColsBitKey,
052        Map<String, Comparable> coordinates,
053        List<String> compoundPredicates);
054
055    /**
056     * Returns a list of segments that can be rolled up to satisfy a given
057     * cell request.
058     *
059     * @param schemaName Schema name
060     * @param schemaChecksum Schema checksum
061     * @param cubeName Cube name
062     * @param measureName Measure name
063     * @param rolapStarFactTableName Fact table table
064     * @param constrainedColsBitKey Bit key
065     * @param coordinates Coordinates
066     * @param compoundPredicates Compound predicates
067     *
068     * @return List of candidates; each element is a list of headers that, when
069     * combined using union, are sufficient to answer the given cell request
070     */
071    List<List<SegmentHeader>> findRollupCandidates(
072        String schemaName,
073        ByteString schemaChecksum,
074        String cubeName,
075        String measureName,
076        String rolapStarFactTableName,
077        BitKey constrainedColsBitKey,
078        Map<String, Comparable> coordinates,
079        List<String> compoundPredicates);
080
081    /**
082     * Finds a list of headers that intersect a given region.
083     *
084     * <p>This method is used to find out which headers need to be trimmed
085     * or removed during a flush.</p>
086     *
087     * @param schemaName Schema name
088     * @param schemaChecksum Schema checksum
089     * @param cubeName Cube name
090     * @param measureName Measure name
091     * @param rolapStarFactTableName Fact table table
092     * @param region Region
093     * @return List of intersecting headers
094     */
095    public List<SegmentHeader> intersectRegion(
096        String schemaName,
097        ByteString schemaChecksum,
098        String cubeName,
099        String measureName,
100        String rolapStarFactTableName,
101        SegmentColumn[] region);
102
103    /**
104     * Adds a header to the index.
105     *
106     * <p>If {@code loading} is true, there must follow a call to
107     * {@link #loadSucceeded} or {@link #loadFailed}.</p>
108     *
109     * @param header Segment header
110     * @param loading Whether segment is pending a load from SQL
111     * @param converter Segment converter
112     * @return True or false, if a new element was inserted into the index.
113     */
114    boolean add(
115        SegmentHeader header,
116        boolean loading,
117        SegmentBuilder.SegmentConverter converter);
118
119    /**
120     * Changes the state of a header from loading to loaded.
121     *
122     * <p>The segment must have previously been added by calling {@link #add}
123     * with a not-null value of the {@code bodyFuture} parameter;
124     * neither {@code loadSucceeded} nor {@link #loadFailed} must have been
125     * called.</p>
126     *
127     * <p>Informs anyone waiting on the future supplied with
128     * {@link #add}.</p>
129     *
130     * @param header Segment header
131     * @param body Segment body
132     */
133    void loadSucceeded(
134        SegmentHeader header,
135        SegmentBody body);
136
137    /**
138     * Notifies the segment index that a segment failed to load, and removes the
139     * segment from the index.
140     *
141     * <p>The segment must have previously been added using {@link #add}
142     * with a not-null value of the {@code bodyFuture} parameter;
143     * neither {@link #loadSucceeded} nor {@code loadFailed} must have been
144     * called.</p>
145     *
146     * <p>Informs anyone waiting on the future supplied with
147     * {@link #add}.</p>
148     *
149     * @param header Header
150     * @param throwable Error message
151     */
152    void loadFailed(
153        SegmentHeader header,
154        Throwable throwable);
155
156    /**
157     * Removes a header from the index.
158     *
159     * @param header Segment header
160     */
161    void remove(SegmentHeader header);
162
163    /**
164     * Prints the state of the cache to the given writer.
165     *
166     * @param pw Print writer
167     */
168    void printCacheState(PrintWriter pw);
169
170    /**
171     * Returns a future slot for a segment body, if a segment is currently
172     * loading, otherwise null. This is the method to use to get segments
173     * 'hot out of the oven'.
174     *
175     * <p>When this method is invoked, the execution instance of the
176     * thread is automatically added to the list of clients for the
177     * given segment. The calling code is responsible for calling
178     * {@link #cancel(Execution)} when it is done with the segments,
179     * or else this registration will prevent others from canceling
180     * the running SQL statements associated to this segment.
181     *
182     * @param header Segment header
183     * @return Slot, or null
184     */
185    Future<SegmentBody> getFuture(Execution exec, SegmentHeader header);
186
187    /**
188     * This method must remove all registrations as a client
189     * for the given execution.
190     *
191     * This must terminate all SQL activity for any orphaned
192     * segments.
193     * @param exec The execution to unregister.
194     */
195    void cancel(Execution exec);
196
197    /**
198     * Tells whether or not a given segment is known to this index.
199     */
200    public boolean contains(SegmentHeader header);
201
202    /**
203     * Allows to link a {@link Statement} to a segment. This allows
204     * the index to cleanup when {@link #cancel(Execution)} is
205     * invoked and orphaned segments are left.
206     * @param header The segment.
207     * @param stmt The SQL statement.
208     */
209    public void linkSqlStatement(SegmentHeader header, Statement stmt);
210
211    /**
212     * Returns a converter that can convert the given header to internal
213     * format.
214     *
215     * @param schemaName Schema name
216     * @param schemaChecksum Schema checksum
217     * @param cubeName Cube name
218     * @param rolapStarFactTableName Fact table
219     * @param measureName Measure name
220     * @param compoundPredicates Compound predicates
221     * @return Converter
222     */
223    SegmentBuilder.SegmentConverter getConverter(
224        String schemaName,
225        ByteString schemaChecksum,
226        String cubeName,
227        String rolapStarFactTableName,
228        String measureName,
229        List<String> compoundPredicates);
230
231    /**
232     * Sets a converter that can convert headers in for a given measure to
233     * internal format.
234     *
235     * @param schemaName Schema name
236     * @param schemaChecksum Schema checksum
237     * @param cubeName Cube name
238     * @param rolapStarFactTableName Fact table
239     * @param measureName Measure name
240     * @param compoundPredicates Compound predicates
241     * @param converter Converter to store
242     */
243    void setConverter(
244        String schemaName,
245        ByteString schemaChecksum,
246        String cubeName,
247        String rolapStarFactTableName,
248        String measureName,
249        List<String> compoundPredicates,
250        SegmentBuilder.SegmentConverter converter);
251}
252
253// End SegmentCacheIndex.java