View Javadoc

1   /*
2    * Copyright (c) 2011.  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(
49                      new Runnable() {
50                          public void run() {
51                              HBqlException outerException = null;
52                              try {
53                                  final ResultScanner scanner = rowRequest.getResultScanner(getMappingContext().getMapping(),
54                                                                                            getWithArgs(),
55                                                                                            getTableWrapper().getHTable());
56                                  for (final Result result : scanner) {
57  
58                                      try {
59                                          if (getClientExpressionTree() != null
60                                              && !getClientExpressionTree().evaluate(getHConnectionImpl(), result))
61                                              continue;
62                                      }
63                                      catch (ResultMissingColumnException e) {
64                                          continue;
65                                      }
66                                      catch (NullColumnValueException e) {
67                                          continue;
68                                      }
69  
70                                      getCompletionQueueExecutor().putElement(result);
71                                  }
72  
73                                  scanner.close();
74                              }
75                              catch (HBqlException e) {
76                                  outerException = e;
77                              }
78                              finally {
79                                  if (outerException != null)
80                                      getCompletionQueueExecutor().addException(outerException);
81  
82                                  getCompletionQueueExecutor().putCompletion();
83                              }
84                          }
85                      });
86          }
87      }
88  
89      public Iterator<T> iterator() {
90  
91          try {
92              return new ResultSetIterator<T, Result>(this) {
93  
94                  protected boolean moreResultsPending() {
95                      return getCompletionQueueExecutor().moreResultsPending();
96                  }
97  
98                  protected Iterator<Result> getNextResultIterator() throws HBqlException {
99                      return null;
100                 }
101 
102                 @SuppressWarnings("unchecked")
103                 protected T fetchNextObject() throws HBqlException {
104 
105                     final ResultAccessor resultAccessor = getMappingContext().getResultAccessor();
106 
107                     // Read data until all jobs have sent DONE tokens
108                     while (true) {
109                         final Result result;
110                         final CompletionQueue.Element<Result> element = getCompletionQueueExecutor().takeElement();
111                         if (element.isCompletionToken()) {
112                             if (!moreResultsPending())
113                                 break;
114                             else
115                                 continue;
116                         }
117                         else {
118                             result = element.getValue();
119                         }
120 
121                         this.incrementReturnedRecordCount();
122 
123                         if (getSelectStmt().isAnAggregateQuery()) {
124                             getAggregateRecord().applyValues(result);
125                         }
126                         else {
127                             final T val = (T)resultAccessor.newObject(getHConnectionImpl(),
128                                                                       getMappingContext(),
129                                                                       getSelectStmt().getSelectElementList(),
130                                                                       getMaxVersions(),
131                                                                       result);
132                             return getQuery().callOnEachRow(val);
133                         }
134                     }
135 
136                     if (getSelectStmt().isAnAggregateQuery() && getAggregateRecord() != null) {
137 
138                         // Stash the value and then null it out for next time through
139                         final AggregateRecord retval = getAggregateRecord();
140                         setAggregateRecord(null);
141 
142                         return getQuery().callOnEachRow((T)retval);
143                     }
144 
145                     this.markIteratorComplete();
146                     return null;
147                 }
148             };
149         }
150         catch (HBqlException e) {
151             e.printStackTrace();
152             getQuery().callOnException(e);
153             return new NullIterator<T>();
154         }
155     }
156 }