【问题标题】:Store and retrieve a float[] to/from Cassandra using Hector使用 Hector 在 Cassandra 之间存储和检索 float[]
【发布时间】:2012-07-04 08:27:41
【问题描述】:

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

【问题讨论】:

    标签: java serialization nosql cassandra hector


    【解决方案1】:

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

    import org.apache.thrift.TBaseHelper;
    
           ... 
    
    ByteBuffer aCorrectedByteBuffer = TBaseHelper.rightSize(theByteBufferIWasGiven);
    

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

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

    【讨论】:

      【解决方案2】:

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

      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-03-12
        • 2011-11-15
        • 2013-05-23
        • 2015-05-06
        • 2015-03-15
        • 1970-01-01
        • 2013-08-02
        • 2012-01-15
        • 2012-04-23
        相关资源
        最近更新 更多