2

我有以下 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());

要(反)序列化我创建(和单元测试)自定义序列化器的 FloatArray:

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 很陌生,所以我在这里犯了一个概念上的错误吗?现在我什至不知道哪里出了问题。序列化器似乎没问题。您能否为我提供一些指示以继续我的搜索?非常感谢!

4

2 回答 2

1

我认为你在正确的轨道上。当我使用 ByteBuffers 时,我发现我有时需要以下语句:

import org.apache.thrift.TBaseHelper;

       ... 

ByteBuffer aCorrectedByteBuffer = TBaseHelper.rightSize(theByteBufferIWasGiven);

字节缓冲区有时会将其值作为偏移量存储到其缓冲区中,但序列化程序似乎假设字节缓冲区的值从偏移量 0 开始。TBaseHelper 尽我所能纠正偏移量,因此序列化程序实现中的假设是有效的.

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

于 2012-07-03T20:53:21.173 回答
0

感谢克里斯,我解决了这个问题。序列化器现在看起来像这样:

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;
    }

}
于 2012-07-04T06:40:49.420 回答