X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fvalue-labels.c;h=c405961f29d69b29a24b767b0095c5029932425d;hb=5b5099296b3c7212623991de8920e1459e234922;hp=6d7f19c17d7ee191862b29c454c7ef62540a8ad5;hpb=cf5e75010ed9fa9b8eb75a71d1419d40e1a8ddd8;p=pspp diff --git a/src/data/value-labels.c b/src/data/value-labels.c index 6d7f19c17d..c405961f29 100644 --- a/src/data/value-labels.c +++ b/src/data/value-labels.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000, 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -231,21 +231,59 @@ val_labs_find (const struct val_labs *vls, const union value *value) return label ? label->label : NULL; } +/* Searches VLS for a value label for VALUE. If successful, + returns the value label; otherwise, returns a null pointer. + Returns a null pointer if VLS is null. */ +static struct val_lab * +val_labs_lookup__ (const struct val_labs *vls, const union value *value, + unsigned int hash) +{ + struct val_lab *label; + + HMAP_FOR_EACH_WITH_HASH (label, struct val_lab, node, hash, &vls->labels) + if (value_equal (&label->value, value, vls->width)) + return label; + + return NULL; +} + /* Searches VLS for a value label for VALUE. If successful, returns the value label; otherwise, returns a null pointer. Returns a null pointer if VLS is null. */ struct val_lab * val_labs_lookup (const struct val_labs *vls, const union value *value) { + return (vls == NULL ? NULL + : val_labs_lookup__ (vls, value, value_hash (value, vls->width, 0))); +} + +/* Searches VLS for a value label whose label is exactly LABEL. If successful, + returns the corresponding value. Otherwise, returns a null pointer. + + Returns a null pointer if VLS is null. + + This function is O(n) in the number of labels in VLS. */ +const union value * +val_labs_find_value (const struct val_labs *vls, const char *label_) +{ + const union value *value = NULL; + if (vls != NULL) { - struct val_lab *label; - HMAP_FOR_EACH_WITH_HASH (label, struct val_lab, node, - value_hash (value, vls->width, 0), &vls->labels) - if (value_equal (&label->value, value, vls->width)) - return label; + const struct val_lab *vl; + const char *label; + + label = intern_new (label_); + HMAP_FOR_EACH (vl, struct val_lab, node, &vls->labels) + if (vl->label == label) + { + value = &vl->value; + break; + } + intern_unref (label); } - return NULL; + + return value; } /* Returns the first value label in VLS, in arbitrary order, or a @@ -301,3 +339,45 @@ val_labs_sorted (const struct val_labs *vls) else return NULL; } + +/* Returns a hash value that represents all of the labels in VLS, starting from + BASIS. */ +unsigned int +val_labs_hash (const struct val_labs *vls, unsigned int basis) +{ + const struct val_lab *label; + unsigned int hash; + + hash = hash_int (val_labs_count (vls), basis); + HMAP_FOR_EACH (label, struct val_lab, node, &vls->labels) + hash ^= value_hash (&label->value, vls->width, + hash_string (label->label, basis)); + return hash; +} + +/* Returns true if A and B contain the same values with the same labels, + false if they differ in some way. */ +bool +val_labs_equal (const struct val_labs *a, const struct val_labs *b) +{ + const struct val_lab *label; + + if (val_labs_count (a) != val_labs_count (b)) + return false; + + if (a == NULL || b == NULL) + return true; + + if (a->width != b->width) + return false; + + HMAP_FOR_EACH (label, struct val_lab, node, &a->labels) + { + struct val_lab *label2 = val_labs_lookup__ (b, &label->value, + label->node.hash); + if (!label2 || label->label != label2->label) + return false; + } + + return true; +}