2012-07-03 3 views
2

를 사용하여 나는 다음과 같은 카산드라 스키마를 가지고 :저장 및 검색을 float []에/카산드라에서 헥터

내가 헥터에 다음과 같은 템플릿을 만들어이 스키마에 부합 데이터를 삽입하기 위해
ColumnFamily: FloatArrays { 
    SCKey: SuperColumn Key (Integer) { 
     Key: FloatArray (float[]) { 
      field (String): value (String) 
     } 
    } 
} 

:

를 (축소) I 생성 (부 테스트)를 FloatArray 직렬화 맞춤 직렬화기에
template = new ThriftSuperCfTemplate<Integer, FloatArray, String>(
    keyspace, "FloatArrays", IntegerSerializer.get(), 
    FloatArraySerializer.get(), StringSerializer.get()); 

:

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

} 

이제 까다로워진다. float 배열을 저장 한 다음 검색하면 동일한 결과가 반환되지 않습니다. 사실 배열의 요소 수는 동일하지 않습니다. 나는 결과를 검색하는 데 사용하는 코드는 다음과 같습니다 :

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

가 나는 카산드라/헥터에 아주 새로운 해요 이후 여기 개념 실수를 하는가? 지금 나는 그것이 잘못되는 부분에 대한 단서조차 갖고 있지 않습니다. Serializer는 괜찮은 것 같습니다. 내 수색을 계속할 수있는 몇 가지 지침을 제게 제공해 주시겠습니까? 많은 감사합니다!

답변

1

나는 당신이 올바른 길에 있다고 생각합니다. 바이트 버퍼가 때때로 그 값이 버퍼에의 오프셋 (offset)로 저장 한

import org.apache.thrift.TBaseHelper; 

     ... 

ByteBuffer aCorrectedByteBuffer = TBaseHelper.rightSize(theByteBufferIWasGiven); 

하지만 직렬 변환기는 오프셋 0에서 바이트 버퍼의 값이 시작된다고 가정하는 것 : 나는 ByteBuffer의 작업 할 때 나는 가끔 문을 필요로 찾을 수 있습니다. Serializer 구현의 가정이 유효하도록 TBaseHelper가 알 수있는 가장 좋은 오프셋을 수정합니다.

배열의 길이와 배열의 길이의 차이는 잘못된 오프셋에서 시작한 결과입니다. 직렬화 된 값의 첫 번째 바이트 또는 두 개에는 배열의 길이가 포함됩니다.

+0

정말 고맙습니다.이 문제가 해결되었습니다. – joost1024

0

Chris 덕분에 문제가 해결되었습니다. 이제 일련 기호는 다음과 같습니다.

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

}