/src/lib/storage/dictionary/abstract_linked_hashed_dictionary.e
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.