aboutsummaryrefslogtreecommitdiff
path: root/immutables/map.py
diff options
context:
space:
mode:
authorYury Selivanov <yury@magic.io>2018-12-13 12:48:29 -0500
committerYury Selivanov <yury@magic.io>2018-12-13 12:55:50 -0500
commit7642044a0c6dd484e259933fce976b2725f9ac59 (patch)
tree87864a69b3b78beb30a3ec9d4242e82f13b14738 /immutables/map.py
parent5a9c2fa8131819523403a6b7a92ad0918f1c595d (diff)
downloadimmutables-7642044a0c6dd484e259933fce976b2725f9ac59.tar.gz
immutables-7642044a0c6dd484e259933fce976b2725f9ac59.zip
Add MapMutation.update(); make creating Map from a Map faster; fix bugs
* Add new MapMutation.update() method that behaves like MutableMapping.update() * Make it faster to create a Map() from another Map() -- it's now an O(1) operation. * update() method had a bug that could cause the update Map object to have a wrong number of elements.
Diffstat (limited to 'immutables/map.py')
-rw-r--r--immutables/map.py61
1 files changed, 61 insertions, 0 deletions
diff --git a/immutables/map.py b/immutables/map.py
index fc40ac8..7b230dd 100644
--- a/immutables/map.py
+++ b/immutables/map.py
@@ -438,6 +438,14 @@ class Map:
self.__root = BitmapNode(0, 0, [], 0)
self.__hash = -1
+ if isinstance(col, Map):
+ self.__count = col.__count
+ self.__root = col.__root
+ self.__hash = col.__hash
+ col = None
+ elif isinstance(col, MapMutation):
+ raise TypeError('cannot create Maps from MapMutations')
+
if col or kw:
init = self.update(col, **kw)
self.__count = init.__count
@@ -640,6 +648,9 @@ class MapMutation:
self.finish()
return False
+ def __iter__(self):
+ raise TypeError('{} is not iterable'.format(type(self)))
+
def __delitem__(self, key):
if self.__mutid == 0:
raise ValueError('mutation {!r} has been finished'.format(self))
@@ -707,6 +718,56 @@ class MapMutation:
else:
return True
+ def update(self, col=None, **kw):
+ it = None
+ if col is not None:
+ if hasattr(col, 'items'):
+ it = iter(col.items())
+ else:
+ it = iter(col)
+
+ if it is not None:
+ if kw:
+ it = iter(itertools.chain(it, kw.items()))
+ else:
+ if kw:
+ it = iter(kw.items())
+
+ if it is None:
+
+ return self
+
+ root = self.__root
+ count = self.__count
+
+ i = 0
+ while True:
+ try:
+ tup = next(it)
+ except StopIteration:
+ break
+
+ try:
+ tup = tuple(tup)
+ except TypeError:
+ raise TypeError(
+ 'cannot convert map update '
+ 'sequence element #{} to a sequence'.format(i)) from None
+ key, val, *r = tup
+ if r:
+ raise ValueError(
+ 'map update sequence element #{} has length '
+ '{}; 2 is required'.format(i, len(r) + 2))
+
+ root, added = root.assoc(0, map_hash(key), key, val, self.__mutid)
+ if added:
+ count += 1
+
+ i += 1
+
+ self.__root = root
+ self.__count = count
+
def finish(self):
self.__mutid = 0
return Map._new(self.__count, self.__root)