2012-07-03 8 views
2

je le schéma Cassandra suivant:magasin et récupérer un flotteur [] à/de Cassandra avec Hector

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

Afin d'insérer des données qui adhère à ce schéma, j'ai créé le modèle suivant à Hector:

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

Pour (dé) sérialisation du FloatArray j'ai créé (et testée en usine) une coutume sérialiseur:

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

} 

Maintenant vient le peu difficile. Stocker, puis récupérer un tableau de flottants ne retourne pas le même résultat. En fait, le nombre d'éléments dans le tableau n'est même pas le même. Le code que j'utilise pour récupérer le résultat est indiqué ci-dessous:

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

-je faire une erreur conceptuelle ici depuis que je suis tout à fait nouveau pour Cassandra/Hector? À l'heure actuelle, je n'ai même pas la moindre idée de ce qui ne va pas. Le Serializer semble aller bien. Pouvez-vous s'il vous plaît me fournir quelques indications pour continuer ma recherche? Merci beaucoup!

Répondre

1

Je pense que vous êtes sur la bonne voie. Quand je travaille avec ByteBuffers je trouve que je dois parfois la déclaration:

import org.apache.thrift.TBaseHelper; 

     ... 

ByteBuffer aCorrectedByteBuffer = TBaseHelper.rightSize(theByteBufferIWasGiven); 

Le tampon d'octets a parfois sa valeur stockée sous forme d'un décalage dans son tampon, mais les Sérialiseurs semble supposer que la valeur du tampon d'octets commence à l'offset 0. Le TBaseHelper corrige les décalages du mieux que je peux dire afin que les hypothèses dans l'implémentation Serializer soient rendues valides.

La différence entre les longueurs d'entrée et de sortie de tableau résulte du démarrage au décalage incorrect. Le premier octet ou deux de la valeur sérialisée contient la longueur du tableau.

+0

Merci beaucoup Chris, ceci a résolu le problème! – joost1024

0

Grâce à Chris j'ai résolu le problème. Le Serializer ressemble maintenant à ceci:

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

} 
Questions connexes