View Javadoc

1   /*
2    * Copyright 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.rest;
22  
23  import java.io.IOException;
24  import java.util.Iterator;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.apache.hadoop.hbase.KeyValue;
29  import org.apache.hadoop.hbase.UnknownScannerException;
30  import org.apache.hadoop.hbase.client.HTableInterface;
31  import org.apache.hadoop.hbase.client.HTablePool;
32  import org.apache.hadoop.hbase.client.Result;
33  import org.apache.hadoop.hbase.client.ResultScanner;
34  import org.apache.hadoop.hbase.client.Scan;
35  import org.apache.hadoop.hbase.filter.Filter;
36  import org.apache.hadoop.hbase.rest.model.ScannerModel;
37  import org.apache.hadoop.util.StringUtils;
38  
39  public class ScannerResultGenerator extends ResultGenerator {
40  
41    private static final Log LOG =
42      LogFactory.getLog(ScannerResultGenerator.class);
43  
44    public static Filter buildFilterFromModel(final ScannerModel model) 
45        throws Exception {
46      String filter = model.getFilter();
47      if (filter == null || filter.length() == 0) {
48        return null;
49      }
50      return buildFilter(filter);
51    }
52  
53    private String id;
54    private Iterator<KeyValue> rowI;
55    private KeyValue cache;
56    private ResultScanner scanner;
57    private Result cached;
58  
59    public ScannerResultGenerator(final String tableName, final RowSpec rowspec,
60        final Filter filter) throws IllegalArgumentException, IOException {
61      HTablePool pool = RESTServlet.getInstance().getTablePool(); 
62      HTableInterface table = pool.getTable(tableName);
63      try {
64        Scan scan;
65        if (rowspec.hasEndRow()) {
66          scan = new Scan(rowspec.getStartRow(), rowspec.getEndRow());
67        } else {
68          scan = new Scan(rowspec.getStartRow());
69        }
70        if (rowspec.hasColumns()) {
71          byte[][] columns = rowspec.getColumns();
72          for (byte[] column: columns) {
73            byte[][] split = KeyValue.parseColumn(column);
74            if (split.length > 1 && (split[1] != null && split[1].length != 0)) {
75              scan.addColumn(split[0], split[1]);
76            } else {
77              scan.addFamily(split[0]);
78            }
79          }
80        }
81        scan.setTimeRange(rowspec.getStartTime(), rowspec.getEndTime());          
82        scan.setMaxVersions(rowspec.getMaxVersions());
83        if (filter != null) {
84          scan.setFilter(filter);
85        }
86        // always disable block caching on the cluster when scanning
87        scan.setCacheBlocks(false);
88        scanner = table.getScanner(scan);
89        cached = null;
90        id = Long.toString(System.currentTimeMillis()) +
91               Integer.toHexString(scanner.hashCode());
92      } finally {
93        table.close();
94      }
95    }
96  
97    public String getID() {
98      return id;
99    }
100 
101   public void close() {
102     if (scanner != null) {
103       scanner.close();
104       scanner = null;
105     }
106   }
107 
108   public boolean hasNext() {
109     if (cache != null) {
110       return true;
111     }
112     if (rowI != null && rowI.hasNext()) {
113       return true;
114     }
115     if (cached != null) {
116       return true;
117     }
118     try {
119       Result result = scanner.next();
120       if (result != null && !result.isEmpty()) {
121         cached = result;
122       }
123     } catch (UnknownScannerException e) {
124       throw new IllegalArgumentException(e);
125     } catch (IOException e) {
126       LOG.error(StringUtils.stringifyException(e));
127     }
128     return cached != null;
129   }
130 
131   public KeyValue next() {
132     if (cache != null) {
133       KeyValue kv = cache;
134       cache = null;
135       return kv;
136     }
137     boolean loop;
138     do {
139       loop = false;
140       if (rowI != null) {
141         if (rowI.hasNext()) {
142           return rowI.next();
143         } else {
144           rowI = null;
145         }
146       }
147       if (cached != null) {
148         rowI = cached.list().iterator();
149         loop = true;
150         cached = null;
151       } else {
152         Result result = null;
153         try {
154           result = scanner.next();
155         } catch (UnknownScannerException e) {
156           throw new IllegalArgumentException(e);
157         } catch (IOException e) {
158           LOG.error(StringUtils.stringifyException(e));
159         }
160         if (result != null && !result.isEmpty()) {
161           rowI = result.list().iterator();
162           loop = true;
163         }
164       }
165     } while (loop);
166     return null;
167   }
168 
169   public void putBack(KeyValue kv) {
170     this.cache = kv;
171   }
172 
173   public void remove() {
174     throw new UnsupportedOperationException("remove not supported");
175   }
176 }