Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

dev(hansbug): add documentation && try do slightly optimization #61

Merged
merged 3 commits into from
Jul 8, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions docs/source/api_doc/tree/common.rst
Original file line number Diff line number Diff line change
@@ -6,10 +6,22 @@ treevalue.tree.common
.. _apidoc_tree_common_treestorage:

TreeStorage
-----------
-------------

.. autoclass:: TreeStorage
:members: get, get_or_default, pop, pop_or_default, set, del_, contains, size, empty, copy, deepcopy, deepcopyx, dump, deepdump, deepdumpx, jsondumpx, copy_from, deepcopy_from, deepcopyx_from, detach
:members: get, get_or_default, pop, pop_or_default, popitem, set, setdefault, del_, contains, size, empty, copy, deepcopy, deepcopyx, dump, deepdump, deepdumpx, jsondumpx, copy_from, deepcopy_from, deepcopyx_from, detach, clear, iter_keys, iter_rev_keys, iter_values, iter_rev_values, iter_items, iter_rev_items

.. note::
Please refer to the source code for method details in this section of the documentation \
because adding method signatures will significantly decrease running speed.


.. _apidoc_tree_common_create_storage:

create_storage
-------------------

.. autofunction:: create_storage


.. _apidoc_tree_common_raw:
2 changes: 1 addition & 1 deletion docs/source/api_doc/tree/tree.rst
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ TreeValue
---------------

.. autoclass:: TreeValue
:members: __init__, __getattribute__, __setattr__, __delattr__, __contains__, __repr__, __iter__, __hash__, __eq__, _attr_extern, __len__, __bool__, __str__, __getstate__, __setstate__, get, pop, keys, values, items, __getitem__, __setitem__, __delitem__, _getitem_extern, _setitem_extern, _delitem_extern, popitem, clear, update, setdefault, __reversed__
:members: __init__, __getattribute__, __setattr__, __delattr__, __contains__, __repr__, __iter__, __hash__, __eq__, _attr_extern, __len__, __bool__, __str__, __getstate__, __setstate__, get, pop, keys, values, items, __getitem__, __setitem__, __delitem__, _getitem_extern, _setitem_extern, _delitem_extern, popitem, clear, update, setdefault, __reversed__, _detach


.. _apidoc_tree_tree_delayed:
2 changes: 2 additions & 0 deletions treevalue/tree/common/storage.pxd
Original file line number Diff line number Diff line change
@@ -2,10 +2,12 @@
# cython:language_level=3

from libcpp cimport bool
cimport cython

ctypedef unsigned char boolean
ctypedef unsigned int uint

@cython.final
cdef class TreeStorage:
cdef readonly dict map

169 changes: 128 additions & 41 deletions treevalue/tree/common/storage.pyx
Original file line number Diff line number Diff line change
@@ -2,8 +2,8 @@
# cython:language_level=3

from copy import deepcopy
cimport cython

from libc.string cimport strlen
from libcpp cimport bool

from .base cimport raw, unraw
@@ -12,17 +12,32 @@ from .delay cimport undelay
cdef inline object _keep_object(object obj):
return obj

@cython.final
cdef class TreeStorage:
def __cinit__(self, dict map_):
self.map = map_

def __getnewargs_ex__(self): # for __cinit__, when pickle.loads
return ({},), {}

cpdef public void set(self, str key, object value) except *:
cpdef public inline void set(self, str key, object value) except *:
"""
Set value of given ``key`` in this storage object.

:param key: Key of the target item, should be a string.
:param value: Value of the target item, should be a native object, raw wrapped object or \\
a delayed object.
"""
self.map[key] = unraw(value)

cpdef public object setdefault(self, str key, object default):
cpdef public inline object setdefault(self, str key, object default):
"""
Set value of given ``key`` if it is not exist yet.

:param key: Key of the target item, should be a string.
:param default: Default value of the target item, similar to ``value`` in method :meth:`set`.
:return: Value of the actual-exist item.
"""
cdef object v, df
try:
v = self.map[key]
@@ -33,60 +48,102 @@ cdef class TreeStorage:
return _c_undelay_data(self.map, key, df)

# get and get_or_default is designed separately due to the consideration of performance
cpdef public object get(self, str key):
cdef object v, nv
try:
v = self.map[key]
return _c_undelay_data(self.map, key, v)
except KeyError:
raise KeyError(f"Key {repr(key)} not found in this tree.")
cpdef public inline object get(self, str key):
"""
Get value of the given ``key``.

:param key: Key of the item.
:return: Value of the item.
:raise KeyError: When ``key`` is not exist, raise ``KeyError``.
"""
cdef object v
v = self.map[key]
return _c_undelay_data(self.map, key, v)

cpdef public object get_or_default(self, str key, object default):
cdef object v, nv
cpdef public inline object get_or_default(self, str key, object default):
"""
Get value of the given ``key``, return ``default`` when not exist.

:param key: Key of the item.
:param default: Default value of the item.
:return: Value of the item if ``key`` is exist, otherwise return ``default``.
"""
cdef object v
v = self.map.get(key, default)
return _c_undelay_check_data(self.map, key, v)

