-
Notifications
You must be signed in to change notification settings - Fork 128
Expand file tree
/
Copy pathpersistent_hash_set.py
More file actions
100 lines (79 loc) · 2.71 KB
/
persistent_hash_set.py
File metadata and controls
100 lines (79 loc) · 2.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
py_object = object
import pixie.vm.object as object
from pixie.vm.primitives import nil, true, false
import pixie.vm.persistent_hash_map as persistent_hash_map
import pixie.vm.stdlib as proto
from pixie.vm.code import extend, as_var, intern_var
import pixie.vm.rt as rt
VAR_KEY = intern_var(u"pixie.stdlib", u"key")
class PersistentHashSet(object.Object):
_type = object.Type(u"pixie.stdlib.PersistentHashSet")
def type(self):
return PersistentHashSet._type
def __init__(self, meta, m):
self._meta = meta
self._map = m
def conj(self, v):
return PersistentHashSet(self._meta, self._map.assoc(v, v))
def disj(self, k):
return PersistentHashSet(self._meta, self._map.without(k))
def meta(self):
return self._meta
def with_meta(self, meta):
return PersistentHashSet(meta, self._map)
EMPTY = PersistentHashSet(nil, persistent_hash_map.EMPTY)
@as_var("set")
def _create(coll):
ret = EMPTY
coll = rt._seq(coll)
while coll is not nil:
ret = ret.conj(rt._first(coll))
coll = rt._seq(rt._next(coll))
return ret
@extend(proto._count, PersistentHashSet)
def _count(self):
assert isinstance(self, PersistentHashSet)
return rt._count(self._map)
@extend(proto._val_at, PersistentHashSet)
def _val_at(self, key, not_found):
assert isinstance(self, PersistentHashSet)
return rt._val_at(self._map, key, not_found)
@extend(proto._contains_key, PersistentHashSet)
def _contains_key(self, key):
assert isinstance(self, PersistentHashSet)
return rt._contains_key(self._map, key)
@extend(proto._eq, PersistentHashSet)
def _eq(self, obj):
assert isinstance(self, PersistentHashSet)
if self is obj:
return true
if not isinstance(obj, PersistentHashSet):
return false
if self._map._cnt != obj._map._cnt:
return false
seq = rt.seq(obj)
while seq is not nil:
if rt._contains_key(self, rt.first(seq)) is false:
return false
seq = rt.next(seq)
return true
@extend(proto._conj, PersistentHashSet)
def _conj(self, v):
assert isinstance(self, PersistentHashSet)
return self.conj(v)
@extend(proto._disj, PersistentHashSet)
def _disj(self, v):
assert isinstance(self, PersistentHashSet)
return self.disj(v)
@extend(proto._reduce, PersistentHashSet)
def _reduce(self, f, init):
assert isinstance(self, PersistentHashSet)
return rt._reduce(rt.keys(self._map), f, init)
@extend(proto._meta, PersistentHashSet)
def _meta(self):
assert isinstance(self, PersistentHashSet)
return self.meta()
@extend(proto._with_meta, PersistentHashSet)
def _with_meta(self, meta):
assert isinstance(self, PersistentHashSet)
return self.with_meta(meta)