使用Hector存储和检索到Cassandra的float []

时间:2012-07-03 20:39:42

标签: java serialization nosql cassandra hector

我有以下Cassandra架构:

ColumnFamily: FloatArrays {
    SCKey: SuperColumn Key (Integer) {
        Key: FloatArray (float[]) {
            field (String): value (String)
        }
    }
}

为了插入符合此架构的数据,我在Hector中创建了以下模板:

template = new ThriftSuperCfTemplate<Integer, FloatArray, String>(
    keyspace, "FloatArrays", IntegerSerializer.get(),
    FloatArraySerializer.get(), StringSerializer.get());

To(de-)序列化我创建的FloatArray(并进行单元测试)自定义Serializer:

public class FloatArraySerializer extends AbstractSerializer<FloatArray> {

    private static final FloatArraySerializer instance = 
        new FloatArraySerializer();

    public static FloatArraySerializer get() {
        return instance;
    }

    @Override
    public FloatArray fromByteBuffer(ByteBuffer buffer) {
        buffer.rewind();
        FloatBuffer floatBuf = buffer.asFloatBuffer();
        float[] floats = new float[floatBuf.limit()];
        if (floatBuf.hasArray()) {
            floats = floatBuf.array(); 
        } else {
            floatBuf.get(floats, 0, floatBuf.limit());
        }
        return new FloatArray(floats);
    }

    @Override
    public ByteBuffer toByteBuffer(FloatArray theArray) {
        float[] floats = theArray.getFloats();
        ByteBuffer byteBuf = ByteBuffer.allocate(4 * descriptor.length);
        FloatBuffer floatBuf = byteBuf.asFloatBuffer();
        floatBuf.put(floats);
        byteBuf.rewind();
        return byteBuf;
    }

}

现在是棘手的一点。存储然后检索浮动数组不会返回相同的结果。实际上,数组中的元素数量甚至不相同。我用来检索结果的代码如下所示:

SuperCfResult<Integer, FloatArray, String> result = 
    template.querySuperColumns(hash);
for (FloatArray floatArray: result.getSuperColumns()) {
    // Do something with the FloatArrays
}

我在这里犯了一个概念上的错误,因为我对Cassandra / Hector很新吗?现在我甚至都不知道哪里出错了。串行器似乎没问题。能否请您提供一些指示继续我的搜索?非常感谢!

2 个答案:

答案 0 :(得分:1)

我认为你走在正确的轨道上。当我使用ByteBuffers时,我发现我有时需要声明:

import org.apache.thrift.TBaseHelper;

       ... 

ByteBuffer aCorrectedByteBuffer = TBaseHelper.rightSize(theByteBufferIWasGiven);

字节缓冲区有时会将其值作为偏移量存储到其缓冲区中,但是Serializers似乎假设字节缓冲区的值从偏移量0开始.TBaseHelper最好地校正偏移量,因此我可以判断出串行器实现中的假设是有效的。

数组输入和数组输出的长度差异是从错误的偏移量开始的结果。序列化值的第一个或第二个字节包含数组的长度。

答案 1 :(得分:0)

感谢Chris我解决了这个问题。 Serializer现在看起来像这样:

public class FloatArraySerializer extends AbstractSerializer<FloatArray> {

    private static final FloatArraySerializer instance = 
        new FloatArraySerializer();

    public static FloatArraySerializer get() {
        return instance;
    }

    @Override
    public FloatArray fromByteBuffer(ByteBuffer buffer) {
        ByteBuffer rightBuffer = TBaseHelper.rightSize(buffer);  // This does the trick
        FloatBuffer floatBuf = rightBuffer.asFloatBuffer();
        float[] floats = new float[floatBuf.limit()];
        if (floatBuf.hasArray()) {
            floats = floatBuf.array(); 
        } else {
            floatBuf.get(floats, 0, floatBuf.limit());
        }
        return new FloatArray(floats);
    }

    @Override
    public ByteBuffer toByteBuffer(FloatArray theArray) {
        float[] floats = theArray.getDescriptor();
        ByteBuffer byteBuf = ByteBuffer.allocate(4 * descriptor.length);
        FloatBuffer floatBuf = byteBuf.asFloatBuffer();
        floatBuf.put(floats);
        byteBuf.rewind();
        return byteBuf;
    }

}