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   }
103 
104   public boolean hasNext() {
105     if (cache != null) {
106       return true;
107     }
108     if (rowI != null && rowI.hasNext()) {
109       return true;
110     }
111     if (cached != null) {
112       return true;
113     }
114     try {
115       Result result = scanner.next();
116       if (result != null && !result.isEmpty()) {
117         cached = result;
118       }
119     } catch (UnknownScannerException e) {
120       throw new IllegalArgumentException(e);
121     } catch (IOException e) {
122       LOG.error(StringUtils.stringifyException(e));
123     }
124     return cached != null;
125   }
126 
127   public KeyValue next() {
128     if (cache != null) {
129       KeyValue kv = cache;
130       cache = null;
131       return kv;
132     }
133     boolean loop;
134     do {
135       loop = false;
136       if (rowI != null) {
137         if (rowI.hasNext()) {
138           return rowI.next();
139         } else {
140           rowI = null;
141         }
142       }
143       if (cached != null) {
144         rowI = cached.list().iterator();
145         loop = true;
146         cached = null;
147       } else {
148         Result result = null;
149         try {
150           result = scanner.next();
151         } catch (UnknownScannerException e) {
152           throw new IllegalArgumentException(e);
153         } catch (IOException e) {
154           LOG.error(StringUtils.stringifyException(e));
155         }
156         if (result != null && !result.isEmpty()) {
157           rowI = result.list().iterator();
158           loop = true;
159         }
160       }
161     } while (loop);
162     return null;
163   }
164 
165   public void putBack(KeyValue kv) {
166     this.cache = kv;
167   }
168 
169   public void remove() {
170     throw new UnsupportedOperationException("remove not supported");
171   }
172 }