comparison lib/gl_anytreehash_list2.h @ 7405:0de49c40e105

Add searching operations, limited to a subsequence of the list.
author Bruno Haible <bruno@clisp.org>
date Thu, 05 Oct 2006 12:45:16 +0000
parents de9a21fc207a
children c9738ed4c499
comparison
equal deleted inserted replaced
7404:71b958155bb9 7405:0de49c40e105
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
18 18
19 /* Common code of gl_avltreehash_list.c and gl_rbtreehash_list.c. */ 19 /* Common code of gl_avltreehash_list.c and gl_rbtreehash_list.c. */
20 20
21 static gl_list_node_t 21 static gl_list_node_t
22 gl_tree_search (gl_list_t list, const void *elt) 22 gl_tree_search_from_to (gl_list_t list, size_t start_index, size_t end_index,
23 const void *elt)
23 { 24 {
24 size_t hashcode = 25 if (!(start_index <= end_index
25 (list->base.hashcode_fn != NULL 26 && end_index <= (list->root != NULL ? list->root->branch_size : 0)))
26 ? list->base.hashcode_fn (elt) 27 /* Invalid arguments. */
27 : (size_t)(uintptr_t) elt); 28 abort ();
28 size_t index = hashcode % list->table_size; 29 {
29 gl_listelement_equals_fn equals = list->base.equals_fn; 30 size_t hashcode =
30 gl_hash_entry_t entry; 31 (list->base.hashcode_fn != NULL
31 32 ? list->base.hashcode_fn (elt)
32 if (list->base.allow_duplicates) 33 : (size_t)(uintptr_t) elt);
33 { 34 size_t index = hashcode % list->table_size;
34 for (entry = list->table[index]; entry != NULL; entry = entry->hash_next) 35 gl_listelement_equals_fn equals = list->base.equals_fn;
35 if (entry->hashcode == hashcode) 36 gl_hash_entry_t entry;
36 { 37
37 if (((struct gl_multiple_nodes *) entry)->magic == MULTIPLE_NODES_MAGIC) 38 if (list->base.allow_duplicates)
38 { 39 {
39 /* An entry representing multiple nodes. */ 40 for (entry = list->table[index]; entry != NULL; entry = entry->hash_next)
40 gl_oset_t nodes = ((struct gl_multiple_nodes *) entry)->nodes; 41 if (entry->hashcode == hashcode)
41 /* Only the first node is interesting. */ 42 {
42 gl_list_node_t node = gl_oset_first (nodes); 43 if (((struct gl_multiple_nodes *) entry)->magic == MULTIPLE_NODES_MAGIC)
43 if (equals != NULL ? equals (elt, node->value) : elt == node->value) 44 {
44 /* All nodes in the entry are equal to the given ELT. 45 /* An entry representing multiple nodes. */
45 But we have to return only the one at the minimal position, 46 gl_oset_t nodes = ((struct gl_multiple_nodes *) entry)->nodes;
46 and this is the first one in the ordered set. */ 47 /* The first node is interesting. */
47 return node; 48 gl_list_node_t node = gl_oset_first (nodes);
48 } 49 if (equals != NULL ? equals (elt, node->value) : elt == node->value)
49 else 50 {
50 { 51 /* All nodes in the entry are equal to the given ELT. */
51 /* An entry representing a single node. */ 52 if (start_index == 0)
52 gl_list_node_t node = (struct gl_list_node_impl *) entry; 53 {
53 if (equals != NULL ? equals (elt, node->value) : elt == node->value) 54 /* We have to return only the one at the minimal
54 return node; 55 position, and this is the first one in the ordered
55 } 56 set. */
56 } 57 if (end_index == list->root->branch_size
57 } 58 || node_position (node) < end_index)
58 else 59 return node;
59 { 60 }
60 /* If no duplicates are allowed, multiple nodes are not needed. */ 61 else
61 for (entry = list->table[index]; entry != NULL; entry = entry->hash_next) 62 {
62 if (entry->hashcode == hashcode) 63 /* We have to return only the one at the minimal
63 { 64 position >= start_index. */
64 gl_list_node_t node = (struct gl_list_node_impl *) entry; 65 const void *elt;
65 if (equals != NULL ? equals (elt, node->value) : elt == node->value) 66 if (gl_oset_search_atleast (nodes,
66 return node; 67 compare_position_threshold,
67 } 68 (void *)(uintptr_t)start_index,
68 } 69 &elt))
69 70 {
70 return NULL; 71 node = (gl_list_node_t) elt;
72 if (end_index == list->root->branch_size
73 || node_position (node) < end_index)
74 return node;
75 }
76 }
77 break;
78 }
79 }
80 else
81 {
82 /* An entry representing a single node. */
83 gl_list_node_t node = (struct gl_list_node_impl *) entry;
84 if (equals != NULL ? equals (elt, node->value) : elt == node->value)
85 {
86 bool position_in_bounds;
87 if (start_index == 0 && end_index == list->root->branch_size)
88 position_in_bounds = true;
89 else
90 {
91 size_t position = node_position (node);
92 position_in_bounds =
93 (position >= start_index && position < end_index);
94 }
95 if (position_in_bounds)
96 return node;
97 break;
98 }
99 }
100 }
101 }
102 else
103 {
104 /* If no duplicates are allowed, multiple nodes are not needed. */
105 for (entry = list->table[index]; entry != NULL; entry = entry->hash_next)
106 if (entry->hashcode == hashcode)
107 {
108 gl_list_node_t node = (struct gl_list_node_impl *) entry;
109 if (equals != NULL ? equals (elt, node->value) : elt == node->value)
110 {
111 bool position_in_bounds;
112 if (start_index == 0 && end_index == list->root->branch_size)
113 position_in_bounds = true;
114 else
115 {
116 size_t position = node_position (node);
117 position_in_bounds =
118 (position >= start_index && position < end_index);
119 }
120 if (position_in_bounds)
121 return node;
122 break;
123 }
124 }
125 }
126
127 return NULL;
128 }
71 } 129 }
72 130
73 static size_t 131 static size_t
74 gl_tree_indexof (gl_list_t list, const void *elt) 132 gl_tree_indexof_from_to (gl_list_t list, size_t start_index, size_t end_index,
133 const void *elt)
75 { 134 {
76 gl_list_node_t node = gl_tree_search (list, elt); 135 gl_list_node_t node =
136 gl_tree_search_from_to (list, start_index, end_index, elt);
77 137
78 if (node != NULL) 138 if (node != NULL)
79 return node_position (node); 139 return node_position (node);
80 else 140 else
81 return (size_t)(-1); 141 return (size_t)(-1);