hamster 1.0.1.pre.rc.1 → 1.0.1.pre.rc2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/hamster/groupable.rb +12 -0
- data/lib/hamster/hash.rb +32 -12
- data/lib/hamster/list.rb +68 -22
- data/lib/hamster/queue.rb +5 -6
- data/lib/hamster/set.rb +50 -14
- data/lib/hamster/stack.rb +2 -0
- data/lib/hamster/trie.rb +34 -14
- data/lib/hamster/tuple.rb +9 -24
- data/lib/hamster/vector.rb +29 -7
- data/lib/hamster/version.rb +1 -1
- data/spec/hamster/core_ext/array_spec.rb +4 -10
- data/spec/hamster/core_ext/enumerable_spec.rb +1 -0
- data/spec/hamster/experimental/mutable_set/add_qm_spec.rb +14 -22
- data/spec/hamster/experimental/mutable_set/add_spec.rb +20 -34
- data/spec/hamster/experimental/mutable_set/delete_qm_spec.rb +15 -24
- data/spec/hamster/experimental/mutable_set/delete_spec.rb +15 -25
- data/spec/hamster/experimental/mutable_stack/pop_spec.rb +21 -27
- data/spec/hamster/experimental/mutable_stack/push_spec.rb +11 -31
- data/spec/hamster/hash/all_spec.rb +21 -34
- data/spec/hamster/hash/any_spec.rb +0 -15
- data/spec/hamster/hash/clear_spec.rb +1 -8
- data/spec/hamster/hash/construction_spec.rb +3 -11
- data/spec/hamster/hash/copying_spec.rb +1 -8
- data/spec/hamster/hash/delete_spec.rb +1 -10
- data/spec/hamster/hash/each_spec.rb +1 -12
- data/spec/hamster/hash/empty_spec.rb +8 -8
- data/spec/hamster/hash/eql_spec.rb +30 -22
- data/spec/hamster/hash/except_spec.rb +1 -10
- data/spec/hamster/hash/fetch_spec.rb +1 -24
- data/spec/hamster/hash/filter_spec.rb +1 -16
- data/spec/hamster/hash/find_spec.rb +1 -14
- data/spec/hamster/hash/has_key_spec.rb +1 -10
- data/spec/hamster/hash/hash_spec.rb +1 -16
- data/spec/hamster/hash/immutable_spec.rb +0 -3
- data/spec/hamster/hash/inspect_spec.rb +1 -9
- data/spec/hamster/hash/keys_spec.rb +4 -5
- data/spec/hamster/hash/map_spec.rb +1 -16
- data/spec/hamster/hash/merge_spec.rb +5 -11
- data/spec/hamster/hash/new_spec.rb +21 -0
- data/spec/hamster/hash/put_spec.rb +13 -11
- data/spec/hamster/hash/reduce_spec.rb +7 -15
- data/spec/hamster/hash/remove_spec.rb +1 -16
- data/spec/hamster/hash/uniq_spec.rb +1 -8
- data/spec/hamster/hash/values_spec.rb +1 -6
- data/spec/hamster/immutable/copying_spec.rb +1 -8
- data/spec/hamster/immutable/immutable_spec.rb +1 -14
- data/spec/hamster/immutable/memoize_spec.rb +0 -1
- data/spec/hamster/list/add_spec.rb +1 -6
- data/spec/hamster/list/all_spec.rb +1 -28
- data/spec/hamster/list/any_spec.rb +1 -20
- data/spec/hamster/list/append_spec.rb +1 -11
- data/spec/hamster/list/at_spec.rb +1 -13
- data/spec/hamster/list/break_spec.rb +1 -13
- data/spec/hamster/list/cadr_spec.rb +1 -9
- data/spec/hamster/list/chunk_spec.rb +1 -9
- data/spec/hamster/list/clear_spec.rb +1 -9
- data/spec/hamster/list/combinations_spec.rb +1 -11
- data/spec/hamster/list/compact_spec.rb +1 -9
- data/spec/hamster/list/cons_spec.rb +1 -10
- data/spec/hamster/list/construction_spec.rb +1 -30
- data/spec/hamster/list/copying_spec.rb +1 -9
- data/spec/hamster/list/count_spec.rb +1 -15
- data/spec/hamster/list/cycle_spec.rb +1 -10
- data/spec/hamster/list/drop_spec.rb +1 -9
- data/spec/hamster/list/drop_while_spec.rb +1 -13
- data/spec/hamster/list/each_slice_spec.rb +1 -17
- data/spec/hamster/list/each_spec.rb +1 -17
- data/spec/hamster/list/each_with_index_spec.rb +1 -10
- data/spec/hamster/list/elem_index_spec.rb +1 -13
- data/spec/hamster/list/elem_indices_spec.rb +1 -11
- data/spec/hamster/list/empty_spec.rb +1 -13
- data/spec/hamster/list/eql_spec.rb +52 -62
- data/spec/hamster/list/find_index_spec.rb +1 -13
- data/spec/hamster/list/find_indices_spec.rb +1 -11
- data/spec/hamster/list/find_spec.rb +1 -17
- data/spec/hamster/list/flatten_spec.rb +1 -9
- data/spec/hamster/list/grep_spec.rb +1 -16
- data/spec/hamster/list/group_by_spec.rb +1 -20
- data/spec/hamster/list/head_spec.rb +1 -11
- data/spec/hamster/list/include_spec.rb +1 -13
- data/spec/hamster/list/init_spec.rb +1 -8
- data/spec/hamster/list/inits_spec.rb +1 -9
- data/spec/hamster/list/inspect_spec.rb +1 -11
- data/spec/hamster/list/intersperse_spec.rb +1 -9
- data/spec/hamster/list/join_spec.rb +1 -18
- data/spec/hamster/list/last_spec.rb +1 -11
- data/spec/hamster/list/map_spec.rb +1 -15
- data/spec/hamster/list/maximum_spec.rb +1 -20
- data/spec/hamster/list/merge_by_spec.rb +1 -19
- data/spec/hamster/list/merge_spec.rb +1 -20
- data/spec/hamster/list/minimum_spec.rb +1 -20
- data/spec/hamster/list/none_spec.rb +1 -18
- data/spec/hamster/list/one_spec.rb +1 -16
- data/spec/hamster/list/partition_spec.rb +1 -13
- data/spec/hamster/list/product_spec.rb +1 -11
- data/spec/hamster/list/reduce_spec.rb +0 -1
- data/spec/hamster/list/remove_spec.rb +1 -15
- data/spec/hamster/list/reverse_spec.rb +1 -11
- data/spec/hamster/list/size_spec.rb +1 -13
- data/spec/hamster/list/slice_spec.rb +1 -11
- data/spec/hamster/list/sorting_spec.rb +1 -14
- data/spec/hamster/list/span_spec.rb +1 -12
- data/spec/hamster/list/split_at_spec.rb +1 -9
- data/spec/hamster/list/sum_spec.rb +1 -11
- data/spec/hamster/list/tail_spec.rb +1 -11
- data/spec/hamster/list/tails_spec.rb +1 -9
- data/spec/hamster/list/take_spec.rb +1 -9
- data/spec/hamster/list/take_while_spec.rb +0 -1
- data/spec/hamster/list/to_a_spec.rb +1 -13
- data/spec/hamster/list/to_ary_spec.rb +0 -1
- data/spec/hamster/list/to_list_spec.rb +1 -9
- data/spec/hamster/list/to_set_spec.rb +2 -8
- data/spec/hamster/list/union_spec.rb +1 -11
- data/spec/hamster/list/uniq_spec.rb +1 -11
- data/spec/hamster/queue/clear_spec.rb +1 -9
- data/spec/hamster/queue/construction_spec.rb +1 -10
- data/spec/hamster/queue/dequeue_spec.rb +1 -11
- data/spec/hamster/queue/empty_spec.rb +1 -13
- data/spec/hamster/queue/enqueue_spec.rb +1 -11
- data/spec/hamster/queue/head_spec.rb +1 -11
- data/spec/hamster/queue/inspect_spec.rb +1 -9
- data/spec/hamster/queue/size_spec.rb +1 -11
- data/spec/hamster/queue/to_a_spec.rb +1 -11
- data/spec/hamster/queue/to_list_spec.rb +1 -11
- data/spec/hamster/set/add_spec.rb +1 -12
- data/spec/hamster/set/all_spec.rb +1 -18
- data/spec/hamster/set/any_spec.rb +1 -17
- data/spec/hamster/set/clear_spec.rb +9 -8
- data/spec/hamster/set/compact_spec.rb +1 -9
- data/spec/hamster/set/construction_spec.rb +1 -9
- data/spec/hamster/set/copying_spec.rb +1 -8
- data/spec/hamster/set/count_spec.rb +1 -13
- data/spec/hamster/set/delete_spec.rb +1 -10
- data/spec/hamster/set/difference_spec.rb +1 -11
- data/spec/hamster/set/empty_spec.rb +1 -11
- data/spec/hamster/set/exclusion_spec.rb +1 -11
- data/spec/hamster/set/filter_spec.rb +10 -17
- data/spec/hamster/set/find_spec.rb +1 -14
- data/spec/hamster/set/flatten_spec.rb +8 -10
- data/spec/hamster/set/group_by_spec.rb +8 -17
- data/spec/hamster/set/head_spec.rb +1 -12
- data/spec/hamster/set/immutable_spec.rb +1 -4
- data/spec/hamster/set/include_spec.rb +1 -9
- data/spec/hamster/set/inspect_spec.rb +1 -9
- data/spec/hamster/set/intersection_spec.rb +1 -11
- data/spec/hamster/set/join_spec.rb +1 -16
- data/spec/hamster/set/map_spec.rb +1 -16
- data/spec/hamster/set/marshal_spec.rb +1 -6
- data/spec/hamster/set/maximum_spec.rb +1 -18
- data/spec/hamster/set/minimum_spec.rb +1 -17
- data/spec/hamster/set/new_spec.rb +21 -0
- data/spec/hamster/set/none_spec.rb +1 -16
- data/spec/hamster/set/one_spec.rb +1 -14
- data/spec/hamster/set/partition_spec.rb +1 -13
- data/spec/hamster/set/product_spec.rb +1 -9
- data/spec/hamster/set/reduce_spec.rb +1 -26
- data/spec/hamster/set/remove_spec.rb +1 -16
- data/spec/hamster/set/size_spec.rb +1 -9
- data/spec/hamster/set/sorting_spec.rb +1 -3
- data/spec/hamster/set/subset_spec.rb +1 -9
- data/spec/hamster/set/sum_spec.rb +1 -9
- data/spec/hamster/set/superset_spec.rb +1 -9
- data/spec/hamster/set/to_a_spec.rb +1 -11
- data/spec/hamster/set/to_list_spec.rb +1 -11
- data/spec/hamster/set/to_set_spec.rb +1 -9
- data/spec/hamster/set/union_spec.rb +1 -11
- data/spec/hamster/set/uniq_spec.rb +1 -7
- data/spec/hamster/sorter/immutable_spec.rb +1 -4
- data/spec/hamster/stack/clear_spec.rb +1 -9
- data/spec/hamster/stack/construction_spec.rb +1 -10
- data/spec/hamster/stack/copying_spec.rb +1 -9
- data/spec/hamster/stack/empty_spec.rb +1 -9
- data/spec/hamster/stack/eql_spec.rb +1 -13
- data/spec/hamster/stack/immutable_spec.rb +1 -4
- data/spec/hamster/stack/inspect_spec.rb +1 -9
- data/spec/hamster/stack/peek_spec.rb +1 -11
- data/spec/hamster/stack/pop_spec.rb +1 -11
- data/spec/hamster/stack/push_spec.rb +1 -11
- data/spec/hamster/stack/size_spec.rb +1 -11
- data/spec/hamster/stack/to_a_spec.rb +1 -11
- data/spec/hamster/stack/to_list_spec.rb +1 -9
- data/spec/hamster/tuple/construction_spec.rb +30 -0
- data/spec/hamster/tuple/copying_spec.rb +1 -8
- data/spec/hamster/tuple/eql_spec.rb +57 -40
- data/spec/hamster/tuple/first_spec.rb +1 -6
- data/spec/hamster/tuple/immutable_spec.rb +1 -4
- data/spec/hamster/tuple/inspect_spec.rb +1 -6
- data/spec/hamster/tuple/last_spec.rb +1 -6
- data/spec/hamster/tuple/to_a_spec.rb +1 -9
- data/spec/hamster/tuple/to_ary_spec.rb +0 -1
- data/spec/hamster/undefined/erase_spec.rb +1 -12
- data/spec/hamster/vector/add_spec.rb +8 -0
- data/spec/hamster/vector/clear_spec.rb +1 -8
- data/spec/hamster/vector/copying_spec.rb +1 -8
- data/spec/hamster/vector/each_spec.rb +1 -11
- data/spec/hamster/vector/each_with_index_spec.rb +1 -9
- data/spec/hamster/vector/empty_spec.rb +7 -9
- data/spec/hamster/vector/eql_spec.rb +1 -12
- data/spec/hamster/vector/filter_spec.rb +8 -12
- data/spec/hamster/vector/first_spec.rb +1 -11
- data/spec/hamster/vector/get_spec.rb +1 -23
- data/spec/hamster/vector/include_spec.rb +1 -10
- data/spec/hamster/vector/map_spec.rb +8 -14
- data/spec/hamster/vector/new_spec.rb +48 -0
- data/spec/hamster/vector/reduce_spec.rb +1 -26
- data/spec/hamster/vector/set_spec.rb +8 -0
- data/spec/spec_helper.rb +0 -5
- metadata +35 -68
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a12201961b658581cc147e8a0c99fdc7003bf3b0
|
4
|
+
data.tar.gz: 3f24be00255e640a0afcefd374f6e3d16e619e5c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: abd019d8bcc64d60d75d734a8ee0e08e549ab3662b2e1638f25afb331a3fa7981b0f45f571625bc61f2a36b17bbce44c0a862aa4586f95f9949949ddc26dc1c0
|
7
|
+
data.tar.gz: 283b36da83e8dda6ab822e430eb2503d7abdf7be6cb142e0c217052acbd2cafcac52c0833e2a156018436cf6cb86b947c7c10a76a5dcfa4b9ab8247a88d6d35d
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Hamster
|
2
|
+
module Groupable
|
3
|
+
def group_by_with(empty_group, &block)
|
4
|
+
return group_by { |item| item } unless block_given?
|
5
|
+
reduce(EmptyHash) do |hash, item|
|
6
|
+
key = yield(item)
|
7
|
+
group = hash.get(key) || empty_group
|
8
|
+
hash.put(key, group.conj(item))
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/hamster/hash.rb
CHANGED
@@ -6,7 +6,7 @@ require "hamster/trie"
|
|
6
6
|
require "hamster/list"
|
7
7
|
|
8
8
|
module Hamster
|
9
|
-
def self.hash(pairs =
|
9
|
+
def self.hash(pairs = nil, &block)
|
10
10
|
Hash.new(pairs, &block)
|
11
11
|
end
|
12
12
|
|
@@ -15,16 +15,25 @@ module Hamster
|
|
15
15
|
include Immutable
|
16
16
|
|
17
17
|
class << self
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
alias :alloc :new
|
19
|
+
|
20
|
+
def new(pairs = nil, &block)
|
21
|
+
if pairs.nil? && block.nil?
|
22
|
+
empty
|
23
|
+
elsif pairs.empty?
|
24
|
+
alloc(EmptyTrie, block)
|
25
|
+
else
|
26
|
+
alloc(Trie[pairs], block)
|
27
|
+
end
|
21
28
|
end
|
22
29
|
|
23
|
-
|
30
|
+
def empty
|
31
|
+
@empty ||= self.alloc
|
32
|
+
end
|
24
33
|
end
|
25
34
|
|
26
|
-
def initialize(
|
27
|
-
@trie
|
35
|
+
def initialize(trie = EmptyTrie, block = nil)
|
36
|
+
@trie = trie
|
28
37
|
@default = block
|
29
38
|
end
|
30
39
|
|
@@ -143,7 +152,9 @@ module Hamster
|
|
143
152
|
def_delegator :self, :find, :detect
|
144
153
|
|
145
154
|
def merge(other)
|
146
|
-
transform
|
155
|
+
transform do
|
156
|
+
other.each { |key, value| @trie = @trie.put(key, value) }
|
157
|
+
end
|
147
158
|
end
|
148
159
|
def_delegator :self, :merge, :+
|
149
160
|
|
@@ -156,7 +167,7 @@ module Hamster
|
|
156
167
|
end
|
157
168
|
|
158
169
|
def keys
|
159
|
-
|
170
|
+
Hamster::Set.alloc(@trie)
|
160
171
|
end
|
161
172
|
|
162
173
|
def values
|
@@ -167,10 +178,15 @@ module Hamster
|
|
167
178
|
self.class.empty
|
168
179
|
end
|
169
180
|
|
181
|
+
# Value-and-type equality
|
170
182
|
def eql?(other)
|
171
183
|
instance_of?(other.class) && @trie.eql?(other.instance_variable_get(:@trie))
|
172
184
|
end
|
173
|
-
|
185
|
+
|
186
|
+
# Value equality, will do type coercion
|
187
|
+
def ==(other)
|
188
|
+
self.eql?(other) || (other.respond_to?(:to_hash) && to_hash.eql?(other.to_hash))
|
189
|
+
end
|
174
190
|
|
175
191
|
def hash
|
176
192
|
keys.sort.reduce(0) do |hash, key|
|
@@ -186,7 +202,7 @@ module Hamster
|
|
186
202
|
"{#{reduce([]) { |memo, key, value| memo << "#{key.inspect} => #{value.inspect}" }.join(", ")}}"
|
187
203
|
end
|
188
204
|
|
189
|
-
def
|
205
|
+
def to_hash
|
190
206
|
output = {}
|
191
207
|
each do |key, value|
|
192
208
|
output[key] = value
|
@@ -194,6 +210,10 @@ module Hamster
|
|
194
210
|
output
|
195
211
|
end
|
196
212
|
|
213
|
+
def marshal_dump
|
214
|
+
to_hash
|
215
|
+
end
|
216
|
+
|
197
217
|
def marshal_load(dictionary)
|
198
218
|
@trie = dictionary.reduce EmptyTrie do |trie, key_value|
|
199
219
|
trie.put(key_value.first, key_value.last)
|
@@ -201,5 +221,5 @@ module Hamster
|
|
201
221
|
end
|
202
222
|
end
|
203
223
|
|
204
|
-
EmptyHash = Hamster::Hash.
|
224
|
+
EmptyHash = Hamster::Hash.empty
|
205
225
|
end
|
data/lib/hamster/list.rb
CHANGED
@@ -4,6 +4,7 @@ require "thread"
|
|
4
4
|
require "hamster/core_ext/enumerable"
|
5
5
|
require "hamster/undefined"
|
6
6
|
require "hamster/enumerable"
|
7
|
+
require "hamster/groupable"
|
7
8
|
require "hamster/tuple"
|
8
9
|
require "hamster/sorter"
|
9
10
|
require "hamster/hash"
|
@@ -144,6 +145,7 @@ module Hamster
|
|
144
145
|
module List
|
145
146
|
extend Forwardable
|
146
147
|
include Enumerable
|
148
|
+
include Groupable
|
147
149
|
|
148
150
|
CADR = /^c([ad]+)r$/
|
149
151
|
|
@@ -151,7 +153,16 @@ module Hamster
|
|
151
153
|
def_delegator :self, :empty?, :null?
|
152
154
|
|
153
155
|
def size
|
154
|
-
|
156
|
+
result, list = 0, self
|
157
|
+
until list.empty?
|
158
|
+
if list.cached_size?
|
159
|
+
return result + list.size
|
160
|
+
else
|
161
|
+
result += 1
|
162
|
+
end
|
163
|
+
list = list.tail
|
164
|
+
end
|
165
|
+
result
|
155
166
|
end
|
156
167
|
def_delegator :self, :size, :length
|
157
168
|
|
@@ -159,6 +170,8 @@ module Hamster
|
|
159
170
|
Sequence.new(item, self)
|
160
171
|
end
|
161
172
|
def_delegator :self, :cons, :>>
|
173
|
+
def_delegator :self, :cons, :conj
|
174
|
+
def_delegator :self, :cons, :conjoin
|
162
175
|
|
163
176
|
def add(item)
|
164
177
|
append(Hamster.list(item))
|
@@ -387,11 +400,7 @@ module Hamster
|
|
387
400
|
end
|
388
401
|
|
389
402
|
def group_by(&block)
|
390
|
-
|
391
|
-
reduce(EmptyHash) do |hash, item|
|
392
|
-
key = yield(item)
|
393
|
-
hash.put(key, (hash.get(key) || EmptyList).cons(item))
|
394
|
-
end
|
403
|
+
group_by_with(EmptyList, &block)
|
395
404
|
end
|
396
405
|
def_delegator :self, :group_by, :group
|
397
406
|
|
@@ -466,6 +475,7 @@ module Hamster
|
|
466
475
|
end
|
467
476
|
end
|
468
477
|
|
478
|
+
# Value-and-type equality
|
469
479
|
def eql?(other)
|
470
480
|
list = self
|
471
481
|
loop do
|
@@ -478,7 +488,12 @@ module Hamster
|
|
478
488
|
other = other.tail
|
479
489
|
end
|
480
490
|
end
|
481
|
-
|
491
|
+
|
492
|
+
# Value equality, will do type coercion on arrays and array-like objects
|
493
|
+
def ==(other)
|
494
|
+
self.eql?(other) ||
|
495
|
+
other.respond_to?(:to_ary) && to_ary.eql?(other.to_ary)
|
496
|
+
end
|
482
497
|
|
483
498
|
def hash
|
484
499
|
reduce(0) { |hash, item| (hash << 5) - hash + item.hash }
|
@@ -505,23 +520,28 @@ module Hamster
|
|
505
520
|
super || !!name.to_s.match(CADR)
|
506
521
|
end
|
507
522
|
|
523
|
+
def cached_size?
|
524
|
+
false
|
525
|
+
end
|
526
|
+
|
508
527
|
private
|
509
528
|
|
510
529
|
def method_missing(name, *args, &block)
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
530
|
+
if name.to_s.match(CADR)
|
531
|
+
# Perform compositions of car and cdr operations. Their names consist of a 'c',
|
532
|
+
# followed by at least one 'a' or 'd', and finally an 'r'. The series of 'a's and
|
533
|
+
# 'd's in the method name identify the series of car and cdr operations performed.
|
534
|
+
# The order in which the 'a's and 'd's appear is the inverse of the order in which
|
535
|
+
# the corresponding operations are performed.
|
536
|
+
code = "def #{name}; self."
|
537
|
+
code << Regexp.last_match[1].reverse.chars.map do |char|
|
538
|
+
{'a' => 'head', 'd' => 'tail'}[char]
|
539
|
+
end.join('.')
|
540
|
+
code << '; end'
|
541
|
+
List.class_eval(code)
|
542
|
+
send(name, *args, &block)
|
543
|
+
else
|
544
|
+
super
|
525
545
|
end
|
526
546
|
end
|
527
547
|
end
|
@@ -544,11 +564,20 @@ module Hamster
|
|
544
564
|
def initialize(head, tail = EmptyList)
|
545
565
|
@head = head
|
546
566
|
@tail = tail
|
567
|
+
@size = tail.cached_size? ? tail.size + 1 : nil
|
547
568
|
end
|
548
569
|
|
549
570
|
def empty?
|
550
571
|
false
|
551
572
|
end
|
573
|
+
|
574
|
+
def size
|
575
|
+
@size || super
|
576
|
+
end
|
577
|
+
|
578
|
+
def cached_size?
|
579
|
+
@size != nil
|
580
|
+
end
|
552
581
|
end
|
553
582
|
|
554
583
|
# Lazy list stream
|
@@ -569,13 +598,22 @@ module Hamster
|
|
569
598
|
|
570
599
|
def initialize(&block)
|
571
600
|
@block = block
|
572
|
-
@lock
|
601
|
+
@lock = Mutex.new
|
602
|
+
@size = nil
|
573
603
|
end
|
574
604
|
|
575
605
|
def_delegator :target, :head
|
576
606
|
def_delegator :target, :tail
|
577
607
|
def_delegator :target, :empty?
|
578
608
|
|
609
|
+
def size
|
610
|
+
@size ||= super
|
611
|
+
end
|
612
|
+
|
613
|
+
def cached_size?
|
614
|
+
@size != nil
|
615
|
+
end
|
616
|
+
|
579
617
|
protected
|
580
618
|
|
581
619
|
def vivify
|
@@ -616,6 +654,14 @@ module Hamster
|
|
616
654
|
def empty?
|
617
655
|
true
|
618
656
|
end
|
657
|
+
|
658
|
+
def size
|
659
|
+
0
|
660
|
+
end
|
661
|
+
|
662
|
+
def cached_size?
|
663
|
+
true
|
664
|
+
end
|
619
665
|
end
|
620
666
|
end
|
621
667
|
end
|
data/lib/hamster/queue.rb
CHANGED
@@ -38,6 +38,8 @@ module Hamster
|
|
38
38
|
end
|
39
39
|
def_delegator :self, :enqueue, :<<
|
40
40
|
def_delegator :self, :enqueue, :add
|
41
|
+
def_delegator :self, :enqueue, :conj
|
42
|
+
def_delegator :self, :enqueue, :conjoin
|
41
43
|
|
42
44
|
def dequeue
|
43
45
|
front = @front
|
@@ -66,20 +68,17 @@ module Hamster
|
|
66
68
|
def_delegator :self, :eql?, :==
|
67
69
|
|
68
70
|
def to_a
|
69
|
-
|
71
|
+
@front.to_a.concat(@rear.to_a.tap { |a| a.reverse! })
|
70
72
|
end
|
71
73
|
def_delegator :self, :to_a, :entries
|
72
|
-
|
73
|
-
def to_ary
|
74
|
-
to_list.to_ary
|
75
|
-
end
|
74
|
+
def_delegator :self, :to_a, :to_ary
|
76
75
|
|
77
76
|
def to_list
|
78
77
|
@front.append(@rear.reverse)
|
79
78
|
end
|
80
79
|
|
81
80
|
def inspect
|
82
|
-
|
81
|
+
to_a.inspect
|
83
82
|
end
|
84
83
|
end
|
85
84
|
|
data/lib/hamster/set.rb
CHANGED
@@ -2,19 +2,33 @@ require "forwardable"
|
|
2
2
|
require "hamster/immutable"
|
3
3
|
require "hamster/undefined"
|
4
4
|
require "hamster/enumerable"
|
5
|
+
require "hamster/groupable"
|
5
6
|
require "hamster/sorter"
|
6
7
|
require "hamster/trie"
|
7
8
|
require "hamster/list"
|
8
9
|
|
9
10
|
module Hamster
|
10
11
|
def self.set(*items)
|
11
|
-
|
12
|
+
Set.new(*items)
|
12
13
|
end
|
13
14
|
|
14
15
|
class Set
|
15
16
|
extend Forwardable
|
16
17
|
include Immutable
|
17
18
|
include Enumerable
|
19
|
+
include Groupable
|
20
|
+
|
21
|
+
class << self
|
22
|
+
alias :alloc :new
|
23
|
+
|
24
|
+
def new(*items)
|
25
|
+
items.empty? ? empty : alloc(Trie[items.map! { |x| [x, nil] }])
|
26
|
+
end
|
27
|
+
|
28
|
+
def empty
|
29
|
+
@empty ||= self.alloc
|
30
|
+
end
|
31
|
+
end
|
18
32
|
|
19
33
|
def initialize(trie = EmptyTrie)
|
20
34
|
@trie = trie
|
@@ -34,6 +48,8 @@ module Hamster
|
|
34
48
|
transform_unless(include?(item)) { @trie = @trie.put(item, nil) }
|
35
49
|
end
|
36
50
|
def_delegator :self, :add, :<<
|
51
|
+
def_delegator :self, :add, :conj
|
52
|
+
def_delegator :self, :add, :conjoin
|
37
53
|
|
38
54
|
def delete(item)
|
39
55
|
trie = @trie.delete(item)
|
@@ -55,12 +71,12 @@ module Hamster
|
|
55
71
|
def filter
|
56
72
|
return self unless block_given?
|
57
73
|
trie = @trie.filter { |entry| yield(entry.key) }
|
58
|
-
return
|
74
|
+
return self.class.empty if trie.empty?
|
59
75
|
transform_unless(trie.equal?(@trie)) { @trie = trie }
|
60
76
|
end
|
61
77
|
|
62
78
|
def include?(object)
|
63
|
-
|
79
|
+
@trie.key?(object)
|
64
80
|
end
|
65
81
|
|
66
82
|
def head
|
@@ -100,8 +116,12 @@ module Hamster
|
|
100
116
|
def_delegator :self, :intersection, :&
|
101
117
|
|
102
118
|
def difference(other)
|
103
|
-
trie = @trie.
|
104
|
-
|
119
|
+
trie = if (@trie.size <= other.size) && (other.is_a?(Hamster::Set) || (defined?(::Set) && other.is_a?(::Set)))
|
120
|
+
@trie.filter { |entry| !other.include?(entry.key) }
|
121
|
+
else
|
122
|
+
other.reduce(@trie) { |trie, item| trie.delete(item) }
|
123
|
+
end
|
124
|
+
trie.empty? ? self.class.empty : self.class.alloc(trie)
|
105
125
|
end
|
106
126
|
def_delegator :self, :difference, :diff
|
107
127
|
def_delegator :self, :difference, :subtract
|
@@ -121,27 +141,29 @@ module Hamster
|
|
121
141
|
end
|
122
142
|
|
123
143
|
def flatten
|
124
|
-
reduce(
|
144
|
+
reduce(self.class.empty) do |set, item|
|
125
145
|
next set.union(item.flatten) if item.is_a?(Set)
|
126
146
|
set.add(item)
|
127
147
|
end
|
128
148
|
end
|
129
149
|
|
130
150
|
def group_by(&block)
|
131
|
-
|
132
|
-
reduce(EmptyHash) do |hash, item|
|
133
|
-
key = yield(item)
|
134
|
-
hash.put(key, (hash.get(key) || EmptySet).add(item))
|
135
|
-
end
|
151
|
+
group_by_with(self.class.empty, &block)
|
136
152
|
end
|
137
153
|
def_delegator :self, :group_by, :group
|
138
154
|
|
139
155
|
def clear
|
140
|
-
|
156
|
+
self.class.empty
|
141
157
|
end
|
142
158
|
|
143
159
|
def eql?(other)
|
144
|
-
instance_of?(other.class)
|
160
|
+
return false if not instance_of?(other.class)
|
161
|
+
other_trie = other.instance_variable_get(:@trie)
|
162
|
+
return false if @trie.size != other_trie.size
|
163
|
+
@trie.each do |entry|
|
164
|
+
return false if !other_trie.key?(entry.key)
|
165
|
+
end
|
166
|
+
true
|
145
167
|
end
|
146
168
|
def_delegator :self, :eql?, :==
|
147
169
|
|
@@ -161,7 +183,21 @@ module Hamster
|
|
161
183
|
def inspect
|
162
184
|
"{#{to_a.inspect[1..-2]}}"
|
163
185
|
end
|
186
|
+
|
187
|
+
def marshal_dump
|
188
|
+
output = {}
|
189
|
+
each do |key|
|
190
|
+
output[key] = nil
|
191
|
+
end
|
192
|
+
output
|
193
|
+
end
|
194
|
+
|
195
|
+
def marshal_load(dictionary)
|
196
|
+
@trie = dictionary.reduce(EmptyTrie) do |trie, key_value|
|
197
|
+
trie.put(key_value.first, nil)
|
198
|
+
end
|
199
|
+
end
|
164
200
|
end
|
165
201
|
|
166
|
-
EmptySet = Hamster::Set.
|
202
|
+
EmptySet = Hamster::Set.empty
|
167
203
|
end
|