# pop and pop_or_default is designed separately due to the consideration of performance
cpdef public object pop(self, str key):
cdef object v, nv, res
try:
v = self.map[key]
res = _c_undelay_data(self.map, key, v)
del self.map[key]
return res
except KeyError:
raise KeyError(f"Key {repr(key)} not found in this tree.")

cpdef public object pop_or_default(self, str key, object default):
cdef object v, nv, res
v = self.map.get(key, default)
res = _c_undelay_data(self.map, key, v)
if key in self.map:
del self.map[key]
return res

cpdef public tuple popitem(self):
cpdef public inline object pop(self, str key):
"""
Pop the item with the given ``key``, and return its value.
After :meth:`pop` method, the ``key`` will be no longer in current storage object.

:param key: Key of the item.
:return: Value of the item.
:raise KeyError: When ``key`` is not exist, raise ``KeyError``.
"""
return undelay(self.map.pop(key))

cpdef public inline object pop_or_default(self, str key, object default):
"""
Pop the item with the given ``key``, return its value when exist, otherwise return ``default``.

:param key: Key of the item.
:param default: Default value of the item.
:return: Value of the item if ``key`` is exist, otherwise return ``default``.
"""
return undelay(self.map.pop(key, default))

cpdef public inline tuple popitem(self):
"""
Pop one item from current storage.

:return: Tuple of the key and its value.
:raise KeyError: When current storage is empty, raise ``KeyError``.
"""
cdef str k
cdef object v
k, v = self.map.popitem()
return k, undelay(v)

cpdef public void del_(self, str key) except *:
try:
del self.map[key]
except KeyError:
raise KeyError(f"Key {repr(key)} not found in this tree.")
cpdef public inline void del_(self, str key) except *:
"""
Delete the item with given ``key``.

cpdef public void clear(self):
:param key: Key of the item.
:raise KeyError: When ``key`` is not exist, raise ``KeyError``.
"""
del self.map[key]

cpdef public inline void clear(self):
"""
Clear all the items in current storage.
"""
self.map.clear()

cpdef public boolean contains(self, str key):
cpdef public inline boolean contains(self, str key):
"""
Return true if ``key`` is exist in current storage, otherwise return false.

:param key: Key.
:return: ``key`` is exist or not.
"""
return key in self.map

cpdef public uint size(self):
cpdef public inline uint size(self):
"""
Return the size of the current storage.

:return: Size of current storage.
"""
return len(self.map)

cpdef public boolean empty(self):
cpdef public inline boolean empty(self):
"""
Return true if current storage is empty (size is 0), otherwise return false.

:return: Empty or not.
"""
return not self.map

cpdef public dict dump(self):
@@ -210,37 +267,67 @@ cdef class TreeStorage:
return hash(tuple(_items))

def iter_keys(self):
"""
Iterate keys in current storage.

:return: Iterator of current keys in normal order.
"""
return self.map.keys()

def iter_rev_keys(self):
"""
Reversely iterate keys in current storage.

:return: Iterator of current keys in reversed order.
"""
return reversed(self.map.keys())

def iter_values(self):
"""
Iterate values in current storage.

:return: Iterator of current values in normal order.
"""
cdef str k
cdef object v, nv
for k, v in self.map.items():
yield _c_undelay_data(self.map, k, v)

def iter_rev_values(self):
"""
Reversely iterate values in current storage.

:return: Iterator of current values in reversed order.
"""
cdef str k
cdef object v, nv
for k, v in reversed(self.map.items()):
yield _c_undelay_data(self.map, k, v)

def iter_items(self):
"""
Iterate items in current storage.

:return: Iterator of current items in normal order.
"""
cdef str k
cdef object v, nv
for k, v in self.map.items():
yield k, _c_undelay_data(self.map, k, v)

def iter_rev_items(self):
"""
Reversely iterate items in current storage.

:return: Iterator of current items in reversed order.
"""
cdef str k
cdef object v, nv
for k, v in reversed(self.map.items()):
yield k, _c_undelay_data(self.map, k, v)


cpdef object create_storage(dict value):
cpdef inline object create_storage(dict value):
cdef dict _map = {}
cdef str k
cdef object v
2 changes: 1 addition & 1 deletion treevalue/tree/general/general.py
Original file line number Diff line number Diff line change
@@ -221,7 +221,7 @@ def walk(self):
- iter: Iterator to walk the given tree, contains 2 items, the 1st one is the full \
path of the node, the 2nd one is the value.

Examples::
Examples:
>>> from treevalue import FastTreeValue, walk
>>> tv1 = FastTreeValue({'a': 1, 'b': 2, 'c': {'x': 2, 'y': 2}})
>>> for k, v in tv1.walk():
2 changes: 1 addition & 1 deletion treevalue/tree/tree/service.pyx
Original file line number Diff line number Diff line change
@@ -119,7 +119,7 @@ cpdef walk(TreeValue tree):
- iter: Iterator to walk the given tree, contains 2 items, the 1st one is the full \
path of the node, the 2nd one is the value.

Examples::
Examples:
>>> from treevalue import TreeValue, walk
>>> tv1 = TreeValue({'a': 1, 'b': 2, 'c': {'x': 2, 'y': 2}})
>>> for k, v in walk(tv1):
Loading