View Javadoc

1   /*
2    * Copyright (c) 2010.  The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package org.apache.hadoop.hbase.hbql.impl;
22  
23  import org.apache.expreval.client.NullColumnValueException;
24  import org.apache.expreval.client.ResultMissingColumnException;
25  import org.apache.hadoop.hbase.client.Result;
26  import org.apache.hadoop.hbase.client.ResultScanner;
27  import org.apache.hadoop.hbase.hbql.client.HBqlException;
28  import org.apache.hadoop.hbase.hbql.mapping.ResultAccessor;
29  import org.apache.hadoop.hbase.hbql.statement.select.RowRequest;
30  import org.apache.hadoop.hbase.hbql.util.CompletionQueue;
31  import org.apache.hadoop.hbase.hbql.util.NullIterator;
32  
33  import java.util.Iterator;
34  import java.util.List;
35  
36  
37  public class ResultExecutorResultSet<T> extends HResultSetImpl<T, Result> {
38  
39      ResultExecutorResultSet(final Query<T> query, final ResultExecutor executor) throws HBqlException {
40          super(query, executor);
41      }
42  
43      protected void submitWork(final List<RowRequest> rowRequestList) {
44  
45          // This will submit jobs until a job is rejected, at which point, execution will take place in
46          // the context of this thread
47          for (final RowRequest rowRequest : rowRequestList) {
48              this.getCompletionQueueExecutor().submitWorkToThreadPool(new Runnable() {
49                  public void run() {
50                      HBqlException outerException = null;
51                      try {
52                          final ResultScanner scanner = rowRequest.getResultScanner(getMappingContext().getMapping(),
53                                                                                    getWithArgs(),
54                                                                                    getTableWrapper().getHTable());
55                          for (final Result result : scanner) {
56  
57                              try {
58                                  if (getClientExpressionTree() != null
59                                      && !getClientExpressionTree().evaluate(getHConnectionImpl(), result))
60                                      continue;
61                              }
62                              catch (ResultMissingColumnException e) {
63                                  continue;
64                              }
65                              catch (NullColumnValueException e) {
66                                  continue;
67                              }
68  
69                              getCompletionQueueExecutor().putElement(result);
70                          }
71  
72                          scanner.close();
73                      }
74                      catch (HBqlException e) {
75                          outerException = e;
76                      }
77                      finally {
78                          if (outerException != null)
79                              getCompletionQueueExecutor().addException(outerException);
80  
81                          getCompletionQueueExecutor().putCompletion();
82                      }
83                  }
84              });
85          }
86      }
87  
88      public Iterator<T> iterator() {
89  
90          try {
91              return new ResultSetIterator<T, Result>(this) {
92  
93                  protected boolean moreResultsPending() {
94                      return getCompletionQueueExecutor().moreResultsPending();
95                  }
96  
97                  protected Iterator<Result> getNextResultIterator() throws HBqlException {
98                      return null;
99                  }
100 
101                 @SuppressWarnings("unchecked")
102                 protected T fetchNextObject() throws HBqlException {
103 
104                     final ResultAccessor resultAccessor = getMappingContext().getResultAccessor();
105 
106                     // Read data until all jobs have sent DONE tokens
107                     while (true) {
108                         final Result result;
109                         final CompletionQueue.Element<Result> element = getCompletionQueueExecutor().takeElement();
110                         if (element.isCompletionToken()) {
111                             if (!moreResultsPending())
112                                 break;
113                             else
114                                 continue;
115                         }
116                         else {
117                             result = element.getValue();
118                         }
119 
120                         this.incrementReturnedRecordCount();
121 
122                         if (getSelectStmt().isAnAggregateQuery()) {
123                             getAggregateRecord().applyValues(result);
124                         }
125                         else {
126                             final T val = (T)resultAccessor.newObject(getHConnectionImpl(),
127                                                                       getMappingContext(),
128                                                                       getSelectStmt().getSelectElementList(),
129                                                                       getMaxVersions(),
130                                                                       result);
131                             return getQuery().callOnEachRow(val);
132                         }
133                     }
134 
135                     if (getSelectStmt().isAnAggregateQuery() && getAggregateRecord() != null) {
136 
137                         // Stash the value and then null it out for next time through
138                         final AggregateRecord retval = getAggregateRecord();
139                         setAggregateRecord(null);
140 
141                         return getQuery().callOnEachRow((T)retval);
142                     }
143 
144                     this.markIteratorComplete();
145                     return null;
146                 }
147             };
148         }
149         catch (HBqlException e) {
150             e.printStackTrace();
151             getQuery().callOnException(e);
152             return new NullIterator<T>();
153         }
154     }
155 }