
com.cloudhopper.datastore.kyoto.KyotoDataStoreIterator Maven / Gradle / Ivy
The newest version!
package com.cloudhopper.datastore.kyoto;
/*
* #%L
* ch-datastore
* %%
* Copyright (C) 2012 Cloudhopper by Twitter
* %%
* Licensed 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.
* #L%
*/
import com.cloudhopper.datastore.DataStoreFatalException;
import com.cloudhopper.datastore.DataStoreIterator;
import kyotocabinet.Cursor;
import kyotocabinet.DB;
import kyotocabinet.Error;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* DateStoreIterator for Kyoto Cabinet that uses a Cursor, and assumes a .kct
* database type.
*
* @author garth
*/
public class KyotoDataStoreIterator implements DataStoreIterator {
private final static Logger logger = LoggerFactory.getLogger(KyotoDataStoreIterator.class);
private final DB db;
private Cursor cursor;
private boolean firstNextCall;
public KyotoDataStoreIterator(DB db) {
this.db = db;
this.cursor = db.cursor();
// flag to indicate this is the first call to next()
this.firstNextCall = true;
}
public boolean next() throws DataStoreFatalException {
// kyoto cabinet does things a little different in that the first record
// is already selected by default -- our interface says that you need
// to call next() first, so we will only call next on calls after the
// first one
if (this.firstNextCall) {
this.firstNextCall = false;
// Jump the cursor to the first record for forward scan.
return this.cursor.jump();
} else {
// Step the cursor to the next record.
return cursor.step();
}
}
public boolean jump(byte[] key) throws DataStoreFatalException {
if (this.firstNextCall) this.firstNextCall = false;
boolean jumped = this.cursor.jump(key);
if (!jumped) {
Error e = db.error();
if (e != null) logger.debug("DataStoreIterator failed to jump to record {} {}", new String(key), errorToString(e));
}
return jumped;
}
public Record getRecord() throws DataStoreFatalException {
byte[] key = cursor.get_key(false);
byte[] value = cursor.get_value(false);
if (key == null) {
Error e = db.error();
if (e != null) logger.warn("Kyoto reporting error {}", errorToString(e));
throw new DataStoreFatalException("Record key was null", e);
}
if (value == null) {
Error e = db.error();
if (e != null) logger.warn("Kyoto reporting error {}", errorToString(e));
throw new DataStoreFatalException("Record value for key "+new String(key)+" was null", e);
}
return new Record(key, value);
}
public void close() throws DataStoreFatalException {
// This method should be called explicitly when the cursor is no longer in use.
cursor.disable();
cursor = null;
}
private String errorToString(Error e) {
return new StringBuilder()
.append("[code=")
.append(e.code())
.append(", name=")
.append(e.name())
.append(", message=")
.append(e.message())
.append("]")
.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy