2010-11-22 24 views
2

Je traite un grand nombre d'enregistrements de base de données, chacun avec une clé unique.Meilleure structure de données que HashTable pour garder une trace des enregistrements traités?

En raison de la nature de ma base de données, ma méthode de traitement peut rencontrer la même clé deux fois, car il s'agit d'une base de données relationnelle et un enregistrement peut avoir plusieurs enregistrements «parents».

C'est une perte de temps, de puissance de traitement, de mémoire et de taille de fichier pour traiter des enregistrements plusieurs fois. J'ai donc besoin d'un moyen de garder une trace des identifiants que j'ai déjà traités.

J'ai regardé HashTable, puisque c'est O (1) pour obtenir et mettre des fonctions et ce sont les seules fonctions dont j'ai besoin. Cependant, il semble que ce soit un gaspillage de mémoire d'avoir essentiellement un bloc de mémoire (1000+)/Load Factor stockant essentiellement des valeurs booléennes. De plus, je ne connais pas ma capacité désirée et je devrais supporter beaucoup de remaniements ou allouer beaucoup plus de mémoire que nécessaire.

Je recherche une structure de données dans laquelle vous pouvez ajouter une valeur et lui donner une erreur si l'ID existe déjà dans la collection, comme retourner false à partir de la méthode put(T value).

Répondre

4

Tout d'abord, il semble que vous voulez un jeu, pas une table. Deuxièmement, si vous voulez O (1), votre seule option est un HashSet, avec le surcoût de mémoire. Si vous êtes prêt à aller avec O (log (n)), alors un TreeSet fonctionnera très bien, sans surcharge. Troisièmement, l'ajout de set (T t) retournera false si l'élément est déjà présent. On dirait que vous vraiment voulez un ensemble au lieu d'une table.

O (log (n)) est toujours assez rapide. Ce n'est certainement pas O (1), mais ce n'est pas trop moche. Vous avez juste besoin de décider (peut-être après quelques tests) qui vous convient le mieux.

+0

O (1) est un avantage de HashSet, pas une exigence du problème. Désolé ce n'était pas clair – CodeFusionMobile

+0

On dirait que l'ensemble est exactement ce dont j'avais besoin. Maintenant, j'ai juste besoin de décider si O (log (n)) vs O (1) est plus important que d'utiliser de la mémoire supplémentaire. – CodeFusionMobile

2

Je pense que HashSet est ce que vous cherchez: http://download.oracle.com/javase/6/docs/api/java/util/HashSet.html

+0

Hashtable est une paire '' alors que HashSet est une "liste" per-say. Comment peut-il aider le PO? –

+0

@The Gentleman Elite J'ai seulement besoin de garder une trace des identifiants qui ont été traités, ne pas mapper les identifiants à leurs enregistrements de base de données. Ainsi, HashSet est exactement ce que je cherchais. – CodeFusionMobile

0

Hey, puisque vous travaillez avec une base de données, ne pourriez-vous pas simplement stocker ces informations dans une table de base de données secondaire ou avec les enregistrements? Aussi, si vous avez une structure arborescente (puisque vous parlez de parents), pourquoi ne pas utiliser un algorithme de déplacement d'arbre, qui marque les nœuds traités. Checkout ces Breadth First Search/Depth First Search Animations et ceux-ci à Wikipeadia Entrées sur BFS et DFS.

En général, je m'assurerais de suivre le drapeau de traitement avec l'objet/ligne. Au lieu d'une structure de données séparée.

+0

La relation de base de données a été simplifiée dans le PO car elle n'était pas pertinente. Le modèle de relation n'est pas un arbre simple. Aussi, puisque je travaille sur la plate-forme Android, les opérations de base de données sont relativement coûteuses car elles nécessitent généralement une écriture dans la mémoire flash. En utilisant le modèle d'arbre comme exemple, j'ai plusieurs feuilles dans l'arbre (différents parents) qui sont en fait le même enregistrement de base de données (même enfant). C'est un graphique, pas un arbre, et la traversée devient beaucoup plus compliquée. – CodeFusionMobile

1

Vous pouvez utiliser Bloom filter, au lieu du hashmap.It est un problème de données probabiliste avec filtre structure Bloom est qu'il donnera de faux + ve's.Check cette implementation of bloom filter .Ce serait la mémoire efficace et plus rapide solution qu'une hashmap.

Plus d'info sur le filtre Bloom:

+0

Intéressant, je n'avais jamais entendu parler de ça auparavant. Cependant, j'ai besoin de certitude absolue, pas de probabilité. Si je reçois un faux positif, cet enregistrement ne pourra jamais être traité. Si elle donnait des faux négatifs, cela pourrait fonctionner mais ne serait pas beaucoup plus efficace que de simplement traiter plusieurs fois des enregistrements. – CodeFusionMobile

+0

@CodeFusionMobile: Je ne suis pas tout à fait sûr comment les utiliser exactement.L'application principale est pour la correction orthographique.Aussi, j'ai lu google bigtables (base de données de google) utiliser bloom-filtre pour l'optimisation. – Emil

+0

La conséquence d'un faux positif signifie qu'un enregistrement est traité à nouveau: donc du temps supplémentaire? Vous pouvez utiliser un filtre de bloom (ou un filtre de bloom évolutif si vous ne connaissez pas le nombre d'enregistrements que vous allez insérer) pour conserver une probabilité d'erreur spécifique. La question est, quoi de plus cher? La solution de bloom 'k * O (1) + * k * '? Ou la solution Set 'k * O (log (n))'? Si le coût de traitement sur dossier est suffisamment bas, je pense que vous pourriez régler votre filtre bloom battre le jeu même dans le pire des cas. – dsummersl

0

Si le resultset est commandé correctement, pourriez-vous garder juste le "dernier traitement" id en mémoire? De cette façon, il vous suffit de cocher "l'identifiant actuel" par rapport à "l'identifiant final". Si elles sont différentes, éliminez-les, sinon passez à l'enregistrement suivant.

+0

Les enregistrements sont traités en blocs distincts à partir de requêtes et d'ensembles de résultats différents provenant de la même table. Cette option n'est donc pas réalisable. – CodeFusionMobile