PageRenderTime 24ms CodeModel.GetById 13ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 1ms

/src/lib/storage/dictionary/abstract_linked_hashed_dictionary.e

http://github.com/tybor/Liberty
Specman e | 210 lines | 143 code | 25 blank | 42 comment | 7 complexity | fa92e0672fe750ce40fafef4052bc85d MD5 | raw file
  1-- This file is part of a Liberty Eiffel library.
  2-- See the full copyright at the end.
  3--
  4deferred class ABSTRACT_LINKED_HASHED_DICTIONARY[V_, K_]
  5   --
  6   -- Associative memory. Values of type `V_' are stored using Keys of type `K_'.
  7   --
  8   -- Efficient implementation of DICTIONARY using some hash_code on keys.
  9   --
 10   -- When iterating over the dictionary, the insertion order is kept.
 11   --
 12
 13inherit
 14   ABSTRACT_HASHED_DICTIONARY[V_, K_]
 15      redefine
 16         new_iterator_on_keys, new_iterator_on_items, new_iterator,
 17         for_each_item, for_all_items, exists_item, aggregate_items,
 18         key_map_in, item_map_in,
 19         buckets_item, cache_node, free_nodes, nodes_list, dispose_node, new_node,
 20         set_cache_user
 21      end
 22
 23feature {ITERATOR}
 24   first_node, last_node: LINKED_HASHED_DICTIONARY_NODE[V_, K_]
 25
 26feature {ANY}
 27   new_iterator_on_keys: ITERATOR[K_]
 28      do
 29         create {ITERATOR_ON_LINKED_HASHED_DICTIONARY_KEYS[V_, K_]} Result.make(Current)
 30      end
 31
 32   new_iterator_on_items: ITERATOR[V_]
 33      do
 34         create {ITERATOR_ON_LINKED_HASHED_DICTIONARY_ITEMS[V_, K_]} Result.make(Current)
 35      end
 36
 37   new_iterator: ITERATOR[TUPLE[V_, K_]]
 38      do
 39         create {ITERATOR_ON_LINKED_HASHED_DICTIONARY[V_, K_]} Result.make(Current)
 40      end
 41
 42   key_map_in (buffer: COLLECTION[K_])
 43      local
 44         node: like first_node
 45      do
 46         from
 47            node := first_node
 48         until
 49            node = Void
 50         loop
 51            buffer.add_last(node.key)
 52            node := node.next_link
 53         end
 54      end
 55
 56   item_map_in (buffer: COLLECTION[V_])
 57      local
 58         node: like first_node
 59      do
 60         from
 61            node := first_node
 62         until
 63            node = Void
 64         loop
 65            buffer.add_last(node.item)
 66            node := node.next_link
 67         end
 68      end
 69
 70feature {ANY} -- Agent-based features:
 71   for_each_item (action: PROCEDURE[TUPLE[V_]])
 72         -- Apply `action' to every item of `Current'.
 73         --
 74         -- See also `for_all', `exists', `aggregate'.
 75      do
 76         new_iterator_on_items.for_each(action)
 77      end
 78
 79   for_all_items (test: PREDICATE[TUPLE[V_]]): BOOLEAN
 80         -- Do all items satisfy `test'?
 81         --
 82         -- See also `for_each', `exists', `aggregate'.
 83      do
 84         Result := new_iterator_on_items.for_all(test)
 85      end
 86
 87   exists_item (test: PREDICATE[TUPLE[V_]]): BOOLEAN
 88         -- Does at least one item satisfy `test'?
 89         --
 90         -- See also `for_each', `for_all', `aggregate'.
 91      do
 92         Result := new_iterator_on_items.exists(test)
 93      end
 94
 95   aggregate_items (action: FUNCTION[TUPLE[V_, V_], V_]; initial: V_): V_
 96         -- Aggregate all the elements starting from the initial value.
 97         --
 98         -- See also `for_each', `for_all', `exists'.
 99      do
100         Result := new_iterator_on_items.aggregate(action, initial)
101      end
102
103feature {}
104   set_cache_user (index: INTEGER)
105      do
106         if cache_user /= index then
107            if cache_iterator = Void then
108               create cache_iterator.make(Current)
109            end
110            from
111               if not cache_iterator.is_valid or else index < cache_iterator.index then
112                  cache_iterator.start
113               end
114            until
115               index = cache_iterator.index
116            loop
117               cache_iterator.next
118            end
119            cache_user := index
120            cache_node := cache_iterator.node
121         end
122      end
123
124   cache_iterator: ITERATOR_ON_LINKED_HASHED_DICTIONARY_KEYS[V_, K_]
125
126feature {}
127   buckets_item (a_buckets: like buckets; idx: INTEGER): like cache_node
128      do
129         Result ::= a_buckets.item(idx)
130      end
131
132   cache_node: LINKED_HASHED_DICTIONARY_NODE[V_, K_]
133
134   free_nodes: WEAK_REFERENCE[LINKED_HASHED_DICTIONARY_NODE[V_, K_]]
135
136   nodes_list: FAST_ARRAY[LINKED_HASHED_DICTIONARY_NODE[V_, K_]]
137
138   dispose_node (node: like cache_node): like cache_node
139      local
140         previous, next: like node
141      do
142         Result := Precursor(node)
143
144         next := node.next_link
145         previous := node.previous_link
146
147         if node = first_node then
148            check
149               previous = Void
150            end
151            first_node := next
152         else
153            previous.set_links(previous.previous_link, next)
154         end
155
156         if node = last_node then
157            check
158               next = Void
159            end
160            last_node := previous
161         else
162            next.set_links(previous, next.next_link)
163         end
164
165         node.set_links(Void, Void)
166      end
167
168   new_node (v: V_; k: K_; next: like cache_node): like cache_node
169      do
170         Result := Precursor(v, k, next)
171         Result.set_links(last_node, Void)
172         if first_node = Void then
173            check
174               last_node = Void
175            end
176            first_node := Result
177         else
178            last_node.set_links(last_node.previous_link, Result)
179         end
180         last_node := Result
181      ensure
182         last_node = Result
183         last_node.previous_link = (old last_node)
184      end
185
186invariant
187   count > 0 implies (first_node /= Void and last_node /= Void)
188   count > 1 = (first_node /= last_node)
189
190end -- class ABSTRACT_LINKED_HASHED_DICTIONARY
191--
192-- Copyright (C) 2009-2017: by all the people cited in the AUTHORS file.
193--
194-- Permission is hereby granted, free of charge, to any person obtaining a copy
195-- of this software and associated documentation files (the "Software"), to deal
196-- in the Software without restriction, including without limitation the rights
197-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
198-- copies of the Software, and to permit persons to whom the Software is
199-- furnished to do so, subject to the following conditions:
200--
201-- The above copyright notice and this permission notice shall be included in
202-- all copies or substantial portions of the Software.
203--
204-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
205-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
206-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
207-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
208-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
209-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
210-- THE SOFTWARE.