2009-08-19 3 views
2

Je construis un système, avec C++, qui utilise Tokyo Cabinet (API d'origine en C). Le problème est que je veux stocker une classe telle que:Tokyo Cabinet et objets C++ de taille variable

class Entity { 
     public: 
     string entityName; 
     short type; 
     vector<another_struct> x; 
     vector<another_struct> y 
     vector<string> z; 
    }; 

Le problème est que les vecteurs et les chaînes ont une longueur variable. Quand je passe un vide * (mon objet) à Tokyo Cabinet pour qu'il puisse le stocker, je dois aussi passer la taille de l'objet en octets. Mais cela ne peut pas être trivialement fait.

Quelle est la meilleure façon de déterminer le nombre d'octets d'un objet? Ou quel est le meilleur moyen de stocker des objets de longueur variable dans le Cabinet de Tokyo.

Je suis déjà à la recherche de bibliothèques de sérialisation.

Merci

Répondre

9

Vous ne pouvez pas traiter portably une struct/classe de non-POD C comme une séquence d'octets brute - c'est indépendamment de l'utilisation de pointeurs ou std::string et std::vector, bien que cette dernière pratiquement garantie qu'elle se brisera dans la pratique. Vous devez d'abord sérialiser l'objet en une séquence de caractères - je suggérerais Boost.Serialization pour un bon cadre de sérialisation multiplateformes flexible.

4

Je pense que c'est pire que cela. Le stockage réel pour les vecteurs n'est pas contigu au reste de l'objet. Vous voyez std::vector<> s conserver leurs données dans des allocations distinctes sur le tas (afin qu'ils puissent les développer si nécessaire). Vous aurez besoin d'une API qui comprend C++ et la STL.

En bref. Cela ne va pas fonctionner.

+0

J'ai aussi peur de ça. Je pense que j'ai besoin d'une librairie sérialisation. –

0

J'ai eu un problème similaire bien que j'utilise HDF5. Dans mon cas, il existe une exigence supplémentaire que je peux lire des sous-parties de l'objet et donc la sérialisation n'est pas vraiment une option. HDF ressemble beaucoup à un grand tableau où un index est utilisé pour accéder aux données. La solution que j'utilise est d'ajouter un "index précédent" à la table qui stocke le type another_struct.

Prenant votre exemple, si « x » et « y » avait 3 et 2 éléments chacun, les données seraient stockées comme suit:

[ index ] [ another_struct data here ] [ previous_index ] 
[ 0 ] [  x data 0   ] [ -1 ] 
[ 1 ] [  x data 1   ] [ 0 ] 
[ 2 ] [  x data 2   ] [ 1 ] 
[ 3 ] [  y data 0   ] [ -1 ] 
[ 4 ] [  y data 1   ] [ 3 ] 

Et puis, dans le tableau principal de l'entité, la dernière index ajouté est stocké:

[ index ] [ Entity data here ] [ x ] [ y ] 
[ 0 ] [  ...  ] [ 2 ] [ 4 ] 

Je ne suis pas familier avec le fonctionnement du Cabinet de Tokyo donc bien que cette approche devrait fonctionner, il peut ne pas être optimale pour ce format de données. Idéalement, si vous pouvez avoir des pointeurs vers de vrais objets du Cabinet de Tokyo, alors plutôt que d'utiliser les index comme je l'ai mentionné plus haut, vous pouvez stocker ces pointeurs.

0

oui, vous feriez mieux d'utiliser boost sérialisation ou protobuf pour stériliser l'objet et le mettre dans le Cabinet

0

J'utilise Protocol Buffers pour stocker mes objets C++ en tant que valeurs de données de Tokyo Cabinet.

Dans les tampons de protocole, vous spécifiez la structure et générez le code de marshaling/unmarshalling pour C++, Python et Java. Dans votre cas, le.fichier proto ressemblerait à ceci:

message Entity { 
    optional string entityName = 1; 
    optional int32 type = 2; //protobuf has no short 
    short type = 3; 
    repeated AnotherStruct x = 4; 
    repeated AnotherStruct y = 5; 
    repeated string z = 6; 
}; 

Surtout si la base de données existe sur une longue timespan, un système qui peut être mis à jour, par exemple couvrir de nouveaux champs est très précieux. Contrairement à XML et autres, protobuf est assez rapide.

Questions connexes