package org.apache.blur.manager.results;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicLongArray;
import org.apache.blur.log.Log;
import org.apache.blur.log.LogFactory;
import org.apache.blur.thrift.BlurClientManager;
import org.apache.blur.thrift.Connection;
import org.apache.blur.thrift.generated.Blur;
import org.apache.blur.thrift.generated.Blur.Client;
import org.apache.blur.thrift.generated.BlurException;
import org.apache.blur.thrift.generated.BlurQuery;
import org.apache.blur.thrift.generated.BlurResult;
import org.apache.blur.thrift.generated.BlurResults;
import org.apache.blur.utils.BlurIterator;
public class BlurResultIterableClient implements BlurResultIterable {
private static final Log LOG = LogFactory.getLog(BlurResultIterableClient.class);
private final Map<String, Long> _shardInfo = new TreeMap<String, Long>();
private final Client _client;
private final String _table;
private final BlurQuery _originalQuery;
private final Connection _connection;
private final int _remoteFetchCount;
private final AtomicLongArray _facetCounts;
private BlurResults _results;
private int _batch = 0;
private long _totalResults;
private long _skipTo;
private boolean _alreadyProcessed;
public BlurResultIterableClient(Connection connection, Blur.Client client, String table, BlurQuery query,
AtomicLongArray facetCounts, int remoteFetchCount) throws BlurException {
_connection = connection;
_client = client;
_table = table;
_facetCounts = facetCounts;
_originalQuery = query;
_remoteFetchCount = remoteFetchCount;
performSearch();
}
public Client getClient() {
return _client;
}
private void performSearch() throws BlurException {
try {
long cursor = _remoteFetchCount * _batch;
BlurQuery blurQuery = new BlurQuery(_originalQuery.query, _originalQuery.facets, null,
_originalQuery.useCacheIfPresent, cursor, _remoteFetchCount, _originalQuery.minimumNumberOfResults,
_originalQuery.maxQueryTime, _originalQuery.uuid, _originalQuery.userContext, _originalQuery.cacheResult,
_originalQuery.startTime, _originalQuery.getSortFields(), _originalQuery.getRowId());
_results = makeLazy(_client.query(_table, blurQuery));
addFacets();
_totalResults = _results.totalResults;
_shardInfo.putAll(_results.shardInfo);
_batch++;
} catch (BlurException e) {
throw e;
} catch (Exception e) {
LOG.error("Error during for [{0}]", e, _originalQuery);
throw new RuntimeException(e);
}
}
private BlurResults makeLazy(BlurResults results) {
List<BlurResult> list = results.results;
for (int i = 0; i < list.size(); i++) {
BlurResult blurResult = list.get(i);
if (blurResult != null) {
list.set(i, new LazyBlurResult(blurResult, _client));
}
}
return results;
}
private void addFacets() {
if (!_alreadyProcessed) {
List<Long> counts = _results.facetCounts;
if (counts != null) {
int size = counts.size();
for (int i = 0; i < size; i++) {
_facetCounts.addAndGet(i, counts.get(i));
}
}
_alreadyProcessed = true;
}
}
@Override
public Map<String, Long> getShardInfo() {
return _shardInfo;
}
@Override
public long getTotalResults() {
return _totalResults;
}
@Override
public void skipTo(long skipTo) {
this._skipTo = skipTo;
}
@Override
public BlurIterator<BlurResult, BlurException> iterator() throws BlurException {
SearchIterator iterator = new SearchIterator();
long start = 0;
while (iterator.hasNext() && start < _skipTo) {
iterator.next();
start++;
}
return iterator;
}
public class SearchIterator implements BlurIterator<BlurResult, BlurException> {
private long _position = 0;
private int _relposition = 0;
@Override
public boolean hasNext() {
if (_position < _originalQuery.minimumNumberOfResults && _position < _totalResults) {
return true;
}
return false;
}
@Override
public BlurResult next() throws BlurException {
if (_relposition >= _results.results.size()) {
performSearch();
_relposition = 0;
}
_position++;
return _results.results.get(_relposition++);
}
@Override
public long getPosition() throws BlurException {
return _position;
}
}
@Override
public void close() throws IOException {
BlurClientManager.returnClient(_connection, _client);
}
}