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