2012-07-03 2 views
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 я создал (и протестированы) настраиваемой 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 
} 

ли я сделать концептуальную ошибку здесь, так как я совершенно новой для Кассандры/Hector? Прямо сейчас я даже не знаю, где это происходит. Сериализатор, похоже, в порядке. Не могли бы вы предоставить мне несколько указателей, чтобы продолжить мой поиск? Большое спасибо!

ответ

1

Я думаю, что вы на правильном пути. Когда я работаю с ByteBuffers я нахожу, что иногда нужно заявление:

import org.apache.thrift.TBaseHelper; 

     ... 

ByteBuffer aCorrectedByteBuffer = TBaseHelper.rightSize(theByteBufferIWasGiven); 

буфер байт иногда имеет свое значение, хранимое как смещение в буфере, но сериализаторы, кажется, предполагают, что значение байтный буфер начинается со смещения 0. TBaseHelper исправляет смещения, насколько я могу судить, поэтому допущения в реализации Serializer действительны.

Разница в длинах массива in и array out является результатом начала с неправильного смещения. Первый байт или два сериализованного значения содержат длину массива.

+0

Спасибо, Крис, это решило проблему! – joost1024

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

} 
Смежные вопросы