7
votes

Quelle est la mise en œuvre recommandée pour la hausse des variantes OLE?

Les variantes OLE, telles qu'utilisées par des versions plus anciennes de Visual Basic et de Pervyivement dans Com Automation, peuvent stocker de nombreux types différents: types de base tels que des entiers et des flotteurs, des types plus compliqués tels que des chaînes et des tableaux, ainsi que tout le cas > IDISPATCH implémentations et pointeurs sous la forme de byref variantes.

Les variantes sont également faiblement dactylographiées: elles convertissent la valeur à un autre type sans avertissement en fonction de l'opérateur que vous appliquez et quels sont les types actuels des valeurs transmises à l'opérateur. Par exemple, comparer deux variantes, on contenant l'entier 1 et un autre contenant la chaîne "1" , car l'égalité retournera vrai .

supposant que je travaille avec des variantes au niveau des données sous-jacentes (par exemple, variante en C ++ ou TVARDATA dans Delphi - c'est-à-dire la grande union de différentes valeurs possibles) , comment devrais-je les variantes de hachage de manière cohérente afin qu'ils obéissent aux bonnes règles?

RÈGLES:

  • Les variantes que HASH devraient comparer inégalement comme inégale, à la fois dans le tri et l'égalité directe
  • variantes qui comparent comme étant égales pour le tri et l'égalité directe doivent hacher comme étant égale

    C'est bon si je dois utiliser différentes règles de tri et de comparaison directe afin de rendre la hache en forme.

    La façon dont je travaille actuellement est que je normalise les variantes aux chaînes (s'ils en conviennent) et je les traite comme des chaînes, sinon je travaille avec les variantes de données comme s'il s'agissait d'une blob opaque et de hachage et comparer ses octets bruts. Qui a des limitations, bien sûr: chiffres 1..10 trier comme [1, 10, 2, ... 9] etc. C'est légèrement ennuyeux, mais il est cohérent et c'est très peu de travail. Cependant, je me demande s'il y a une pratique acceptée pour ce problème.


12 commentaires

La variante est en fait une structure, qui a deux morceaux de valeur et de type de données. Votre demande de comparaison et de conversion semble prendre en considération la valeur que la valeur et ne regarde pas le type déposé de cette structure. La bonne approche est de toujours considérer le type déposé également.


@Franci, je pense que tu as manqué le point. Deux variantes peuvent comparer égales même lorsque leurs types diffèrent. Si les variantes se comparent égales, alors Barry souhaite également être égale à leurs hayes. variante (1) = variante ('1') ==> hachage (variante (1)) = hachage (variante ('1')) .


Barry, je ne pense pas que votre première règle a raison. Il ignore la possibilité de collisions de hasch, où les hachages sont égaux, mais les valeurs ne sont pas du tout similaires.


Vous avez raison @rob, je voulais dire l'inverse - j'ai inversé. Bien que je pense que cela découle réellement de la deuxième règle.


Non, je n'ai pas manqué le point de Barry. Mais ses revendications de conversion et de comparaison au paragraphe 2 de la question sont erronées. Deux variantes ne peuvent pas comparer égales, si leurs types diffèrent. Il doit y avoir une conversion avant la comparaison (qui dans le monde COM est explicite, mais dans la VB et Delphes peuvent être implicites). Variante (vt_int, 1) n'est pas égale à la variante (vt_bstr, L "1").


Si Barry veut une égalité sémantique, c'est-à-dire une représentation du nombre 1 dans n'importe quel type de variante (y compris des chaînes, des dates et des objets (quelle est la représentation IDISPATCH ou OLEDATE de 1, de toute façon?)) Et d'avoir le même hachage, Il devrait prendre en compte le type lors du calcul du hachage, ou devrait "normaliser" toutes les représentations au même type de données (qu'il semble en faire actuellement). S'il choisit l'approche "Normalisation", la partie variante n'est absolument pas pertinente pour la question, car le même problème s'applique à tout autre stockage de valeur qu'il choisit.


Si vous étiez plus enclin à poster des réponses plutôt que de commentaires, il pourrait y avoir des votants appropriés (+ et -) et potentiellement acceptation se passent ici ...


Juste hors de curiosité, qu'essayez-vous d'accomplir? Je me demande s'il y a une meilleure façon.


@Luke - Tout ce dont j'ai besoin, c'est comparer et hacher suffisamment cohérent à utiliser dans des structures de données telles que les tables de hachage, les arbres, etc.


Mais qu'essayez-vous de faire à un niveau supérieur? La notion d'une collection associative où la variante est la clé qui me semble absurde. Pourquoi auriez-vous besoin de faire une recherche sur une variante?


@Luke - J'essaie d'écrire un conteneur générique pour une bibliothèque d'exécution de la langue. Ce n'est pas à moi de me demander pourquoi l'utilisateur ferait la clé d'une variante.


Je ne pense pas qu'il y ait un bon moyen de le faire avec des variantes. Vous pouvez les convertir tous vers des cordes à des fins de hachage, mais comme d'autres l'ont déclaré, cela présente des problèmes (aussi, tous les types de variantes ne peuvent pas être convertis en chaînes). Peut-être devriez-vous regarder le fichier CLR .NET pour voir comment Object.GetHashCode () est mis en œuvre.


3 Réponses :


0
votes

Donc, en résumé, pour faire des choses comparables au premier flux à un format commun, de la chaîne ou du blob.

Comment gérez-vous par exemple. Localisation, par exemple formation de réels? Un réel comparé à une chaîne contenant le même réel créé dans une autre locale échouera. Ou un véritable écrit à la chaîne avec un réglage de précision différent.

Cela me semble que la définition d'égale () est le problème, pas le hachage. Si des valeurs "égales" peuvent être sérialisées à la chaîne (ou au blob) différemment, le hachage échouera.


1 commentaires

C'est un bon point. Il y a deux réponses potentielles: (a) Utilisez des paramètres invariants afin que les codes de hachage soient fiables sur plusieurs instances et localités, etc., soit (b) Ne vous souciez pas tant que les résultats sont cohérents au sein d'une exécution donnée (bien que les paramètres puissent changer et casser des choses dans des cas de bord). Compte tenu de tout ce qui a été dit dans les commentaires à ma question - j'aimerais que plus de ces commentaires étaient des réponses réelles - je peux examiner mon approche et monté les types individuellement, et ne pas essayer de préserver la sémantique de l'égalité de type Delphi lorsque vous envisagez des comparateurs, etc. nécessaires pour les algorithmes. .



0
votes

Les codes de hasch de variantes égales doivent être égaux.

Sans connaître les règles d'égalité et de contrainte utilisées pour tester l'égalité, il est difficile de trouver une implémentation appropriée.


2 commentaires

Je connais très bien comment les codes Hash travaillent dans .NET et Java (j'ai écrit des compilateurs dans la ciblage à la fois CLR et JVM), mais le problème est que les variantes utilisées dans VB et Delphi ne sont pas sécurisées dans le même manière que les objets polymorphes stockés dans un emplacement d'objet de type dans .NET ou Java, ou la manière dont les valeurs sont sécurisées dans Ruby, Python ou JavaScript. C'est-à-dire que 1 == "1" ou 1.equals ("1") == true , pour des valeurs variantes de 1 et "1" . Je suppose que la réponse à ma question est "Cela dépend" - en fonction de la sémantique de la langue.


Je marquais cette réponse comme c'est tout à fait vrai, afin d'écrire la fonction de hachage garantie de la fonction d'égalité, la fonction d'égalité doit être connue et bien définie.



2
votes

Il y a une tension intégrée dans votre question entre l'utilisation d'une fonction de hachage et les exigences énoncées, qui sont validées contre l'entrée du hachage. Je suggérerais de garder à l'esprit quelques propriétés de hachage en général: les informations sont perdues lors du processus de hachage et des collisions de hachage doivent être attendues. Il est possible de construire un hachage parfait sans collision, mais cela serait problématique (ou impossible?) Construire une fonction de hachage parfaite si le domaine de la fonction est toute variante d'ole. D'autre part, si nous ne parlons pas d'un hachage parfait, votre première règle est violée.

Je ne connais pas le contexte plus large de ce que vous essayez d'accomplir, mais je dois repousser une de vos hypothèses: est une fonction de hachage vraiment ce que vous voulez? Vos exigences pourraient être remplies de manière assez simple si vous développez un système qui code, pas de hachage, tous les attributs de variante d'ole d'éventuels afin qu'ils puissent être rappelés plus tard et comparé contre d'autres images variantes.

Votre implémentation de base de la conversion de la variante en une représentation à chaîne est en mouvement dans cette direction. Comme vous le savez sans aucun doute, une variante peut contenir des pointeurs, des pointeurs doubles et des tableaux. Vous devrez donc développer une représentation de chaîne cohérente de ces types de données. Je me demande si cette approche pourrait vraiment être classée comme un hachage. N'es-tu pas juste persister les attributs de données?


1 commentaires

J'écris une classe de collecte générique pour une bibliothèque d'exécution. Le paramètre générique pourrait être une variante. Le hachage parfait n'est pas pertinent. (En fait, le hachage parfait peut être contre-productif dans de petites tables de hachage en augmentant le coût d'une recherche hachage ratée.)