├── .dockerignore ├── .gitignore ├── Cargo.toml ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── builder.Dockerfile ├── deps ├── README.md └── trees │ ├── .gitignore │ ├── Cargo.toml │ ├── LICENSE-APACHE │ ├── LICENSE-MIT │ ├── README.md │ └── src │ ├── bfs.rs │ ├── bfs_impls.rs │ ├── forest.rs │ ├── heap.rs │ ├── into_iter.rs │ ├── iter.rs │ ├── iter_rc.rs │ ├── lib.rs │ ├── macros.rs │ ├── node.rs │ ├── node_vec.rs │ ├── notation.rs │ ├── rc.rs │ ├── size.rs │ ├── tree.rs │ ├── tuple.rs │ └── walk.rs ├── docker-entrypoint.sh ├── redis.conf ├── sentinel.conf ├── src └── lib.rs ├── tester.Dockerfile └── tests ├── README.md ├── __init__.py ├── conftest.py ├── requirements.txt └── test_commands.py /.dockerignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .vscode 3 | target 4 | hacker 5 | */target 6 | tests/.pytest_cache 7 | tests/__pycache__ -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | test/testspace 3 | .vscode 4 | */target 5 | 6 | tests/.pytest_cache 7 | tests/__pycache__ 8 | tree2 9 | .idea 10 | 11 | Cargo.lock -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "redistree" 3 | version = "0.1.0" 4 | authors = ["OhBonsai "] 5 | edition = "2018" 6 | 7 | [lib] 8 | crate-type = ["dylib"] 9 | name = "retree" 10 | 11 | 12 | [dependencies] 13 | redis-module = { version="0.11", features = ["experimental-api"]} 14 | #redis-module = { path= "deps/redis-module", features=["experimental-api"]} 15 | trees = {path= "deps/trees", package="trees"} 16 | 17 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ohbonsai/retree-builder:latest as builder 2 | 3 | ENV LIBDIR /usr/lib/redis/modules 4 | ADD . /RETREE 5 | WORKDIR /RETREE 6 | 7 | # Build the source 8 | RUN set -ex ;\ 9 | cargo build --release ;\ 10 | mv target/release/libretree.so target/release/retree.so 11 | 12 | 13 | #---------------------------------------------------------------------------------------------- 14 | # Package the runner 15 | FROM redis:6.0.10 16 | 17 | WORKDIR /data 18 | COPY --from=builder /RETREE/target/release/retree.so /usr/lib/redis/modules/retree.so 19 | ADD ./redis.conf /etc/redis/redis.conf 20 | ADD ./sentinel.conf /etc/redis/sentinel.conf 21 | ADD ./acl.file /etc/redis/acl.file 22 | COPY docker-entrypoint.sh /docker-entrypoint.sh 23 | RUN chmod a+x /docker-entrypoint.sh 24 | 25 | WORKDIR /data 26 | 27 | # set log path 28 | # set aclfile 29 | # set daemonize no 30 | RUN sed -i 's/^\(logfile .*\)$/# \1/' /etc/redis/redis.conf \ 31 | && echo "\nlogfile /data/redis-server.log" >> /etc/redis/redis.conf \ 32 | && sed -i 's/^\(daemonize .*\)$/# \1/' /etc/redis/redis.conf \ 33 | && echo "\ndaemonize no" >> /etc/redis/redis.conf \ 34 | && echo "\naclfile /etc/redis/acl.file" >> /etc/redis/redis.conf \ 35 | && sed -i 's/^\(user .*\)$/# \1/' /etc/redis/redis.conf 36 | 37 | 38 | 39 | # Load the entrypoint script to be run later 40 | ENTRYPOINT ["/docker-entrypoint.sh"] 41 | 42 | # Invoke the entrypoint script 43 | CMD ["single"] 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Bonsai 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | default: help 2 | .PHONY: default deps builder build tester test clean help 3 | 4 | # Test if the dependencies we need to run this Makefile are installed 5 | ifndef $(shell command -v docker) 6 | @echo "Docker is not available. Please install docker" 7 | @exit 1 8 | endif 9 | 10 | builder: ## build rust cross-compiler base image, for mac developers 11 | docker build -t ohbonsai/retree-builder -f builder.Dockerfile . 12 | 13 | 14 | has_builder := $(shell docker images 'retree-builder' | tail -n 1 | grep 'retree-builder' | awk '{print $2}') 15 | build: ## build retree docker image 16 | ifndef has_builder 17 | @echo "Builder image is not exist, Auto make builder" 18 | @make builder 19 | endif 20 | docker build -t ohbonsai/redistree:latest -f Dockerfile . 21 | 22 | tester: build ## build tester image 23 | docker build -t retree-tester -f tester.Dockerfile . 24 | 25 | test: tester ## do some behavioral tester 26 | docker run -v ${PWD}/tests:/tests --name treetest --rm retree-tester 27 | 28 | 29 | push: build ## push to docker hub 30 | docker push ohbonsai/retree-builder 31 | docker push ohbonsai/redistree 32 | 33 | cluster: run-master run-slave run-sentinel ## run sentinel cluster 34 | 35 | # https://github.com/docker-library/redis/issues/45 36 | # 在mac中,你无法在host直接链接进去 37 | run-master: 38 | docker rm -f master || echo "no contianer is ok" 39 | docker run --name master --net=host -d ohbonsai/redistree master 40 | 41 | run-slave: 42 | docker rm -f slave || echo "no contianer is ok" 43 | docker run --name slave --net=host --env REDIS_PORT=6380 --env MASTER_IP=0.0.0.0 -d ohbonsai/redistree slave 44 | 45 | run-sentinel: 46 | docker rm -f s1 || echo "no container is ok" 47 | docker rm -f s2 || echo "no container is ok" 48 | docker rm -f s3 || echo "no container is ok" 49 | docker run --name s1 --net=host --env REDIS_PORT=26379 --env MASTER_IP=0.0.0.0 -d ohbonsai/redistree sentinel 50 | docker run --name s2 --net=host --env REDIS_PORT=26380 --env MASTER_IP=0.0.0.0 -d ohbonsai/redistree sentinel 51 | docker run --name s3 --net=host --env REDIS_PORT=26381 --env MASTER_IP=0.0.0.0 -d ohbonsai/redistree sentinel 52 | 53 | 54 | clean: ## clean 55 | rm -rf target 56 | rm -rf tests/.pytest_cache 57 | 58 | help: 59 | @grep -E '^[a-zA-Z_-]+:.*?## .*$$' ./Makefile | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RedisTree 2 | RedisTree is a [Redis](https://redis.io/) module that implements Polytree as a native data type. It allows creating,locating,pushing and detaching tree from Redis keys. 3 | **RedisTree has been running in production environment for one year** 4 | 5 | 6 | - 哥,来一趟不容易,点个Star呗 7 | - Не могли бы вы дать мне звезду ... 8 | - Could you give me a star... 9 | - Donne moi une étoile 10 | - 星をください 11 | - 나에게 별을 줘 12 | 13 | ## Why? 14 | Store organization data in redis, Need ploytree and some helper function 15 | 16 | ## Quick Start 17 | 18 | ### Docker 19 | ```shell 20 | # run redis by docker 21 | docker run -p 6379:6379 -d --name redis-redistree ohbonsai/redistree 22 | 23 | # exec redis-cli in redis container 24 | docker exec -it redis-redistree /bin/sh 25 | redis-cli 26 | ``` 27 | 28 | ### Rust 29 | - Run `cargo build` 30 | - Start a redis server with the `redistree` module 31 | * Linux: `redis-server --loadmodule ./target/release/libretree.so` 32 | * Mac: `redis-server --loadmodule ./target/release/libretree.dylib` 33 | - Open a Redis CLI, and run `tree.init hello "a (b (d) c)"`. 34 | 35 | 36 | ## Commands 37 | - `tree.init key tree_value` 38 | - `tree.get key` 39 | - `tree.del key` 40 | - `tree.get_subtree key node_value` 41 | - `tree.del_subtree key node_value` 42 | - `tree.set_subtree key node_value tree_value` 43 | - `tree.get_ancestors key node_value` 44 | - `tree.get_descendants key node_value` 45 | - `tree.get_father key node_value` 46 | - `tree.get_children key node_value` 47 | 48 | ### Init Get Del tree from String 49 | 50 | ``` 51 | a 52 | / \ 53 | b c 54 | | 55 | e 56 | 57 | 127.0.0.1:6379> tree.init hello "a (b (d) c)" 58 | OK 59 | 127.0.0.1:6379> tree.get hello 60 | "a( b( d ) c )" 61 | 127.0.0.1:6379> tree.del hello 62 | OK 63 | 127.0.0.1:6379> tree.get hello 64 | (nil) 65 | 127.0.0.1:6379> tree.init hello "a ((" 66 | (error) ERR () is not closed or no root 67 | 68 | ``` 69 | 70 | 71 | ### Fetch Detach 72 | #### USA government tree 73 | ``` 74 | |----------------------------------USA----------------------------------| 75 | | | | 76 | Legislature ExecutiveJudiciary Judiciary 77 | / \ | | 78 | House Senate WhiteHouse SupremeCourt 79 | | | | | 80 | Pelosi Harris Biden Roberts 81 | 82 | 83 | 127.0.0.1:6379> tree.init usa "USA (Legislature (House (Pelosi) Senate (Harris))ExecutiveJudiciary (WhiteHouse (Biden))Judiciary (SupremeCourt (Roberts)))" 84 | OK 85 | 86 | # Get subtree of executive judiciary 87 | 127.0.0.1:6379> tree.get_subtree usa ExecutiveJudiciary 88 | "ExecutiveJudiciary( WhiteHouse( Biden ) )" 89 | 90 | # Add secretary for Biden 91 | 127.0.0.1:6379> tree.set_subtree usa Biden "Blinken" 92 | OK 93 | # now biden has secretary 94 | 127.0.0.1:6379> tree.get_subtree usa Biden 95 | "Biden( Blinken )" 96 | 97 | # Detach Blinken from Biden 98 | 127.0.0.1:6379> tree.del_subtree usa Blinken 99 | "Blinken" 100 | 127.0.0.1:6379> tree.get_subtree usa Biden 101 | "Biden" 102 | 103 | 104 | # Get Harris ancestors 105 | 127.0.0.1:6379> tree.get_ancestors usa Harris 106 | 1) "Senate" 107 | 2) "Legislature" 108 | 3) "USA" 109 | 110 | # Get Harris Father node 111 | 127.0.0.1:6379> tree.get_father usa Harris 112 | "Senate" 113 | 114 | # Get Legislature Children 115 | 127.0.0.1:6379> tree.get_children usa Legislature 116 | 1) "House" 117 | 2) "Senate" 118 | 119 | 120 | # Get Legislature Descendants(BFS) 121 | 127.0.0.1:6379> tree.get_descendants usa Legislature 122 | 1) "Legislature" 123 | 2) "House" 124 | 3) "Senate" 125 | 4) "Pelosi" 126 | 5) "Harris" 127 | 128 | 129 | ``` 130 | 131 | ## Run 132 | ### Linux 133 | ``` 134 | redis-server --loadmodule yourpath/libretree.so 135 | ``` 136 | 137 | ### Mac 138 | ``` 139 | redis-server --loadmodule ./target/debug/libretree.dylib 140 | ``` 141 | 142 | ### Config 143 | ``` 144 | loadmodule /yourpath/libretree.so 145 | ``` 146 | 147 | 148 | ## Dev 149 | ### Prerequisites 150 | - [Install Rust](https://www.rust-lang.org/tools/install) 151 | - [Install Redis](https://redis.io/download), most likely using your favorite package manager (Homebrew on Mac, APT or YUM on Linux) 152 | 153 | 154 | ### Makefile 155 | ``` 156 | build build retree docker image 157 | builder build rust cross-compiler base image, for mac developers 158 | clean clean 159 | push push to pornhub 160 | test do some behavioral tester 161 | tester build tester image 162 | ``` 163 | 164 | ### TODO 165 | - Postgres ltree gist index 166 | - Postgres ltree query 167 | - Hash Index 168 | 169 | 170 | ## Thanks 171 | - [RedisJSON](https://github.com/RedisJSON/RedisJSON) 172 | - [trees](https://github.com/oooutlk/trees) 173 | -------------------------------------------------------------------------------- /builder.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:latest as builder 2 | 3 | RUN apt-get -qq update -y 4 | RUN apt-get -qq install -y git wget clang cmake 5 | 6 | 7 | 8 | # Inject some package dependency, If not do steps below, Build will pull dependency and compile it every time, It cost to much time 9 | # If code or cargo.toml has big chagne, You can rebuild builder image 10 | ADD . /RETREE 11 | WORKDIR /RETREE 12 | 13 | # Add china crate registry because of china great firewall 14 | RUN echo '[source.crates-io]\nregistry = "https://github.com/rust-lang/crates.io-index"\nreplace-with = "ustc"\n[source.ustc]\nregistry = "git://mirrors.ustc.edu.cn/crates.io-index"' >> /usr/local/cargo/config 15 | 16 | # Build the source 17 | RUN set -ex ;\ 18 | cargo build --release ;\ -------------------------------------------------------------------------------- /deps/README.md: -------------------------------------------------------------------------------- 1 | # Some Change 2 | 3 | - implement some special methods for locating node -------------------------------------------------------------------------------- /deps/trees/.gitignore: -------------------------------------------------------------------------------- 1 | .*.swo 2 | .*.swp 3 | .swp 4 | /target 5 | **/*.rs.bk 6 | Cargo.lock 7 | -------------------------------------------------------------------------------- /deps/trees/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "trees" 3 | version = "0.4.1" 4 | edition = "2018" 5 | authors = ["oooutlk "] 6 | license = "MIT/Apache-2.0" 7 | keywords = [ "tree", "forest", "node", "bfs", "dfs" ] 8 | readme = "README.md" 9 | repository = "https://github.com/oooutlk/trees" 10 | documentation = "https://docs.rs/trees" 11 | categories = [ "data-structures", "no-std" ] 12 | description = "General purpose tree data structures" 13 | 14 | [features] 15 | no_std = [] 16 | -------------------------------------------------------------------------------- /deps/trees/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /deps/trees/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any 2 | person obtaining a copy of this software and associated 3 | documentation files (the "Software"), to deal in the 4 | Software without restriction, including without 5 | limitation the rights to use, copy, modify, merge, 6 | publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software 8 | is furnished to do so, subject to the following 9 | conditions: 10 | 11 | The above copyright notice and this permission notice 12 | shall be included in all copies or substantial portions 13 | of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 16 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 17 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 19 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 22 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /deps/trees/README.md: -------------------------------------------------------------------------------- 1 | This project provides trees data structure serving for general purpose. 2 | 3 | ## Quickstart 4 | 5 | Impatient readers can start with the 6 | [notations](https://oooutlk.github.io/trees/notations.html). 7 | 8 | # Features 9 | 10 | 1. Step-by-step 11 | [creating, reading, updating, deleting](https://oooutlk.github.io/trees/crud.html) 12 | and iterating nodes with assocated data items. 13 | 14 | 2. Compact notations to express trees: `-`,`/` encoded or tuple encoded trees. 15 | 16 | 3. Depth first search cursor. 17 | 18 | 4. Breadth first search iterators. 19 | 20 | 5. Trees can be built by stages, with nodes stored scatteredly among memory. 21 | 22 | 6. Trees can be built once through, with nodes stored contiguously. 23 | 24 | 7. Support exclusive ownership with static borrow check. 25 | 26 | 8. Support shared ownership with dynamic borrow check. 27 | 28 | # Examples 29 | 30 | - notation of a literal tree 31 | 32 | ```rust 33 | use trees::tr; 34 | 35 | let scattered_tree = tr(0) /( tr(1)/tr(2)/tr(3) ) /( tr(4)/tr(5)/tr(6) ); 36 | let piled_tree = trees::Tree::from(( 0, (1,2,3), (4,5,6) )); 37 | ``` 38 | 39 | They both encode a tree drawn as follows: 40 | 41 | ```text 42 | ............. 43 | . 0 . 44 | . / \ . 45 | . 1 4 . 46 | . / \ / \ . 47 | .2 3 5 6. 48 | ............. 49 | ``` 50 | 51 | - use tree notation to reduce syntax noise, quoted from crate `reflection_derive`, [version 0.1.1](https://github.com/oooutlk/reflection/blob/master/reflection_derive/src/lib.rs#L202): 52 | 53 | ```rust 54 | quote! { 55 | #( 56 | -( ::reflection::variant( stringify!( #vnames )) 57 | /( 58 | #( 59 | -( ::reflection::field( 60 | #fnames, 61 | <#ftypes1 as ::reflection::Reflection>::ty(), 62 | <#ftypes2 as ::reflection::Reflection>::name(), 63 | Some( <#ftypes3 as ::reflection::Reflection>::members ))) 64 | )* 65 | ) 66 | ) 67 | )* 68 | } 69 | ``` 70 | 71 | The starting of tree operations are denoted by `-(` and `/(` which are humble enough to let the reader focusing on the data part. 72 | 73 | - use iterators if the tree travesal is a "driving wheel"( you can iterate over the tree on your own ). 74 | 75 | ```rust 76 | use trees::{Node, tr}; 77 | use std::fmt::Display; 78 | 79 | let tree = tr(0) 80 | /( tr(1) /tr(2)/tr(3) ) 81 | /( tr(4) /tr(5)/tr(6) ); 82 | 83 | fn tree_to_string( node: &Node ) -> String { 84 | if node.has_no_child() { 85 | node.data.to_string() 86 | } else { 87 | format!( "{}( {})", node.data, 88 | node.iter().fold( String::new(), 89 | |s,c| s + &tree_to_string(c) + &" " )) 90 | } 91 | } 92 | 93 | assert_eq!( tree_to_string( &tree ), "0( 1( 2 3 ) 4( 5 6 ) )" ); 94 | ``` 95 | 96 | - use `TreeWalk` when the tree travesal is a "driven wheel"( driven by other library ). Quoted from crate `tsv`, [version 0.1.0](https://github.com/oooutlk/tsv/blob/master/src/de.rs#L542): 97 | 98 | ```rust 99 | fn next_value_seed>( &mut self, seed: V ) -> Result { 100 | let result = self.next_element_in_row( seed )?; 101 | self.de.next_column(); 102 | self.de.row += 1; 103 | self.de.pop_stack(); // finish key-value pair 104 | self.de.next_column(); 105 | self.de.columns.revisit(); 106 | Ok( result ) 107 | } 108 | ``` 109 | The `serde` library is driving on the schema tree when (de)serializing variables. Use `TreeWalk` methods such as `next_column` and `revisit` to follow the step. 110 | 111 | # License 112 | 113 | Under Apache License 2.0 or MIT License, at your will. 114 | -------------------------------------------------------------------------------- /deps/trees/src/bfs.rs: -------------------------------------------------------------------------------- 1 | //! Breadth first search. 2 | 3 | use crate::rust::*; 4 | 5 | use super::Size; 6 | 7 | /// Visit a node in breadth first search. 8 | #[derive(Debug, PartialEq, Eq)] 9 | pub struct Visit { 10 | pub data : T, 11 | pub size : Size, 12 | } 13 | 14 | /// Tree iterator for breadth first search. 15 | pub struct BfsTree { 16 | pub iter : Iter, 17 | pub size : Size, 18 | } 19 | 20 | impl BfsTree> 21 | where Iter: Iterator 22 | { 23 | pub fn from( treelike: Treelike, size: Size ) -> Self 24 | where Treelike: IntoIterator 25 | { 26 | Self{ iter: Splitted::::from( treelike ), size: size } 27 | } 28 | } 29 | 30 | impl BfsTree { 31 | pub fn wrap( self ) -> Bfs { Bfs::Tree( self )} 32 | 33 | /// Takes a closure and creates another BfsTree which calls that closure on 34 | /// each `Visit::data`. 35 | /// 36 | /// # Examples 37 | /// 38 | /// ```rust 39 | /// use trees::Tree; 40 | /// 41 | /// let tree = Tree::::from_tuple(( 0, (1,2,3), (4,5,6), )); 42 | /// assert_eq!( Tree::from( tree.bfs() ), 43 | /// Tree::<&i32>::from_tuple(( &0, (&1,&2,&3), (&4,&5,&6), ))); 44 | /// assert_eq!( Tree::from( tree.bfs().map( ToOwned::to_owned )), 45 | /// Tree::::from_tuple(( 0, (1,2,3), (4,5,6), ))); 46 | /// ``` 47 | pub fn map( self, mut f: F ) -> BfsTree>> 48 | where Iter : Iterator> 49 | , F : FnMut(T) -> B 50 | { 51 | BfsTree { 52 | iter: self.iter.map( move |visit| Visit{ data: f( visit.data ), size: visit.size }), 53 | size: self.size, 54 | } 55 | } 56 | } 57 | 58 | /// Forest iterator for breadth first search. 59 | pub struct BfsForest { 60 | pub iter : Iter, 61 | pub size : Size, 62 | } 63 | 64 | impl BfsForest> 65 | where Iter: Iterator 66 | { 67 | pub fn from( treelike: Treelike, size: Size ) -> Self 68 | where Treelike: IntoIterator 69 | { 70 | Self{ iter: Splitted::::from( treelike ), size: size } 71 | } 72 | } 73 | 74 | impl BfsForest { 75 | pub fn wrap( self ) -> Bfs { Bfs::Forest( self )} 76 | 77 | /// Takes a closure and creates another BfsForest which calls that closure 78 | /// on each `Visit::data`. 79 | /// 80 | /// # Examples 81 | /// 82 | /// ```rust 83 | /// use trees::Forest; 84 | /// 85 | /// let forest = Forest::::from_tuple(( 0, (1,2,3), (4,5,6), )); 86 | /// assert_eq!( Forest::from( forest.bfs() ), 87 | /// Forest::<&i32>::from_tuple(( &0, (&1,&2,&3), (&4,&5,&6), ))); 88 | /// assert_eq!( Forest::from( forest.bfs().map( ToOwned::to_owned )), 89 | /// Forest::::from_tuple(( 0, (1,2,3), (4,5,6), ))); 90 | /// ``` 91 | pub fn map( self, mut f: F ) -> BfsForest>> 92 | where Iter : Iterator> 93 | , F : FnMut(T) -> B 94 | { 95 | BfsForest { 96 | iter: self.iter.map( move |visit| Visit{ data: f( visit.data ), size: visit.size }), 97 | size: self.size, 98 | } 99 | } 100 | } 101 | 102 | /// Bfs iterator of either tree or forest. 103 | pub enum Bfs { 104 | Tree( BfsTree ), 105 | Forest( BfsForest ), 106 | } 107 | 108 | impl Bfs 109 | where Iter: Iterator> 110 | { 111 | /// Returns the iterator in breadth-first search. 112 | pub fn iter( self ) -> Iter { 113 | match self { 114 | Bfs::Tree( tree ) => tree.iter, 115 | Bfs::Forest( forest ) => forest.iter, 116 | } 117 | } 118 | 119 | /// Returns the iterator and size infomation. 120 | pub fn iter_and_size( self ) -> ( Iter, Size ) { 121 | match self { 122 | Bfs::Tree( tree ) => (tree.iter, tree.size), 123 | Bfs::Forest( forest ) => (forest.iter, forest.size), 124 | } 125 | } 126 | 127 | /// Returns the iterator which iterates the tree nodes in breadth-first 128 | /// search, or `None` if it is created by some `Forest`. 129 | pub fn tree_iter( self ) -> Option { 130 | match self { 131 | Bfs::Tree( tree ) => Some( tree.iter ), 132 | _ => None, 133 | } 134 | } 135 | 136 | /// Returns the iterator which iterates the forest nodes in breadth-first 137 | /// search, or `None` if it is created by some `Tree`. 138 | pub fn forest_iter( self ) -> Option { 139 | match self { 140 | Bfs::Forest( forest ) => Some( forest.iter ), 141 | _ => None, 142 | } 143 | } 144 | } 145 | 146 | /// Split tree node into data item and children iter. 147 | pub trait Split { 148 | type Item; 149 | type Iter: ExactSizeIterator; 150 | 151 | fn split( self ) -> (Self::Item, Self::Iter, usize); 152 | } 153 | 154 | /// An iterator in breadth-first manner. 155 | #[derive( Debug )] 156 | pub struct Splitted { 157 | pub(crate) iters : VecDeque, 158 | } 159 | 160 | impl From for Splitted 161 | where Treelike : IntoIterator 162 | , Iter : Iterator 163 | { 164 | fn from( treelike: Treelike ) -> Self { 165 | let mut iters = VecDeque::new(); 166 | iters.push_back( treelike.into_iter() ); 167 | Splitted{ iters } 168 | } 169 | } 170 | 171 | impl Iterator for Splitted 172 | where Iter : ExactSizeIterator 173 | , Item : Split 174 | { 175 | type Item = Visit; 176 | 177 | fn next( &mut self ) -> Option { 178 | loop { 179 | let next_item = 180 | if let Some( ref mut iter ) = self.iters.front_mut() { 181 | iter.next() 182 | } else { 183 | return None; 184 | }; 185 | if let Some( item ) = next_item { 186 | let (data, iter, descendants) = item.split(); 187 | let degree = iter.len(); 188 | self.iters.push_back( iter ); 189 | return Some( Visit{ data, size: Size{ degree, descendants }}); 190 | } else { 191 | self.iters.pop_front(); 192 | } 193 | } 194 | } 195 | } 196 | 197 | #[cfg( miri )] 198 | mod miri_tests { 199 | mod bfs_tree { 200 | #[test] fn map() { 201 | use crate::Tree; 202 | 203 | let tree = Tree::::from_tuple(( 0, (1,2,3), (4,5,6), )); 204 | assert_eq!( Tree::from( tree.bfs() ), 205 | Tree::<&i32>::from_tuple(( &0, (&1,&2,&3), (&4,&5,&6), ))); 206 | assert_eq!( Tree::from( tree.bfs().map( ToOwned::to_owned )), 207 | Tree::::from_tuple(( 0, (1,2,3), (4,5,6), ))); 208 | } 209 | } 210 | 211 | mod bfs_forest { 212 | #[test] fn map() { 213 | use crate::Forest; 214 | 215 | let forest = Forest::::from_tuple(( 0, (1,2,3), (4,5,6), )); 216 | assert_eq!( Forest::from( forest.bfs() ), 217 | Forest::<&i32>::from_tuple(( &0, (&1,&2,&3), (&4,&5,&6), ))); 218 | assert_eq!( Forest::from( forest.bfs().map( ToOwned::to_owned )), 219 | Forest::::from_tuple(( 0, (1,2,3), (4,5,6), ))); 220 | } 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /deps/trees/src/bfs_impls.rs: -------------------------------------------------------------------------------- 1 | use crate::Size; 2 | 3 | use crate::bfs::{BfsForest, BfsTree, Split, Splitted, Visit}; 4 | 5 | use crate::rust::*; 6 | 7 | use super::{Data, Forest, IntoIter, Iter, IterMut, Node, NodeVec, Tree}; 8 | 9 | impl Node { 10 | /// Clones the node deeply and creates a new tree. 11 | /// 12 | /// # Examples 13 | /// 14 | /// ``` 15 | /// use trees::Tree; 16 | /// 17 | /// let tree = Tree::::from_tuple(( 0, (1,2,3), (4,5,6), (7,8,9), )); 18 | /// assert_eq!( tree.iter().nth(1).unwrap().deep_clone(), 19 | /// Tree::from_tuple(( 4,5,6 ))); 20 | /// ``` 21 | pub fn deep_clone( &self ) -> Tree 22 | where T: Clone 23 | { 24 | let (iter,size) = self.bfs().wrap().iter_and_size(); 25 | let bfs_tree = BfsTree { 26 | iter: iter.map( |visit| Visit{ data: visit.data.clone(), size: visit.size }), 27 | size, 28 | }; 29 | 30 | Tree::from( bfs_tree ) 31 | } 32 | 33 | /// Clones the node's descendant nodes as a forest. 34 | /// 35 | /// # Examples 36 | /// 37 | /// ``` 38 | /// use trees::{Tree,Forest}; 39 | /// 40 | /// let tree = Tree::::from_tuple(( 0, (1,2,3), (4,5,6), (7,8,9), )); 41 | /// assert_eq!( tree.iter().nth(1).unwrap().deep_clone_forest(), 42 | /// Forest::from_tuple(( 5,6 ))); 43 | /// ``` 44 | pub fn deep_clone_forest( &self ) -> Forest 45 | where T: Clone 46 | { 47 | let (iter,size) = self.bfs_children().wrap().iter_and_size(); 48 | let bfs_forest = BfsForest { 49 | iter: iter.map( |visit| Visit{ data: visit.data.clone(), size: visit.size }), 50 | size, 51 | }; 52 | 53 | Forest::from( bfs_forest ) 54 | } 55 | 56 | /// Provides a forward iterator in a breadth-first manner, which iterates over all its descendants. 57 | /// 58 | /// # Examples 59 | /// 60 | /// ``` 61 | /// use trees::Tree; 62 | /// 63 | /// let tree = Tree::from_tuple(( 0, (1,2,3), (4,5,6), )); 64 | /// let visits = tree.root().bfs_children().iter 65 | /// .map( |visit| (*visit.data, visit.size.degree, visit.size.descendants )) 66 | /// .collect::>(); 67 | /// assert_eq!( visits, vec![ (1, 2, 2), (4, 2, 2), (2, 0, 0), (3, 0, 0), (5, 0, 0), (6, 0, 0), ]); 68 | /// ``` 69 | pub fn bfs_children( &self ) -> BfsForest>> { BfsForest::from( self.iter(), self.size )} 70 | 71 | /// Provides a forward iterator with mutable references in a breadth-first manner, which iterates over all its descendants. 72 | /// 73 | /// # Examples 74 | /// 75 | /// ``` 76 | /// use trees::{tr, Tree}; 77 | /// 78 | /// let mut tree = Tree::from_tuple(( 0, (1,2,3), (4,5,6), )); 79 | /// let mut root = tree.root_mut(); 80 | /// root.bfs_children_mut().iter 81 | /// .zip( 1.. ) 82 | /// .for_each( |(visit,nth)| *visit.data += 10 * nth ); 83 | /// assert_eq!( tree, Tree::::from_tuple(( 0, (11,32,43), (24,55,66), ))); 84 | /// ``` 85 | pub fn bfs_children_mut( &mut self ) -> BfsForest>> { 86 | let size = self.size; 87 | BfsForest::from( self.iter_mut(), size ) 88 | } 89 | 90 | /// Provides a forward iterator in a breadth-first manner. 91 | /// 92 | /// # Examples 93 | /// 94 | /// ``` 95 | /// use trees::Tree; 96 | /// 97 | /// let tree = Tree::from_tuple(( 0, (1,2,3), (4,5,6), )); 98 | /// let visits = tree.root().bfs().iter 99 | /// .map( |visit| (*visit.data, visit.size.degree, visit.size.descendants )) 100 | /// .collect::>(); 101 | /// assert_eq!( visits, vec![ (0, 2, 6), (1, 2, 2), (4, 2, 2), (2, 0, 0), (3, 0, 0), (5, 0, 0), (6, 0, 0), ]); 102 | /// ``` 103 | pub fn bfs( &self ) -> BfsTree>> { 104 | BfsTree::from( self.into_iter(), Size{ degree: 1, descendants: self.size.descendants }) 105 | } 106 | 107 | /// Provides a forward iterator with mutable references in a breadth-first manner. 108 | /// 109 | /// # Examples 110 | /// 111 | /// ``` 112 | /// use trees::{tr, Tree}; 113 | /// 114 | /// let mut tree = Tree::from_tuple(( 0, (1,2,3), (4,5,6), )); 115 | /// let mut root = tree.root_mut(); 116 | /// root.bfs_mut().iter 117 | /// .zip( 1.. ) 118 | /// .for_each( |(visit,nth)| *visit.data += 10 * nth ); 119 | /// assert_eq!( tree, Tree::::from_tuple(( 10, (21,42,53), (34,65,76), ))); 120 | /// ``` 121 | pub fn bfs_mut( &mut self ) -> BfsTree>> { 122 | let size = Size{ degree: 1, descendants: self.size.descendants }; 123 | BfsTree::from( unsafe{ Pin::new_unchecked( self )}, size ) 124 | } 125 | } 126 | 127 | impl<'a, T:'a> Split for &'a Node { 128 | type Item = &'a T; 129 | type Iter = Iter<'a,T>; 130 | 131 | fn split( self ) -> (Self::Item, Self::Iter, usize) { 132 | (self.data(), self.iter(), self.size.descendants) 133 | } 134 | } 135 | 136 | impl<'a, T:'a> Split for Pin<&'a mut Node> { 137 | type Item = &'a mut T; 138 | type Iter = IterMut<'a,T>; 139 | 140 | fn split( self ) -> (Self::Item, Self::Iter, usize) { 141 | let descendants = self.size.descendants; 142 | unsafe { 143 | let node_mut = self.get_unchecked_mut() as *mut Node; 144 | let data = (*node_mut).data_mut() as *mut T; 145 | let iter = (*node_mut).iter_mut(); 146 | (&mut *data, iter, descendants) 147 | } 148 | } 149 | } 150 | 151 | impl Forest { 152 | /// Provides a forward iterator in a breadth-first manner. 153 | /// 154 | /// # Examples 155 | /// 156 | /// ``` 157 | /// use trees::Forest; 158 | /// 159 | /// let forest = Forest::from_tuple(( (1,2,3), (4,5,6), )); 160 | /// let visits = forest.bfs().iter 161 | /// .map( |visit| (*visit.data, visit.size.degree, visit.size.descendants )) 162 | /// .collect::>(); 163 | /// assert_eq!( visits, vec![ (1, 2, 2), (4, 2, 2), (2, 0, 0), (3, 0, 0), (5, 0, 0), (6, 0, 0), ]); 164 | /// ``` 165 | pub fn bfs( &self ) -> BfsForest>> { BfsForest::from( self.iter(), self.root_().size )} 166 | 167 | /// Provides a forward iterator with mutable references in a breadth-first manner. 168 | /// 169 | /// # Examples 170 | /// 171 | /// ``` 172 | /// use trees::Forest; 173 | /// 174 | /// let mut forest = Forest::::from_tuple(( (1,2,3), (4,5,6), )); 175 | /// forest.bfs_mut().iter 176 | /// .zip( 0.. ) 177 | /// .for_each( |(visit,nth)| *visit.data += 10 * nth ); 178 | /// assert_eq!( forest, Forest::from_tuple(( (1,(22,),(33,)), (14,(45,),(56,)), ))); 179 | /// ``` 180 | pub fn bfs_mut( &mut self ) -> BfsForest>> { 181 | let size = self.root_().size; 182 | BfsForest::from( self.iter_mut(), size ) 183 | } 184 | 185 | /// Provides a forward iterator with owned data in a breadth-first manner. 186 | /// 187 | /// # Examples 188 | /// 189 | /// ``` 190 | /// use trees::{bfs,Size}; 191 | /// use trees::Forest; 192 | /// 193 | /// let forest = Forest::::new(); 194 | /// let visits = forest.into_bfs().iter.collect::>(); 195 | /// assert!( visits.is_empty() ); 196 | /// 197 | /// let forest = Forest::from_tuple(( (1,2,3), (4,5,6), )); 198 | /// let visits = forest.into_bfs().iter.collect::>(); 199 | /// assert_eq!( visits, vec![ 200 | /// bfs::Visit{ data: 1, size: Size{ degree: 2, descendants: 2 }}, 201 | /// bfs::Visit{ data: 4, size: Size{ degree: 2, descendants: 2 }}, 202 | /// bfs::Visit{ data: 2, size: Size{ degree: 0, descendants: 0 }}, 203 | /// bfs::Visit{ data: 3, size: Size{ degree: 0, descendants: 0 }}, 204 | /// bfs::Visit{ data: 5, size: Size{ degree: 0, descendants: 0 }}, 205 | /// bfs::Visit{ data: 6, size: Size{ degree: 0, descendants: 0 }}, 206 | /// ]); 207 | /// ``` 208 | pub fn into_bfs( self: Forest ) -> BfsForest>> { 209 | let size = self.root_().size; 210 | BfsForest::from( self.into_iter(), size ) 211 | } 212 | } 213 | 214 | impl Tree { 215 | /// Provides a forward iterator with mutable references in a breadth-first manner, which iterates over all its descendants. 216 | /// 217 | /// # Examples 218 | /// 219 | /// ``` 220 | /// use trees::{tr, Tree}; 221 | /// 222 | /// let mut tree = Tree::from_tuple(( 0, (1,2,3), (4,5,6), )); 223 | /// tree.bfs_children_mut().iter 224 | /// .zip( 1.. ) 225 | /// .for_each( |(visit,nth)| *visit.data += 10 * nth ); 226 | /// assert_eq!( tree, Tree::::from_tuple(( 0, (11,32,43), (24,55,66), ))); 227 | /// ``` 228 | pub fn bfs_children_mut( &mut self ) -> BfsForest>> { self.root_mut_().bfs_children_mut() } 229 | 230 | /// Provides a forward iterator with mutable references in a breadth-first manner. 231 | /// 232 | /// # Examples 233 | /// 234 | /// ``` 235 | /// use trees::{tr, Tree}; 236 | /// 237 | /// let mut tree = Tree::from_tuple(( 0, (1,2,3), (4,5,6), )); 238 | /// tree.bfs_mut().iter 239 | /// .zip( 1.. ) 240 | /// .for_each( |(visit,nth)| *visit.data += 10 * nth ); 241 | /// assert_eq!( tree, Tree::::from_tuple(( 10, (21,42,53), (34,65,76), ))); 242 | /// ``` 243 | pub fn bfs_mut( &mut self ) -> BfsTree>> { self.root_mut_().bfs_mut() } 244 | 245 | /// Provides a forward iterator with owned data in a breadth-first manner. 246 | /// 247 | /// # Examples 248 | /// 249 | /// ``` 250 | /// use trees::{bfs,Size}; 251 | /// use trees::Tree; 252 | /// 253 | /// let tree = Tree::::from_tuple(( 0, (1,2,3), (4,5,6) )); 254 | /// let visits = tree.into_bfs().iter.collect::>(); 255 | /// assert_eq!( visits, vec![ 256 | /// bfs::Visit{ data: 0, size: Size{ degree: 2, descendants: 6 }}, 257 | /// bfs::Visit{ data: 1, size: Size{ degree: 2, descendants: 2 }}, 258 | /// bfs::Visit{ data: 4, size: Size{ degree: 2, descendants: 2 }}, 259 | /// bfs::Visit{ data: 2, size: Size{ degree: 0, descendants: 0 }}, 260 | /// bfs::Visit{ data: 3, size: Size{ degree: 0, descendants: 0 }}, 261 | /// bfs::Visit{ data: 5, size: Size{ degree: 0, descendants: 0 }}, 262 | /// bfs::Visit{ data: 6, size: Size{ degree: 0, descendants: 0 }}, 263 | /// ]); 264 | /// ``` 265 | pub fn into_bfs( self ) -> BfsTree>> { 266 | let size = Size{ degree: 1, descendants: self.root().size.descendants }; 267 | BfsTree::from( self, size ) 268 | } 269 | } 270 | 271 | impl From> for Tree 272 | where Iter: Iterator> 273 | { 274 | fn from( tree_iter: BfsTree ) -> Self { 275 | let mut iter = tree_iter.wrap().iter(); 276 | let visit_root = iter.next().unwrap(); 277 | let (degree, node_cnt) = (visit_root.size.degree, visit_root.size.descendants+1); 278 | 279 | let mut node_vec = NodeVec::new_raw_non_null( node_cnt ); 280 | 281 | unsafe { 282 | node_vec.as_mut().make_piled_node( None, 0, visit_root.data, visit_root.size ); 283 | } 284 | 285 | let mut parent = 0; 286 | let mut child = 1; 287 | let mut remains = degree; 288 | 289 | while let Some( visit ) = iter.next() { 290 | unsafe { 291 | node_vec.as_mut().append_child( parent, child, visit.data, visit.size ); 292 | } 293 | remains -= 1; 294 | while remains == 0 { 295 | parent += 1; 296 | unsafe { 297 | remains = node_vec.as_mut().node( parent ).degree(); 298 | } 299 | if parent == child { break; } 300 | } 301 | child += 1; 302 | } 303 | 304 | Tree::from_node( unsafe{ node_vec.as_ref().non_null_node(0) }) 305 | } 306 | } 307 | 308 | impl Split for Tree { 309 | type Item = T; 310 | type Iter = IntoIter; 311 | 312 | fn split( mut self ) -> (T, IntoIter, usize) { 313 | let descendants = self.root().size.descendants; 314 | let iter = self.abandon().into_iter(); 315 | let data = self.into_data(); 316 | (data, iter, descendants) 317 | } 318 | } 319 | 320 | impl From> for Forest 321 | where Iter: Iterator> 322 | { 323 | fn from( forest_iter: BfsForest ) -> Self { 324 | let (mut iter, size) = forest_iter.wrap().iter_and_size(); 325 | let (degree, node_cnt) = (size.degree, size.descendants+1); 326 | 327 | let mut node_vec = NodeVec::new_raw_non_null( node_cnt ); 328 | 329 | unsafe { 330 | let fake_root = Data::PiledNone{ owner: node_vec }; 331 | node_vec.as_mut().make_node( None, 0, fake_root, size ); 332 | } 333 | 334 | let mut parent = 0; 335 | let mut child = 1; 336 | let mut remains = degree; 337 | 338 | while let Some( visit ) = iter.next() { 339 | unsafe { 340 | node_vec.as_mut().append_child( parent, child, visit.data, visit.size ); 341 | } 342 | remains -= 1; 343 | while remains == 0 { 344 | parent += 1; 345 | unsafe { 346 | remains = node_vec.as_mut().node( parent ).degree(); 347 | } 348 | if parent == child { break; } 349 | } 350 | child += 1; 351 | } 352 | 353 | Forest::from_node( unsafe{ node_vec.as_ref().non_null_node(0) }) 354 | } 355 | } 356 | 357 | #[cfg( test )] 358 | mod tests { 359 | use super::*; 360 | use super::super::tr; 361 | 362 | #[test] fn piled_tree_from_bfs() { 363 | let linked = tr(0) /( tr(1)/tr(2)/tr(3) ) /( tr(4)/tr(5)/tr(6) ); 364 | let piled = Tree::::from( linked.into_bfs() ); 365 | assert_eq!( piled.to_string(), "0( 1( 2 3 ) 4( 5 6 ) )" ); 366 | } 367 | 368 | #[test] fn piled_forest_from_bfs() { 369 | let linked = -( tr(1)/tr(2)/tr(3) ) -( tr(4)/tr(5)/tr(6) ); 370 | let bfs = linked.into_bfs(); 371 | let piled = Forest::::from( bfs ); 372 | assert_eq!( piled.to_string(), "( 1( 2 3 ) 4( 5 6 ) )" ); 373 | } 374 | 375 | #[test] fn piled_tree_from_bfs_1_1() { 376 | let linked = tr(1) /( tr(2) /tr(3) ); 377 | let bfs = linked.into_bfs(); 378 | let piled = Tree::::from( bfs ); 379 | assert_eq!( piled.to_string(), "1( 2( 3 ) )" ); 380 | } 381 | 382 | #[test] fn piled_forest_from_bfs_1_1() { 383 | let forest = -( tr(1) /tr(2) ); 384 | let bfs = forest.into_bfs(); 385 | let forest = Forest::::from( bfs ); 386 | assert_eq!( forest.to_string(), "( 1( 2 ) )" ); 387 | } 388 | } 389 | 390 | #[cfg( miri )] 391 | mod miri_tests { 392 | mod node { 393 | #[test] fn deep_clone() { 394 | use crate::Tree; 395 | 396 | let tree = Tree::::from_tuple(( 0, (1,2,3), (4,5,6), (7,8,9), )); 397 | assert_eq!( tree.iter().nth(1).unwrap().deep_clone(), Tree::from_tuple(( 4,5,6 ))); 398 | } 399 | 400 | #[test] fn deep_clone_forest() { 401 | use crate::{Forest, Tree}; 402 | 403 | let tree = Tree::::from_tuple(( 0, (1,2,3), (4,5,6), (7,8,9), )); 404 | assert_eq!( tree.iter().nth(1).unwrap().deep_clone_forest(), Forest::from_tuple(( 5,6 ))); 405 | } 406 | 407 | #[test] fn bfs_children() { 408 | use crate::Tree; 409 | 410 | let tree = Tree::from_tuple(( 0, (1,2,3), (4,5,6), )); 411 | let visits = tree.root().bfs_children().iter.map( |visit| (*visit.data, visit.size.degree, visit.size.descendants )).collect::>(); 412 | assert_eq!( visits, vec![ (1, 2, 2), (4, 2, 2), (2, 0, 0), (3, 0, 0), (5, 0, 0), (6, 0, 0), ]); 413 | } 414 | 415 | #[test] fn bfs_children_mut() { 416 | use crate::Tree; 417 | 418 | let mut tree = Tree::from_tuple(( 0, (1,2,3), (4,5,6), )); 419 | let mut root = tree.root_mut(); 420 | root.bfs_children_mut().iter.zip( 1.. ).for_each( |(visit,nth)| *visit.data += 10 * nth ); 421 | assert_eq!( tree, Tree::::from_tuple(( 0, (11,32,43), (24,55,66), ))); 422 | } 423 | 424 | #[test] fn bfs() { 425 | use crate::Tree; 426 | 427 | let tree = Tree::from_tuple(( 0, (1,2,3), (4,5,6), )); 428 | let visits = tree.root().bfs().iter.map( |visit| (*visit.data, visit.size.degree, visit.size.descendants )).collect::>(); 429 | assert_eq!( visits, vec![ (0, 2, 6), (1, 2, 2), (4, 2, 2), (2, 0, 0), (3, 0, 0), (5, 0, 0), (6, 0, 0), ]); 430 | } 431 | 432 | #[test] fn bfs_mut() { 433 | use crate::Tree; 434 | 435 | let mut tree = Tree::from_tuple(( 0, (1,2,3), (4,5,6), )); 436 | let mut root = tree.root_mut(); 437 | root.bfs_mut().iter.zip( 1.. ).for_each( |(visit,nth)| *visit.data += 10 * nth ); 438 | assert_eq!( tree, Tree::::from_tuple(( 10, (21,42,53), (34,65,76), ))); 439 | } 440 | } 441 | 442 | mod forest { 443 | #[test] fn bfs() { 444 | use crate::Forest; 445 | 446 | let forest = Forest::from_tuple(( (1,2,3), (4,5,6), )); 447 | let visits = forest.bfs().iter.map( |visit| (*visit.data, visit.size.degree, visit.size.descendants )).collect::>(); 448 | assert_eq!( visits, vec![ (1, 2, 2), (4, 2, 2), (2, 0, 0), (3, 0, 0), (5, 0, 0), (6, 0, 0), ]); 449 | } 450 | 451 | #[test] fn bfs_mut() { 452 | use crate::Forest; 453 | let mut forest = Forest::::from_tuple(( (1,2,3), (4,5,6), )); 454 | forest.bfs_mut().iter.zip( 0.. ).for_each( |(visit,nth)| *visit.data += 10 * nth ); 455 | assert_eq!( forest, Forest::from_tuple(( (1,(22,),(33,)), (14,(45,),(56,)), ))); 456 | } 457 | 458 | #[test] fn into_bfs() { 459 | use crate::{Forest, Size, bfs}; 460 | 461 | let forest = Forest::::new(); 462 | let visits = forest.into_bfs().iter.collect::>(); 463 | assert!( visits.is_empty() ); 464 | 465 | let forest = Forest::from_tuple(( (1,2,3), (4,5,6), )); 466 | let visits = forest.into_bfs().iter.collect::>(); 467 | assert_eq!( visits, vec![ 468 | bfs::Visit{ data: 1, size: Size{ degree: 2, descendants: 2 }}, 469 | bfs::Visit{ data: 4, size: Size{ degree: 2, descendants: 2 }}, 470 | bfs::Visit{ data: 2, size: Size{ degree: 0, descendants: 0 }}, 471 | bfs::Visit{ data: 3, size: Size{ degree: 0, descendants: 0 }}, 472 | bfs::Visit{ data: 5, size: Size{ degree: 0, descendants: 0 }}, 473 | bfs::Visit{ data: 6, size: Size{ degree: 0, descendants: 0 }}, 474 | ]); 475 | } 476 | } 477 | 478 | mod tree { 479 | #[test] fn bfs_children_mut() { 480 | use crate::Tree; 481 | let mut tree = Tree::from_tuple(( 0, (1,2,3), (4,5,6), )); 482 | tree.bfs_children_mut().iter.zip( 1.. ).for_each( |(visit,nth)| *visit.data += 10 * nth ); 483 | assert_eq!( tree, Tree::::from_tuple(( 0, (11,32,43), (24,55,66), ))); 484 | } 485 | 486 | #[test] fn bfs_mut() { 487 | use crate::Tree; 488 | 489 | let mut tree = Tree::from_tuple(( 0, (1,2,3), (4,5,6), )); 490 | tree.bfs_mut().iter.zip( 1.. ).for_each( |(visit,nth)| *visit.data += 10 * nth ); 491 | assert_eq!( tree, Tree::::from_tuple(( 10, (21,42,53), (34,65,76), ))); 492 | } 493 | 494 | #[test] fn into_bfs() { 495 | use crate::{Tree, Size, bfs}; 496 | 497 | let tree = Tree::::from_tuple(( 0, (1,2,3), (4,5,6) )); 498 | let visits = tree.into_bfs().iter.collect::>(); 499 | assert_eq!( visits, vec![ 500 | bfs::Visit{ data: 0, size: Size{ degree: 2, descendants: 6 }}, 501 | bfs::Visit{ data: 1, size: Size{ degree: 2, descendants: 2 }}, 502 | bfs::Visit{ data: 4, size: Size{ degree: 2, descendants: 2 }}, 503 | bfs::Visit{ data: 2, size: Size{ degree: 0, descendants: 0 }}, 504 | bfs::Visit{ data: 3, size: Size{ degree: 0, descendants: 0 }}, 505 | bfs::Visit{ data: 5, size: Size{ degree: 0, descendants: 0 }}, 506 | bfs::Visit{ data: 6, size: Size{ degree: 0, descendants: 0 }}, 507 | ]); 508 | } 509 | } 510 | } 511 | -------------------------------------------------------------------------------- /deps/trees/src/forest.rs: -------------------------------------------------------------------------------- 1 | //! Composed of a list of `Node`s as its children. 2 | //! 3 | //! 1. Support adding and storing nodes only once on tree creation, in a 4 | //! contiguous memory address. 5 | //! 6 | //! 2. Support adding and storing nodes one by one, in scattered memory 7 | //! allocations. 8 | //! 9 | //! 3. Tuple notations for construction. 10 | //! 11 | //! 4. `fr()`,`-`,`/` notations for construction. 12 | 13 | use super::heap; 14 | use super::{Tree, Node, Data, Iter, IterMut}; 15 | use super::NodeVec; 16 | use crate::{Size, TupleForest}; 17 | 18 | use crate::rust::*; 19 | 20 | /// List of `Node`s as its children. 21 | pub struct Forest { 22 | root : NonNull>, 23 | mark : PhantomData>, 24 | } 25 | 26 | impl Forest { 27 | pub(crate) fn root_( &self ) -> &Node { unsafe{ &*self.root.as_ptr() }} 28 | pub(crate) fn root_mut_( &mut self ) -> &mut Node { unsafe{ &mut *self.root.as_ptr() }} 29 | 30 | /// Makes an empty `Forest`. 31 | pub fn new() -> Forest { 32 | Forest::from_node( heap::make_node( Data::ScatteredNone{ owner: NonNull::dangling() })) 33 | } 34 | 35 | /// Construct forest from tuple notations. 36 | /// 37 | /// # Examples 38 | /// 39 | /// ``` 40 | /// use trees::{Forest, tr}; 41 | /// 42 | /// let forest = Forest::::from_tuple(( 0, (1,2), (3,4) )); 43 | /// assert_eq!( forest, -tr(0) -tr(1)/tr(2) -tr(3)/tr(4) ); 44 | /// assert_eq!( forest.to_string(), "( 0 1( 2 ) 3( 4 ) )" ); 45 | /// ``` 46 | pub fn from_tuple( tuple: Tuple ) -> Self 47 | where Tuple : TupleForest 48 | { 49 | let node_count = >::SIZE.descendants + 1; 50 | let mut node_vec = NodeVec::new_raw_non_null( node_count ); 51 | unsafe{ node_vec.as_mut().construct_forest( tuple )}; 52 | 53 | Forest::from_node( unsafe{ node_vec.as_ref().non_null_node(0) }) 54 | } 55 | 56 | pub(crate) fn from_node( root: NonNull> ) -> Forest { 57 | Forest{ root, mark: PhantomData } 58 | } 59 | 60 | pub(crate) fn set_up( &mut self, parent: &mut Node ) { 61 | self.iter_mut() 62 | .map( |node| unsafe{ Pin::get_unchecked_mut( node )}) 63 | .for_each( |node| node.set_up( parent )); 64 | } 65 | 66 | pub(crate) fn clear( &mut self ) { 67 | unsafe { 68 | let root = self.root.as_mut(); 69 | root.head = None; 70 | root.tail = None; 71 | root.size = Size::default(); 72 | } 73 | } 74 | 75 | /// Returns `true` if `Forest` is empty. 76 | /// 77 | /// # Examples 78 | /// 79 | /// ``` 80 | /// use trees::{tr, fr}; 81 | /// let mut forest = fr(); 82 | /// assert!( forest.has_no_child() ); 83 | /// forest.push_back( tr(1) ); 84 | /// assert!( !forest.has_no_child() ); 85 | /// ``` 86 | pub fn has_no_child( &self ) -> bool { self.root_().has_no_child() } 87 | 88 | /// Returns the number of child nodes in `Forest`. 89 | /// 90 | /// # Examples 91 | /// 92 | /// ``` 93 | /// use trees::Forest; 94 | /// let forest = Forest::::from_tuple(( 0, (1,2), (3,4) )); 95 | /// assert_eq!( forest.degree(), 3 ); 96 | /// ``` 97 | pub fn degree( &self ) -> usize { self.root_().degree() } 98 | 99 | /// Returns the number of all child nodes in `Forest`. 100 | /// 101 | /// # Examples 102 | /// 103 | /// ``` 104 | /// use trees::Forest; 105 | /// let forest = Forest::::from_tuple(( 0, (1,2), (3,4) )); 106 | /// assert_eq!( forest.node_count(), 5 ); 107 | /// ``` 108 | pub fn node_count( &self ) -> usize { self.root_().node_count() } 109 | 110 | /// Provides a forward iterator over child `Node`s. 111 | /// 112 | /// # Examples 113 | /// 114 | /// ``` 115 | /// use trees::{tr, fr}; 116 | /// 117 | /// let forest = fr::(); 118 | /// assert_eq!( forest.iter().next(), None ); 119 | /// 120 | /// let forest = -tr(1)-tr(2); 121 | /// let mut iter = forest.iter(); 122 | /// assert_eq!( iter.next(), Some( tr(1).root() )); 123 | /// assert_eq!( iter.next(), Some( tr(2).root() )); 124 | /// assert_eq!( iter.next(), None ); 125 | /// ``` 126 | pub fn iter<'a, 's:'a>( &'s self ) -> Iter<'a,T> { self.root_().iter() } 127 | 128 | /// Provides a forward iterator over child `Node`s with mutable references. 129 | /// 130 | /// # Examples 131 | /// 132 | /// ``` 133 | /// use trees::Forest; 134 | /// 135 | /// let mut forest = Forest::::new(); 136 | /// assert_eq!( forest.iter_mut().next(), None ); 137 | /// 138 | /// let mut forest = Forest::::from_tuple(( 1, 2 )); 139 | /// forest.iter_mut().for_each( |mut child| { *child.data_mut() *= 10; }); 140 | /// assert_eq!( forest.to_string(), "( 10 20 )" ); 141 | /// ``` 142 | pub fn iter_mut<'a, 's:'a>( &'s mut self ) -> IterMut<'a,T> { self.root_mut_().iter_mut() } 143 | 144 | /// Returns the first child of the forest, 145 | /// or `None` if it is empty. 146 | pub fn front( &self ) -> Option<&Node> { 147 | self.root_().front() 148 | } 149 | 150 | /// Returns a mutable pointer to the first child of the forest, 151 | /// or `None` if it is empty. 152 | pub fn front_mut( &mut self ) -> Option>> { 153 | self.root_mut_().front_mut() 154 | } 155 | 156 | pub fn back( &self ) -> Option<&Node> { 157 | self.root_().back() 158 | } 159 | 160 | /// Returns a mutable pointer to the last child of the forest, 161 | /// or `None` if it is empty. 162 | pub fn back_mut( &mut self ) -> Option>> { 163 | self.root_mut_().back_mut() 164 | } 165 | 166 | /// Add the tree as the first child. 167 | /// 168 | /// # Examples 169 | /// 170 | /// ``` 171 | /// use trees::{Tree, Forest}; 172 | /// let mut forest = Forest::new(); 173 | /// forest.push_front( Tree::new(1) ); 174 | /// assert_eq!( forest.to_string(), "( 1 )" ); 175 | /// forest.push_front( Tree::new(2) ); 176 | /// assert_eq!( forest.to_string(), "( 2 1 )" ); 177 | /// ``` 178 | pub fn push_front( &mut self, tree: Tree ) { 179 | self.root_mut_().push_front( tree ); 180 | } 181 | 182 | /// Add the tree as the last child. 183 | /// 184 | /// # Examples 185 | /// 186 | /// ``` 187 | /// use trees::{Tree, Forest}; 188 | /// let mut forest = Forest::new(); 189 | /// forest.push_back( Tree::new(1) ); 190 | /// assert_eq!( forest.to_string(), "( 1 )" ); 191 | /// forest.push_back( Tree::new(2) ); 192 | /// assert_eq!( forest.to_string(), "( 1 2 )" ); 193 | /// ``` 194 | pub fn push_back( &mut self, tree: Tree ) { 195 | self.root_mut_().push_back( tree ); 196 | } 197 | 198 | /// Remove and return the first child. 199 | /// 200 | /// # Examples 201 | /// 202 | /// ``` 203 | /// use trees::{Tree, Forest}; 204 | /// let mut forest = Forest::new(); 205 | /// forest.push_back( Tree::new(1) ); 206 | /// forest.push_back( Tree::new(2) ); 207 | /// assert_eq!( forest.to_string(), "( 1 2 )" ); 208 | /// assert_eq!( forest.pop_front(), Some( Tree::new(1) )); 209 | /// assert_eq!( forest.to_string(), "( 2 )" ); 210 | /// assert_eq!( forest.pop_front(), Some( Tree::new(2) )); 211 | /// assert_eq!( forest.to_string(), "()" ); 212 | /// ``` 213 | pub fn pop_front( &mut self ) -> Option> { 214 | self.root_mut_().pop_front() 215 | } 216 | 217 | /// Remove and return the first child. 218 | /// 219 | /// # Examples 220 | /// 221 | /// ``` 222 | /// use trees::{Tree, Forest}; 223 | /// let mut forest = Forest::new(); 224 | /// forest.push_back( Tree::new(1) ); 225 | /// forest.push_back( Tree::new(2) ); 226 | /// assert_eq!( forest.to_string(), "( 1 2 )" ); 227 | /// assert_eq!( forest.pop_back(), Some( Tree::new(2) )); 228 | /// assert_eq!( forest.to_string(), "( 1 )" ); 229 | /// assert_eq!( forest.pop_back(), Some( Tree::new(1) )); 230 | /// assert_eq!( forest.to_string(), "()" ); 231 | /// ``` 232 | pub fn pop_back( &mut self ) -> Option> { 233 | self.root_mut_().pop_back() 234 | } 235 | 236 | /// Add all the forest's trees at front of children list 237 | /// 238 | /// # Examples 239 | /// 240 | /// ``` 241 | /// use trees::{Tree, Forest}; 242 | /// let mut forest = Forest::new(); 243 | /// forest.push_back( Tree::new(1) ); 244 | /// forest.push_back( Tree::new(2) ); 245 | /// let mut forest2 = Forest::new(); 246 | /// forest2.push_back( Tree::new(3) ); 247 | /// forest2.push_back( Tree::new(4) ); 248 | /// forest.prepend( forest2 ); 249 | /// assert_eq!( forest.to_string(), "( 3 4 1 2 )" ); 250 | /// ``` 251 | pub fn prepend( &mut self, forest: Forest ) { 252 | self.root_mut_().prepend( forest ); 253 | } 254 | 255 | /// Add all the forest's trees at back of children list 256 | /// 257 | /// # Examples 258 | /// 259 | /// ``` 260 | /// use trees::{Tree, Forest}; 261 | /// let mut forest = Forest::new(); 262 | /// forest.push_back( Tree::new(1) ); 263 | /// forest.push_back( Tree::new(2) ); 264 | /// let mut forest2 = Forest::new(); 265 | /// forest2.push_back( Tree::new(3) ); 266 | /// forest2.push_back( Tree::new(4) ); 267 | /// forest.append( forest2 ); 268 | /// assert_eq!( forest.to_string(), "( 1 2 3 4 )" ); 269 | /// ``` 270 | pub fn append( &mut self, forest: Forest ) { 271 | self.root_mut_().append( forest ); 272 | } 273 | } 274 | 275 | impl Default for Forest { fn default() -> Self { Forest::new() }} 276 | 277 | impl Drop for Forest { 278 | fn drop( &mut self ) { 279 | while let Some(_) = self.pop_front() {} 280 | heap::drop_node( self.root ); 281 | } 282 | } 283 | 284 | impl Clone for Forest { 285 | fn clone( &self ) -> Self { 286 | self.root_().deep_clone_forest() 287 | } 288 | } 289 | 290 | impl_debug_display_for_forest!( Forest, iter() ); 291 | impl_order_relations_for_collection!( Forest, iter() ); 292 | impl_hash_for_forest!( Forest, iter() ); 293 | 294 | #[cfg( test )] 295 | mod tests { 296 | use super::*; 297 | 298 | #[test] fn empty_piled_forest_from_tuple() { 299 | let tuple = (); 300 | let piled = Forest::::from_tuple( tuple ); 301 | assert_eq!( piled.to_string(), "()" ); 302 | } 303 | 304 | #[test] fn piled_forest_from_tuple() { 305 | let tuple = ( (2,3,4), (5,6,7) ); 306 | let piled = Forest::::from_tuple( tuple ); 307 | assert_eq!( piled.to_string(), "( 2( 3 4 ) 5( 6 7 ) )" ); 308 | } 309 | } 310 | 311 | #[cfg( miri )] 312 | mod miri_tests { 313 | #[test] fn has_no_child() { 314 | use crate::{fr, tr}; 315 | 316 | let mut forest = fr(); 317 | assert!( forest.has_no_child() ); 318 | forest.push_back( tr(1) ); 319 | assert!( !forest.has_no_child() ); 320 | } 321 | 322 | #[test] fn degree() { 323 | use crate::Forest; 324 | 325 | let forest = Forest::::from_tuple(( 0, (1,2), (3,4) )); 326 | assert_eq!( forest.degree(), 3 ); 327 | } 328 | 329 | #[test] fn node_count() { 330 | use crate::Forest; 331 | 332 | let forest = Forest::::from_tuple(( 0, (1,2), (3,4) )); 333 | assert_eq!( forest.node_count(), 5 ); 334 | } 335 | 336 | #[test] fn iter() { 337 | use crate::{fr, tr}; 338 | 339 | let forest = fr::(); 340 | assert_eq!( forest.iter().next(), None ); 341 | 342 | let forest = -tr(1)-tr(2); 343 | let mut iter = forest.iter(); 344 | assert_eq!( iter.next(), Some( tr(1).root() )); 345 | assert_eq!( iter.next(), Some( tr(2).root() )); 346 | assert_eq!( iter.next(), None ); 347 | } 348 | 349 | #[test] fn iter_mut() { 350 | use crate::Forest; 351 | 352 | let mut forest = Forest::::new(); 353 | assert_eq!( forest.iter_mut().next(), None ); 354 | 355 | let mut forest = Forest::::from_tuple(( 1, 2 )); 356 | forest.iter_mut().for_each( |mut child| { *child.data_mut() *= 10; }); 357 | assert_eq!( forest.to_string(), "( 10 20 )" ); 358 | } 359 | 360 | #[test] fn push_front() { 361 | use crate::{Forest, Tree}; 362 | 363 | let mut forest = Forest::new(); 364 | forest.push_front( Tree::new(1) ); 365 | assert_eq!( forest.to_string(), "( 1 )" ); 366 | forest.push_front( Tree::new(2) ); 367 | assert_eq!( forest.to_string(), "( 2 1 )" ); 368 | } 369 | 370 | #[test] fn push_back() { 371 | use crate::{Forest, Tree}; 372 | 373 | let mut forest = Forest::new(); 374 | forest.push_back( Tree::new(1) ); 375 | assert_eq!( forest.to_string(), "( 1 )" ); 376 | forest.push_back( Tree::new(2) ); 377 | assert_eq!( forest.to_string(), "( 1 2 )" ); 378 | } 379 | 380 | #[test] fn pop_front() { 381 | use crate::{Forest, Tree}; 382 | 383 | let mut forest = Forest::new(); 384 | forest.push_back( Tree::new(1) ); 385 | forest.push_back( Tree::new(2) ); 386 | assert_eq!( forest.to_string(), "( 1 2 )" ); 387 | assert_eq!( forest.pop_front(), Some( Tree::new(1) )); 388 | assert_eq!( forest.to_string(), "( 2 )" ); 389 | assert_eq!( forest.pop_front(), Some( Tree::new(2) )); 390 | assert_eq!( forest.to_string(), "()" ); 391 | } 392 | 393 | #[test] fn pop_back() { 394 | use crate::{Forest, Tree}; 395 | 396 | let mut forest = Forest::new(); 397 | forest.push_back( Tree::new(1) ); 398 | forest.push_back( Tree::new(2) ); 399 | assert_eq!( forest.to_string(), "( 1 2 )" ); 400 | assert_eq!( forest.pop_back(), Some( Tree::new(2) )); 401 | assert_eq!( forest.to_string(), "( 1 )" ); 402 | assert_eq!( forest.pop_back(), Some( Tree::new(1) )); 403 | assert_eq!( forest.to_string(), "()" ); 404 | } 405 | 406 | #[test] fn prepend() { 407 | use crate::{Forest, Tree}; 408 | 409 | let mut forest = Forest::new(); 410 | forest.push_back( Tree::new(1) ); 411 | forest.push_back( Tree::new(2) ); 412 | let mut forest2 = Forest::new(); 413 | forest2.push_back( Tree::new(3) ); 414 | forest2.push_back( Tree::new(4) ); 415 | forest.prepend( forest2 ); 416 | assert_eq!( forest.to_string(), "( 3 4 1 2 )" ); 417 | } 418 | 419 | #[test] fn append() { 420 | use crate::{Forest, Tree}; 421 | 422 | let mut forest = Forest::new(); 423 | forest.push_back( Tree::new(1) ); 424 | forest.push_back( Tree::new(2) ); 425 | let mut forest2 = Forest::new(); 426 | forest2.push_back( Tree::new(3) ); 427 | forest2.push_back( Tree::new(4) ); 428 | forest.append( forest2 ); 429 | assert_eq!( forest.to_string(), "( 1 2 3 4 )" ); 430 | } 431 | 432 | #[test] fn from_tuple() { 433 | use crate::{Forest, tr}; 434 | 435 | let forest = Forest::::from_tuple(( 0, (1,2), (3,4) )); 436 | assert_eq!( forest, -tr(0) -tr(1)/tr(2) -tr(3)/tr(4) ); 437 | assert_eq!( forest.to_string(), "( 0 1( 2 ) 3( 4 ) )" ); 438 | } 439 | } 440 | -------------------------------------------------------------------------------- /deps/trees/src/heap.rs: -------------------------------------------------------------------------------- 1 | #![doc( hidden )] 2 | 3 | use super::{Data, Node, NodeVec, Size}; 4 | 5 | use crate::rust::*; 6 | 7 | pub(crate) fn make_node( data: Data ) -> NonNull> { 8 | let rc = Rc::new( RefCell::new( Node{ 9 | prev : None, 10 | next : None, 11 | head : None, 12 | tail : None, 13 | up : None, 14 | size : Size::default(), 15 | data , 16 | })); 17 | let rc_raw = Rc::into_raw( rc ); 18 | let rc_raw_non_null = unsafe{ NonNull::new_unchecked( rc_raw as *mut _ )}; 19 | let mut rc = unsafe{ Rc::from_raw( rc_raw )}; 20 | let node = Rc::get_mut( &mut rc ).unwrap().get_mut(); 21 | match &mut node.data { 22 | Data::ScatteredNone{ owner } | 23 | Data::Scattered { owner, .. } => *owner = rc_raw_non_null, 24 | _ => (), 25 | } 26 | let node_raw_non_null = unsafe{ NonNull::new_unchecked( node )}; 27 | 28 | mem::forget( rc ); 29 | node_raw_non_null 30 | } 31 | 32 | pub(crate) fn drop_node( mut node: NonNull> ) { 33 | unsafe { 34 | match node.as_mut().data.replace( Data::None ) { 35 | Data::None => (), 36 | Data::ScatteredNone{ owner } | 37 | Data::Scattered { owner, .. } => { 38 | drop( Rc::from_raw( owner.as_ptr() )); 39 | }, 40 | Data::PiledNone { owner } | 41 | Data::Piled { owner, .. } => { 42 | NodeVec::decr_ref( owner ); 43 | }, 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /deps/trees/src/into_iter.rs: -------------------------------------------------------------------------------- 1 | //! Forest's owning iterator. 2 | 3 | use crate::rust::*; 4 | 5 | use super::{Forest, Iter, IterMut, Node, Tree}; 6 | 7 | /// Forest's owning iterator. 8 | pub struct IntoIter { 9 | pub(crate) forest : Forest, 10 | pub(crate) marker : PhantomData>, 11 | } 12 | 13 | impl Iterator for IntoIter { 14 | type Item = Tree; 15 | 16 | fn next( &mut self ) -> Option> { 17 | self.forest.pop_front() 18 | } 19 | 20 | fn size_hint( &self ) -> (usize, Option) { 21 | let degree = self.forest.degree(); 22 | (degree, Some( degree )) 23 | } 24 | } 25 | 26 | impl ExactSizeIterator for IntoIter {} 27 | 28 | impl Drop for IntoIter { 29 | fn drop( &mut self ) { 30 | for _ in self.by_ref() {} 31 | } 32 | } 33 | 34 | impl IntoIterator for Tree { 35 | type Item = Tree; 36 | type IntoIter = IntoIter; 37 | 38 | fn into_iter( self ) -> IntoIter { 39 | let mut forest = Forest::::new(); 40 | forest.push_back( self ); 41 | IntoIter{ forest, marker: PhantomData } 42 | } 43 | } 44 | 45 | impl IntoIterator for Forest { 46 | type Item = Tree; 47 | type IntoIter = IntoIter; 48 | 49 | fn into_iter( self ) -> IntoIter { IntoIter{ forest: self, marker: PhantomData }} 50 | } 51 | 52 | impl<'a, T:'a> IntoIterator for &'a Node { 53 | type Item = Self; 54 | type IntoIter = Iter<'a,T>; 55 | 56 | fn into_iter( self ) -> Self::IntoIter { 57 | Iter::once( Some( self.non_null() )) 58 | } 59 | } 60 | 61 | impl<'a, T:'a> IntoIterator for Pin<&'a mut Node> { 62 | type Item = Self; 63 | type IntoIter = IterMut<'a,T>; 64 | 65 | fn into_iter( self ) -> Self::IntoIter { 66 | IterMut::once( Some( self.non_null() )) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /deps/trees/src/iter.rs: -------------------------------------------------------------------------------- 1 | //! Iterators of `Tree`/`Forest`, returned by `iter()` or `iter_mut()`. 2 | 3 | use crate::rust::*; 4 | 5 | use super::Node; 6 | 7 | #[derive( Debug )] 8 | pub(crate) struct UncountedRawIter { 9 | curr : Option>>, 10 | } 11 | 12 | impl UncountedRawIter { 13 | pub(crate) fn new( curr: Option>> ) -> UncountedRawIter { 14 | UncountedRawIter{ curr } 15 | } 16 | } 17 | 18 | impl Copy for UncountedRawIter {} 19 | 20 | impl Clone for UncountedRawIter { 21 | fn clone( &self ) -> Self { 22 | UncountedRawIter{ curr: self.curr.clone() } 23 | } 24 | } 25 | 26 | impl Iterator for UncountedRawIter { 27 | type Item = NonNull>; 28 | 29 | fn next( &mut self ) -> Option { 30 | self.curr.map( |curr| unsafe { 31 | let item = curr; 32 | self.curr = curr.as_ref().next; 33 | item 34 | }) 35 | } 36 | } 37 | 38 | #[derive( Debug )] 39 | pub(crate) struct CountedRawIter { 40 | iter : UncountedRawIter, 41 | len : usize, 42 | } 43 | 44 | impl CountedRawIter { 45 | pub(crate) fn new( curr: Option>>, len: usize ) -> CountedRawIter { 46 | CountedRawIter { 47 | iter : UncountedRawIter::new( curr ), 48 | len , 49 | } 50 | } 51 | 52 | pub(crate) fn once( curr: Option>> ) -> CountedRawIter { 53 | CountedRawIter::::new( curr, 1 ) 54 | } 55 | } 56 | 57 | impl Copy for CountedRawIter {} 58 | 59 | impl Clone for CountedRawIter { 60 | fn clone( &self ) -> Self { 61 | CountedRawIter{ iter: self.iter.clone(), len: self.len } 62 | } 63 | } 64 | 65 | impl Iterator for CountedRawIter { 66 | type Item = NonNull>; 67 | 68 | fn next( &mut self ) -> Option { 69 | if self.len == 0 { 70 | return None; 71 | } else { 72 | self.len -= 1; 73 | return self.iter.next(); 74 | } 75 | } 76 | 77 | fn size_hint( &self ) -> ( usize, Option ) { 78 | (self.len, Some( self.len )) 79 | } 80 | } 81 | 82 | /// An iterator over the child `Node`s of `Tree`, `Node` or `Forest`. 83 | /// 84 | /// This `struct` is created by [`Node::iter`] and [`Forest::iter`]. 85 | /// See its document for more. 86 | /// 87 | /// [`Node::iter`]: ../node/struct.Node.html#method.iter 88 | /// [`Forest::iter`]: ../forest/struct.Forest.html#method.iter 89 | #[derive( Debug )] 90 | pub struct Iter<'a, T> { 91 | iter : CountedRawIter, 92 | mark : PhantomData<&'a Node>, 93 | } 94 | 95 | impl<'a,T:'a> Iter<'a,T> { 96 | pub(crate) fn new( curr: Option>>, len: usize ) -> Iter<'a,T> { 97 | Iter{ iter: CountedRawIter::::new( curr, len ), mark: PhantomData } 98 | } 99 | 100 | pub(crate) fn once( curr: Option>> ) -> Iter<'a,T> { 101 | Iter{ iter: CountedRawIter::::once( curr ), mark: PhantomData } 102 | } 103 | } 104 | 105 | impl<'a,T:'a> Iterator for Iter<'a,T> { 106 | type Item = &'a Node; 107 | 108 | fn next( &mut self ) -> Option { 109 | self.iter.next().map( |node| unsafe{ &*node.as_ptr() }) 110 | } 111 | 112 | fn size_hint( &self ) -> ( usize, Option ) { self.iter.size_hint() } 113 | } 114 | 115 | impl<'a,T> ExactSizeIterator for Iter<'a, T> {} 116 | impl<'a,T> FusedIterator for Iter<'a, T> {} 117 | 118 | /// A mutable iterator over the child `Node`s of `Tree`, `Node` or `Forest`. 119 | /// 120 | /// This `struct` is created by [`Node::iter_mut`] and [`Forest::iter_mut`]. 121 | /// See its document for more. 122 | /// 123 | /// [`Node::iter_mut`]: ../node/struct.Node.html#method.iter_mut 124 | /// [`Forest::iter_mut`]: ../forest/struct.Forest.html#method.iter_mut 125 | #[derive( Debug )] 126 | pub struct IterMut<'a, T> { 127 | iter : CountedRawIter, 128 | mark : PhantomData<&'a mut Node>, 129 | } 130 | 131 | impl<'a,T:'a> IterMut<'a,T> { 132 | pub(crate) fn new( curr: Option>>, len: usize ) -> IterMut<'a,T> { 133 | IterMut{ iter: CountedRawIter::::new( curr, len ), mark: PhantomData } 134 | } 135 | 136 | pub(crate) fn once( curr: Option>> ) -> IterMut<'a,T> { 137 | IterMut{ iter: CountedRawIter::::once( curr ), mark: PhantomData } 138 | } 139 | } 140 | 141 | impl<'a,T:'a> Iterator for IterMut<'a,T> { 142 | type Item = Pin<&'a mut Node>; 143 | 144 | fn next( &mut self ) -> Option { 145 | self.iter.next().map( |node| unsafe{ Pin::new_unchecked( &mut *node.as_ptr() )}) 146 | } 147 | 148 | fn size_hint( &self ) -> ( usize, Option ) { self.iter.size_hint() } 149 | } 150 | 151 | impl<'a,T> ExactSizeIterator for IterMut<'a, T> {} 152 | impl<'a,T> FusedIterator for IterMut<'a, T> {} 153 | -------------------------------------------------------------------------------- /deps/trees/src/iter_rc.rs: -------------------------------------------------------------------------------- 1 | //! Iterators of `RcNode`, returned by `iter_rc()`. 2 | 3 | use crate::rust::*; 4 | 5 | use super::{CountedRawIter, Node, RcNode}; 6 | 7 | /// An iterator over the child `Node`s of `RcNode` with shared ownership. 8 | /// 9 | /// This `struct` is created by [`RcNode::iter_rc`]. 10 | /// See its document for more. 11 | /// 12 | /// [`RcNode::iter_rc`]: ../rc/enum.RcNode.html#method.iter_rc 13 | pub struct IterRc { 14 | iter : CountedRawIter, 15 | mark : PhantomData>, 16 | } 17 | 18 | impl Iterator for IterRc { 19 | type Item = RcNode; 20 | 21 | fn next( &mut self ) -> Option> { 22 | self.iter.next().map( |node| unsafe{ node.as_ref().rc() }) 23 | } 24 | 25 | fn size_hint( &self ) -> ( usize, Option ) { self.iter.size_hint() } 26 | } 27 | 28 | impl IterRc { 29 | pub(crate) fn new( curr: Option>>, len: usize ) -> Self { 30 | IterRc { 31 | iter: CountedRawIter::new( curr, len ), 32 | mark: PhantomData, 33 | } 34 | } 35 | } 36 | 37 | impl Clone for IterRc { 38 | fn clone( &self ) -> Self { 39 | IterRc { ..*self } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /deps/trees/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2018 oooutlk@outlook.com. See the COPYRIGHT 2 | // file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 or the MIT license 6 | // , at your 7 | // option. This file may not be copied, modified, or distributed 8 | // except according to those terms. 9 | 10 | //! General purpose tree library. 11 | //! See the [trees book](https://oooutlk.github.io/trees/) for more. 12 | //! 13 | //! # Examples 14 | //! 15 | //! The code below construct the following tree in different ways: 16 | //! 17 | //! ```text 18 | //! ............. 19 | //! . 0 . 20 | //! . / \ . 21 | //! . 1 4 . 22 | //! . / \ / \ . 23 | //! .2 3 5 6. 24 | //! ............. 25 | //! ``` 26 | //! 27 | //! ## Example of `tr` notations for building trees 28 | //! 29 | //! ```rust 30 | //! use trees::tr; 31 | //! 32 | //! let tree = tr(0) /( tr(1)/tr(2)/tr(3) ) /( tr(4)/tr(5)/tr(6) ); 33 | //! ``` 34 | //! 35 | //! ## Example of tuple notations for building trees 36 | //! 37 | //! ```rust 38 | //! let tree = trees::Tree::::from_tuple(( 0, (1,2,3), (4,5,6) )); 39 | //! ``` 40 | //! 41 | //! ## Example of building trees step by step 42 | //! 43 | //! ```rust 44 | //! use trees::Tree; 45 | //! 46 | //! let mut tree = Tree::new(0); 47 | //! 48 | //! let mut root = tree.root_mut(); 49 | //! root.push_back( Tree::new(1) ); 50 | //! root.push_back( Tree::new(4) ); 51 | //! 52 | //! let mut children = root.iter_mut(); 53 | //! 54 | //! let mut node_1 = children.next().unwrap(); 55 | //! node_1.push_back( Tree::new(2) ); 56 | //! node_1.push_back( Tree::new(3) ); 57 | //! 58 | //! let mut node_4 = children.next().unwrap(); 59 | //! node_4.push_back( Tree::new(5) ); 60 | //! node_4.push_back( Tree::new(6) ); 61 | //! ``` 62 | //! 63 | //! # Overview of features 64 | //! 65 | //! 1. Step-by-step [creating, reading, updating, deleting](./crud.md) and iterating 66 | //! nodes with assocated data items. 67 | //! 68 | //! 2. Compact notations to express trees: `-`,`/` encoded or tuple encoded trees. 69 | //! 70 | //! 3. Depth first search cursor. 71 | //! 72 | //! 4. Breadth first search iterators. 73 | //! 74 | //! 5. Trees can be built by stages, with nodes stored scatteredly among memory. 75 | //! 76 | //! 6. Trees can be built once through, with nodes stored contiguously. 77 | //! 78 | //! 7. Support exclusive ownership with static borrow check. 79 | //! 80 | //! 8. Support shared ownership with dynamic borrow check. 81 | 82 | #![cfg_attr( feature = "no_std", no_std )] 83 | 84 | #[doc( hidden )] 85 | pub mod rust { 86 | #[cfg(not(feature="no_std"))] pub use std::borrow::{Borrow, ToOwned}; 87 | #[cfg(not(feature="no_std"))] pub use std::boxed::Box; 88 | #[cfg(not(feature="no_std"))] pub use std::cell::{Cell, Ref, RefMut, RefCell}; 89 | #[cfg(not(feature="no_std"))] pub use std::collections::VecDeque; 90 | #[cfg(not(feature="no_std"))] pub use std::cmp::Ordering::{self, *}; 91 | #[cfg(not(feature="no_std"))] pub use std::fmt::{self, Debug, Display, Formatter}; 92 | #[cfg(not(feature="no_std"))] pub use std::hash::{Hasher, Hash}; 93 | #[cfg(not(feature="no_std"))] pub use std::iter::{Iterator, FromIterator, IntoIterator, FusedIterator}; 94 | #[cfg(not(feature="no_std"))] pub use std::marker::{PhantomData, Unpin}; 95 | #[cfg(not(feature="no_std"))] pub use std::mem::{self, forget, transmute, MaybeUninit}; 96 | #[cfg(not(feature="no_std"))] pub use std::ops::{Add, AddAssign, Deref, DerefMut, Div, Neg, Sub, SubAssign}; 97 | #[cfg(not(feature="no_std"))] pub use std::pin::Pin; 98 | #[cfg(not(feature="no_std"))] pub use std::ptr::{self, NonNull, null, null_mut}; 99 | #[cfg(not(feature="no_std"))] pub use std::rc::{Rc, Weak}; 100 | #[cfg(not(feature="no_std"))] pub use std::vec::Vec; 101 | 102 | #[cfg(feature="no_std")] extern crate core; 103 | #[cfg(feature="no_std")] extern crate alloc; 104 | #[cfg(feature="no_std")] pub use self::alloc::borrow::{Borrow, ToOwned}; 105 | #[cfg(feature="no_std")] pub use self::alloc::boxed::Box; 106 | #[cfg(feature="no_std")] pub use self::alloc::string::String; 107 | #[cfg(feature="no_std")] 108 | #[cfg(test)] pub use self::alloc::string::ToString; 109 | #[cfg(feature="no_std")] pub use self::alloc::collections::VecDeque; 110 | #[cfg(feature="no_std")] 111 | #[cfg(test)] pub use self::alloc::format; 112 | #[cfg(feature="no_std")] pub use self::alloc::rc::{Rc, Weak}; 113 | #[cfg(feature="no_std")] 114 | #[cfg(test)] pub use self::alloc::vec; 115 | #[cfg(feature="no_std")] pub use self::alloc::vec::Vec; 116 | #[cfg(feature="no_std")] pub use core::cell::{Cell, Ref, RefMut, RefCell}; 117 | #[cfg(feature="no_std")] pub use core::cmp::Ordering::{self, *}; 118 | #[cfg(feature="no_std")] pub use core::fmt::{self, Debug, Display, Formatter}; 119 | #[cfg(feature="no_std")] pub use core::hash::{Hasher, Hash}; 120 | #[cfg(feature="no_std")] pub use core::iter::{Iterator, FromIterator, IntoIterator, FusedIterator}; 121 | #[cfg(feature="no_std")] pub use core::marker::{PhantomData, Unpin}; 122 | #[cfg(feature="no_std")] pub use core::mem::{self, forget, transmute, MaybeUninit}; 123 | #[cfg(feature="no_std")] pub use core::ops::{Add, AddAssign, Deref, DerefMut, Div, Neg, Sub, SubAssign}; 124 | #[cfg(feature="no_std")] pub use core::pin::Pin; 125 | #[cfg(feature="no_std")] pub use core::ptr::{self, NonNull, null, null_mut}; 126 | } 127 | 128 | #[macro_use] 129 | mod macros; 130 | 131 | pub mod tuple; 132 | pub use tuple::{TupleForest, TupleTree}; 133 | 134 | pub mod bfs; 135 | 136 | pub mod size; 137 | pub use size::Size; 138 | 139 | pub mod tree; 140 | pub use tree::Tree; 141 | 142 | pub mod forest; 143 | pub use forest::Forest; 144 | 145 | pub mod node; 146 | pub use node::Node; 147 | pub(crate) use node::Data; 148 | 149 | pub(crate) mod node_vec; 150 | pub(crate) use node_vec::NodeVec; 151 | 152 | pub mod iter; 153 | pub use iter::{Iter, IterMut}; 154 | pub(crate) use iter::CountedRawIter; 155 | 156 | pub mod into_iter; 157 | pub use into_iter::IntoIter; 158 | 159 | pub mod heap; 160 | 161 | pub mod walk; 162 | pub use walk::{TreeWalk, ForestWalk}; 163 | 164 | pub mod notation; 165 | pub use notation::{tr, fr}; 166 | 167 | pub mod iter_rc; 168 | pub use iter_rc::IterRc; 169 | 170 | pub mod rc; 171 | pub use rc::{RcNode, WeakNode}; 172 | 173 | pub(crate) mod bfs_impls; 174 | 175 | 176 | #[derive(Debug)] 177 | pub struct Error { 178 | pub msg: String, 179 | } 180 | 181 | impl From for Error { 182 | fn from(e: String) -> Self { 183 | Error { msg: e } 184 | } 185 | } 186 | 187 | impl From<&str> for Error { 188 | fn from(e: &str) -> Self { 189 | Error { msg: e.to_string() } 190 | } 191 | } 192 | 193 | use std::fmt; 194 | impl fmt::Display for Error { 195 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 196 | write!(f, "{}", self.msg) 197 | } 198 | } 199 | 200 | use std::error; 201 | impl error::Error for Error { 202 | fn description(&self) -> &str { 203 | &self.msg 204 | } 205 | } 206 | 207 | 208 | 209 | use std::pin::Pin; 210 | impl Node { 211 | pub fn locate_first_by_path<'s, 't>(&'s self, mut path: impl Iterator + Clone ) -> Option<&'s Node> 212 | where T: 't + PartialEq 213 | { 214 | if let Some( data ) = path.next() { 215 | if self.data() == data { 216 | let clone_path = path.clone(); 217 | 218 | if path.next().is_none() { 219 | return Some(self) 220 | } 221 | 222 | for child in self.iter() { 223 | if let Some( node ) = child.locate_first_by_path(clone_path.clone() ) { 224 | return Some( node ); 225 | } 226 | } 227 | } 228 | } 229 | None 230 | } 231 | 232 | pub fn locate_first_by_data<'s, 't>(&'s self, data: &'t T) -> Option<&'s Node> 233 | where T: 't + PartialEq 234 | { 235 | if self.data() == data { 236 | return Some(self) 237 | } 238 | 239 | for child in self.iter() { 240 | if let Some(node) = child.locate_first_by_data(data) { 241 | return Some(node); 242 | } 243 | } 244 | 245 | None 246 | } 247 | 248 | pub fn locate_first_mut_by_data<'s, 't>(&'s mut self, data: &'t T) -> Option>> 249 | where T: 't + PartialEq 250 | { 251 | if self.data() == data { 252 | return Some( unsafe { Pin::new_unchecked(self)}); 253 | } 254 | 255 | for child in self.iter_mut() { 256 | let child = unsafe{ Pin::get_unchecked_mut(child) }; 257 | if let Some(node) = child.locate_first_mut_by_data(data) { 258 | return Some(node); 259 | } 260 | } 261 | None 262 | } 263 | 264 | pub fn locate_first_mut_by_path<'s, 't>(&'s mut self, mut path: impl Iterator + Clone ) -> Option>> 265 | where T: 't + PartialEq 266 | { 267 | if let Some( data ) = path.next() { 268 | 269 | if self.data() == data { 270 | let clone_path = path.clone(); 271 | 272 | if path.next().is_none() { 273 | return Some( unsafe{ Pin::new_unchecked( self )}); 274 | } 275 | 276 | for child in self.iter_mut() { 277 | let child = unsafe{ Pin::get_unchecked_mut( child )}; 278 | if let Some( node ) = child.locate_first_mut_by_path( clone_path.clone() ) { 279 | return Some( node ); 280 | } 281 | } 282 | } 283 | } 284 | None 285 | } 286 | 287 | 288 | pub fn ancestors(&self) -> Vec<&T> { 289 | let mut ancestors = vec![]; 290 | 291 | let mut current_node = self; 292 | while let Some(node) = current_node.parent(){ 293 | ancestors.push(node.data()); 294 | current_node = node; 295 | } 296 | ancestors 297 | } 298 | 299 | 300 | pub fn descendants(&self) -> Vec<&T> { 301 | self.bfs().iter.map(|v| { 302 | v.data 303 | }).collect::>() 304 | } 305 | 306 | 307 | pub fn children(&self) -> Vec<&T> { 308 | self.iter().map(|v| v.data()).collect::>() 309 | } 310 | 311 | pub fn father(&self) -> Option<&T> { 312 | self.parent().map(|v| v.data()) 313 | } 314 | 315 | } 316 | 317 | 318 | 319 | use std::convert::{TryFrom}; 320 | use crate::rust::Formatter; 321 | 322 | 323 | impl TryFrom<&str> for Tree { 324 | type Error = Error; 325 | fn try_from(item: &str) -> Result { 326 | Tree::::try_from(item.to_string()) 327 | } 328 | } 329 | 330 | impl TryFrom for Tree { 331 | type Error = Error; 332 | 333 | fn try_from(item: String) -> Result { 334 | let tree_string = item.trim(); 335 | 336 | if tree_string.starts_with("(") { 337 | return Err("no root in tree string".into()) 338 | } 339 | 340 | 341 | let mut tokens = Vec::new(); 342 | let mut legal = 0; 343 | 344 | let mut t = String::from(""); 345 | tree_string.chars().for_each(|v| { 346 | match v { 347 | '(' | ')' | ' ' => { 348 | if !t.is_empty() { 349 | tokens.push(t.clone()); 350 | t = "".to_string(); 351 | } 352 | if v !=' ' { 353 | tokens.push(v.to_string()); 354 | } 355 | legal = if v == '(' { 356 | legal + 1 357 | } else if v == ')' { 358 | legal - 1 359 | } else { 360 | legal 361 | } 362 | }, 363 | _ => t.push(v) 364 | } 365 | }); 366 | 367 | if !t.is_empty() { tokens.push(t) } 368 | 369 | // the number of '(' is not equal to the number of ')' 370 | if legal !=0 || tokens.len() == 0 { 371 | return Err("() is not closed".into()) 372 | } 373 | 374 | let mut tree = Tree::new(String::from(&tokens[0])); 375 | let mut forests: Vec> = Vec::new(); 376 | tokens.iter().skip(1).for_each(|v| { 377 | match v.as_str() { 378 | "(" => forests.push(Forest::new()), 379 | ")" => { 380 | let last_forest = forests.pop().unwrap(); 381 | if let Some(father_forest) = forests.last_mut() { 382 | last_forest.into_iter().for_each(|v| { 383 | father_forest.back_mut().unwrap().push_back(v) 384 | }) 385 | } else { 386 | // stack emtpy, append forest to root 387 | tree.root_mut().prepend(last_forest) 388 | } 389 | }, 390 | _ => forests.last_mut().unwrap().push_back(Tree::new(String::from(v))) 391 | } 392 | }); 393 | Ok(tree) 394 | } 395 | } 396 | 397 | 398 | #[cfg(test)] 399 | mod extend_tests { 400 | use super::*; 401 | 402 | 403 | #[test] fn test_try_from_string() { 404 | let tree_string = " 0( 1( 2 3bc) 4( 5 6 ) ) "; 405 | let wrong_string = " ((0)"; 406 | 407 | assert!(Tree::try_from(wrong_string).is_err()); 408 | assert!(Tree::try_from("a").is_ok()); 409 | assert!(Tree::try_from(String::from(tree_string)).is_ok()); 410 | 411 | assert_eq!(Tree::try_from("a").unwrap(), Tree::new("a".to_string())); 412 | 413 | 414 | let wrong_string = " (0)"; 415 | assert!(Tree::try_from(wrong_string).is_err()); 416 | } 417 | 418 | 419 | #[test] fn test_node_locate_by_path() { 420 | let mut tree = tr(0) /(tr(1)/tr(2)) /(tr(3)/tr(4)); 421 | let path = vec![ 0,3 ]; 422 | assert_eq!(tree.root().locate_first_by_path( path.iter() ).unwrap().data(), &3 ); 423 | 424 | 425 | let mut root = tree.root_mut(); 426 | let path = vec![ 0,3 ]; 427 | let mut node3 = root.locate_first_mut_by_path(path.iter()).unwrap(); 428 | node3.push_back(tr(4)); 429 | 430 | println!("{:?}", tree.to_string()) 431 | } 432 | 433 | #[test] fn test_node_locate_by_data() { 434 | let mut t = Tree::try_from(" 0( 1( 2 3bc) 4( 5 6 ) ) ".to_owned()).unwrap(); 435 | assert!(t.root().locate_first_by_data(&"3bc".to_string()).is_some()); 436 | 437 | 438 | let node = t.root().locate_first_by_data(&"2bc".to_string()); 439 | assert!(node.is_none()); 440 | 441 | 442 | let mut root = t.root_mut(); 443 | let mut node = root.locate_first_mut_by_data(&"3bc".to_string()); 444 | assert!(node.is_some()); 445 | 446 | } 447 | 448 | #[test] fn test_ancestors() { 449 | let mut t = Tree::try_from(" 0( 1( 2 3bc) 4( 5 6 ) ) ".to_owned()).unwrap(); 450 | println!("{:?}", t.root().locate_first_by_data(&"3bc".to_string()).unwrap().ancestors()); 451 | println!("{:?}", t.to_string()); 452 | } 453 | 454 | #[test] fn test_descendants() { 455 | let mut t = Tree::try_from(" 0( 1( 2 3bc) 4( 5 6 ) ) ".to_owned()).unwrap(); 456 | println!("{:?}", t.root().locate_first_by_data(&"1".to_string()).unwrap().descendants()); 457 | println!("{:?}", t.to_string()); 458 | } 459 | 460 | 461 | } -------------------------------------------------------------------------------- /deps/trees/src/macros.rs: -------------------------------------------------------------------------------- 1 | macro_rules! impl_debug_display_for_collection { 2 | ( $ty:ident, $($agent:tt)+ ) => { 3 | use crate::rust::{Debug, Display}; 4 | 5 | impl Debug for $ty { 6 | fn fmt( &self, f: &mut Formatter ) -> fmt::Result { self.$($agent)+.fmt(f) } 7 | } 8 | 9 | impl Display for $ty { 10 | fn fmt( &self, f: &mut Formatter ) -> fmt::Result { write!( f, "{}", self.$($agent)+ )} 11 | } 12 | }; 13 | } 14 | 15 | macro_rules! impl_debug_display_for_forest { 16 | ( $ty:ident, $($agent:tt)+ ) => { 17 | use crate::rust::{Debug, Display}; 18 | 19 | impl Debug for $ty { 20 | fn fmt( &self, f: &mut Formatter ) -> fmt::Result { 21 | if self.has_no_child() { 22 | write!( f, "()" ) 23 | } else { 24 | write!( f, "( " )?; 25 | for child in self.$($agent)+ { 26 | child.fmt(f)?; 27 | write!( f, " " )?; 28 | } 29 | write!( f, ")" ) 30 | } 31 | } 32 | } 33 | 34 | impl Display for $ty { 35 | fn fmt( &self, f: &mut Formatter ) -> fmt::Result { 36 | if self.has_no_child() { 37 | write!( f, "()" ) 38 | } else { 39 | write!( f, "( " )?; 40 | for child in self.$($agent)+ { 41 | write!( f, "{} ", child )?; 42 | } 43 | write!( f, ")" ) 44 | } 45 | } 46 | } 47 | }; 48 | } 49 | 50 | macro_rules! impl_order_relations_for_collection { 51 | ( $ty:ident, $($agent:tt)+ ) => { 52 | impl PartialEq for $ty { 53 | fn eq( &self, other: &Self ) -> bool { self.$($agent)+.eq( other.$($agent)+ )} 54 | fn ne( &self, other: &Self ) -> bool { self.$($agent)+.ne( other.$($agent)+ )} 55 | } 56 | 57 | impl Eq for $ty {} 58 | 59 | impl PartialOrd for $ty { 60 | fn partial_cmp( &self, other: &Self ) -> Option { self.$($agent)+.partial_cmp( other.$($agent)+ )} 61 | } 62 | 63 | impl Ord for $ty { 64 | fn cmp( &self, other: &Self ) -> Ordering { self.$($agent)+.cmp( other.$($agent)+ )} 65 | } 66 | }; 67 | } 68 | 69 | macro_rules! impl_hash_for_collection { 70 | ( $ty:ident, $($agent:tt)+ ) => { 71 | use crate::rust::{Hash, Hasher}; 72 | 73 | impl Hash for $ty { 74 | fn hash( &self, state: &mut H ) { self.$($agent)+.hash( state )} 75 | } 76 | }; 77 | } 78 | 79 | macro_rules! impl_hash_for_forest { 80 | ( $ty:ident, $($agent:tt)+ ) => { 81 | use crate::rust::{Hash, Hasher}; 82 | 83 | impl Hash for $ty { 84 | fn hash( &self, state: &mut H ) { 85 | for child in self.$($agent)+ { 86 | child.hash( state ) 87 | } 88 | } 89 | } 90 | }; 91 | } 92 | 93 | macro_rules! impl_debug_display_for_node { 94 | ( $ty:ident, $iter:ident, $($data:tt)+ ) => { 95 | use crate::rust::{Debug, Display}; 96 | 97 | impl Debug for $ty { 98 | fn fmt( &self, f: &mut Formatter ) -> fmt::Result { 99 | if self.has_no_child() { 100 | self.$($data)+.fmt(f)?; 101 | write!( f, "@{:?} ", self as *const _ ) 102 | } else { 103 | self.$($data)+.fmt(f)?; 104 | write!( f, "@{:?} ", self as *const _ )?; 105 | write!( f, "( " )?; 106 | for child in self.$iter() { 107 | child.fmt(f)?; 108 | } 109 | write!( f, ")" ) 110 | } 111 | } 112 | } 113 | 114 | impl Display for $ty { 115 | fn fmt( &self, f: &mut Formatter ) -> fmt::Result { 116 | if self.has_no_child() { 117 | write!( f, "{}", self.$($data)+ ) 118 | } else { 119 | write!( f, "{}", self.$($data)+ )?; 120 | write!( f, "( " )?; 121 | for child in self.$iter() { 122 | write!( f, "{} ", child )?; 123 | } 124 | write!( f, ")" ) 125 | } 126 | } 127 | } 128 | }; 129 | } 130 | 131 | macro_rules! impl_order_relations_for_node { 132 | ( $ty:ident, $iter:ident, $($data:tt)+ ) => { 133 | impl PartialEq for $ty { 134 | fn eq( &self, other: &Self ) -> bool { self.$($data)+ == other.$($data)+ && self.$iter().eq( other.$iter() )} 135 | fn ne( &self, other: &Self ) -> bool { self.$($data)+ != other.$($data)+ || self.$iter().ne( other.$iter() )} 136 | } 137 | 138 | impl Eq for $ty {} 139 | 140 | impl PartialOrd for $ty { 141 | fn partial_cmp( &self, other: &Self ) -> Option { 142 | match self.$($data)+.partial_cmp( &other.$($data)+ ) { 143 | None => None, 144 | Some( order ) => match order { 145 | Less => Some( Less ), 146 | Greater => Some( Greater ), 147 | Equal => self.$iter().partial_cmp( other.$iter() ), 148 | }, 149 | } 150 | } 151 | } 152 | 153 | impl Ord for $ty { 154 | fn cmp( &self, other: &Self ) -> Ordering { 155 | match self.$($data)+.cmp( &other.$($data)+ ) { 156 | Less => Less, 157 | Greater => Greater, 158 | Equal => self.$iter().cmp( other.$iter() ), 159 | } 160 | } 161 | } 162 | }; 163 | } 164 | 165 | macro_rules! impl_hash_for_node { 166 | ( $ty:ident, $iter:ident, $($data:tt)+ ) => { 167 | impl Hash for $ty { 168 | fn hash( &self, state: &mut H ) { 169 | self.$($data)+.hash( state ); 170 | for child in self.$iter() { 171 | child.hash( state ); 172 | } 173 | } 174 | } 175 | }; 176 | } 177 | -------------------------------------------------------------------------------- /deps/trees/src/node.rs: -------------------------------------------------------------------------------- 1 | //! Composed of `data` and a list of its child `Node`s. 2 | //! 3 | //! Can be converted to `RcNode`, which has shared ownership. 4 | 5 | use crate::Size; 6 | 7 | use crate::rust::*; 8 | 9 | use super::{Forest, Iter, IterMut, NodeVec, Tree}; 10 | 11 | /// Data associated with `Node`. 12 | #[derive( Debug, PartialEq, Eq, PartialOrd, Ord, Hash )] 13 | pub(crate) enum Data { 14 | None, 15 | ScatteredNone{ owner: NonNull>> }, 16 | Scattered { data: T, owner: NonNull>> }, 17 | PiledNone { owner: NonNull> }, 18 | Piled { data: T, owner: NonNull> }, 19 | } 20 | 21 | impl Default for Data { 22 | fn default() -> Self { Data::None } 23 | } 24 | 25 | impl Data { 26 | pub(crate) fn is_none( &self ) -> bool { 27 | match self { 28 | Data::None => true, 29 | _ => false, 30 | } 31 | } 32 | 33 | pub(crate) fn take( &mut self ) -> T { 34 | match self { 35 | Data::Scattered{ owner, .. } => { 36 | let data = Data::ScatteredNone{ owner: *owner }; 37 | match mem::replace( self, data ) { 38 | Data::Scattered{ data, .. } => data, 39 | _ => unreachable!(), 40 | } 41 | }, 42 | Data::Piled{ owner, .. } => { 43 | let data = Data::PiledNone{ owner: *owner }; 44 | match mem::replace( self, data ) { 45 | Data::Piled{ data, .. } => data, 46 | _ => unreachable!(), 47 | } 48 | }, 49 | _ => unreachable!(), 50 | } 51 | } 52 | 53 | pub(crate) fn replace( &mut self, other: Data ) -> Data { 54 | mem::replace( self, other ) 55 | } 56 | 57 | pub(crate) fn into_inner( self ) -> T { 58 | match self { 59 | Data::Piled{ data, owner } => { 60 | NodeVec::decr_ref( owner ); 61 | data 62 | }, 63 | Data::Scattered{ data, owner } => { 64 | drop( unsafe{ Rc::from_raw( owner.as_ptr() )}); 65 | data 66 | }, 67 | _ => unreachable!(), 68 | } 69 | } 70 | } 71 | 72 | impl AsRef for Data { 73 | fn as_ref( &self ) -> &T { 74 | match self { 75 | Data::Piled { ref data, .. } => data, 76 | Data::Scattered{ ref data, .. } => data, 77 | _ => unreachable!(), 78 | } 79 | } 80 | } 81 | 82 | impl AsMut for Data { 83 | fn as_mut( &mut self ) -> &mut T { 84 | match self { 85 | Data::Piled { ref mut data, .. } => data, 86 | Data::Scattered{ ref mut data, .. } => data, 87 | _ => unreachable!(), 88 | } 89 | } 90 | } 91 | 92 | /// Composed of `data` and a list of its child `Node`s. 93 | /// Size infomation tracked. 94 | pub struct Node { 95 | pub(crate) prev : Option>>, 96 | pub(crate) next : Option>>, 97 | pub(crate) head : Option>>, 98 | pub(crate) tail : Option>>, 99 | pub(crate) up : Option>>, 100 | pub(crate) size : Size, 101 | pub(crate) data : Data, 102 | } 103 | 104 | impl Default for Node { 105 | fn default() -> Self { 106 | Node{ prev: None, next: None, head: None, tail: None, up: None, size: Size::default(), data: Data::default() } 107 | } 108 | } 109 | 110 | impl Node { 111 | /// Reference of its associated data. 112 | pub fn data( &self ) -> &T { self.data.as_ref() } 113 | 114 | /// Mutable reeference of its associated data. 115 | pub fn data_mut( &mut self ) -> &mut T { self.data.as_mut() } 116 | 117 | /// Returns `true` if `Node` has no child nodes. 118 | /// 119 | /// # Examples 120 | /// 121 | /// ``` 122 | /// use trees::Tree; 123 | /// let mut tree = Tree::new(0); 124 | /// let mut root = tree.root_mut(); 125 | /// assert!( root.has_no_child() ); 126 | /// root.push_back( Tree::new(1) ); 127 | /// assert!( !root.has_no_child() ); 128 | /// ``` 129 | pub fn has_no_child( &self ) -> bool { self.head.is_none() } 130 | 131 | /// Returns the number of child nodes in `Node`. 132 | /// 133 | /// # Examples 134 | /// 135 | /// ``` 136 | /// use trees::Tree; 137 | /// let mut tree = Tree::new(0); 138 | /// let mut root = tree.root_mut(); 139 | /// assert_eq!( root.degree(), 0 ); 140 | /// root.push_back( Tree::new(1) ); 141 | /// assert_eq!( root.degree(), 1 ); 142 | /// root.push_back( Tree::new(2) ); 143 | /// assert_eq!( root.degree(), 2 ); 144 | /// ``` 145 | pub fn degree( &self ) -> usize { self.size.degree } 146 | 147 | /// Returns the number of all child nodes in `Node`, including itself. 148 | /// 149 | /// # Examples 150 | /// 151 | /// ``` 152 | /// use trees::Tree; 153 | /// 154 | /// let tree = Tree::::from_tuple(( 0, (1,2), (3,4) )); 155 | /// assert_eq!( tree.root().node_count(), 5 ); 156 | /// ``` 157 | pub fn node_count( &self ) -> usize { 158 | if self.is_forest() { 159 | self.size.descendants 160 | } else { 161 | self.size.descendants + 1 162 | } 163 | } 164 | 165 | /// Returns the parent node of this node, 166 | /// or None if it is the root node. 167 | /// 168 | /// # Examples 169 | /// 170 | /// ``` 171 | /// use trees::Tree; 172 | /// 173 | /// let tree = Tree::::from_tuple(( 0, 1, 2, 3 )); 174 | /// tree.root().iter().for_each( |child| { 175 | /// assert_eq!( child.parent(), Some( tree.root())) 176 | /// }); 177 | /// ``` 178 | pub fn parent( &self ) -> Option<&Node> { 179 | let mut node = self.non_null(); 180 | unsafe { 181 | while let Some( parent ) = node.as_ref().up { 182 | if parent.as_ref().is_forest() { 183 | node = parent; 184 | } else { 185 | return Some( &*parent.as_ptr() ); 186 | } 187 | } 188 | } 189 | None 190 | } 191 | 192 | /// Inserts sib tree before `self`. 193 | /// The newly inserted node will not be iterated over by the currently running iterator. 194 | /// 195 | /// # Examples 196 | /// 197 | /// ``` 198 | /// use trees::tr; 199 | /// 200 | /// let mut tree = tr(0) /tr(1)/tr(2); 201 | /// tree.iter_mut().for_each( |mut sub| sub.insert_prev_sib( tr(3) )); 202 | /// assert_eq!( tree.to_string(), "0( 3 1 3 2 )" ); 203 | /// ``` 204 | pub fn insert_prev_sib( &mut self, mut sib: Tree ) { 205 | let mut up = self.up.unwrap(); 206 | 207 | sib.root_mut_().up = Some( up ); 208 | 209 | unsafe { 210 | if let Some( mut prev ) = self.prev { 211 | prev.as_mut().connect_next( sib.root_mut_() ); 212 | } else { 213 | up.as_mut().head = Some( sib.root ); 214 | } 215 | sib.root_mut_().connect_next( self ); 216 | 217 | up.as_mut().inc_sizes( 1, sib.node_count() ); 218 | } 219 | 220 | mem::forget( sib ); 221 | } 222 | 223 | /// Inserts sib tree after `self`. 224 | /// The newly inserted node will not be iterated over by the currently running iterator. 225 | /// 226 | /// # Examples 227 | /// 228 | /// ``` 229 | /// use trees::tr; 230 | /// let mut tree = tr(0) /tr(1)/tr(2); 231 | /// tree.iter_mut().for_each( |mut sub| sub.insert_next_sib( tr(3) )); 232 | /// assert_eq!( tree.to_string(), "0( 1 3 2 3 )" ); 233 | /// ``` 234 | pub fn insert_next_sib( &mut self, mut sib: Tree ) { 235 | let mut up = self.up.unwrap(); 236 | 237 | sib.root_mut_().up = Some( up ); 238 | 239 | unsafe { 240 | if let Some( mut next ) = self.next { 241 | sib.root_mut_().connect_next( next.as_mut() ); 242 | } else { 243 | up.as_mut().tail = Some( sib.root ); 244 | } 245 | self.connect_next( sib.root_mut_() ); 246 | 247 | up.as_mut().inc_sizes( 1, sib.node_count() ); 248 | } 249 | 250 | mem::forget( sib ); 251 | } 252 | 253 | /// The subtree departs from its parent and becomes an indepent `Tree`. 254 | /// 255 | /// # Examples 256 | /// ``` 257 | /// use trees::{tr, fr}; 258 | /// 259 | /// let mut forest = fr()-tr(1)-tr(2)-tr(3); 260 | /// forest.iter_mut().for_each( |mut sub| { sub.detach(); }); 261 | /// assert_eq!( forest, fr() ); 262 | /// ``` 263 | pub fn detach( &mut self ) -> Tree { 264 | unsafe { 265 | let mut up = self.up.unwrap(); 266 | 267 | match up.as_ref().size.degree { 268 | 1 => { 269 | up.as_mut().head = None; 270 | up.as_mut().tail = None; 271 | } 272 | _ => if self.prev.is_none() { 273 | let mut next = self.next.unwrap(); 274 | next.as_mut().prev = None; 275 | up.as_mut().head = Some( next ); 276 | self.next = None; 277 | } else if self.next.is_none() { 278 | let mut prev = self.prev.unwrap(); 279 | prev.as_mut().next = None; 280 | up.as_mut().tail = Some( prev ); 281 | self.prev = None; 282 | } else { 283 | self.prev.unwrap().as_mut().connect_next( self.next.unwrap().as_mut() ); 284 | self.prev = None; 285 | self.next = None; 286 | }, 287 | } 288 | 289 | up.as_mut().dec_sizes( 1, self.node_count() ); 290 | self.up = None; 291 | } 292 | 293 | Tree{ root: self.non_null(), mark: PhantomData } 294 | } 295 | 296 | /// Provides a forward iterator over child `Node`s 297 | /// 298 | /// # Examples 299 | /// 300 | /// ``` 301 | /// use trees::Tree; 302 | /// 303 | /// let mut tree = Tree::new(0); 304 | /// assert_eq!( tree.iter().next(), None ); 305 | /// 306 | /// tree.push_back( Tree::new(1) ); 307 | /// tree.push_back( Tree::new(2) ); 308 | /// let mut iter = tree.root().iter(); 309 | /// assert_eq!( iter.next(), Some( Tree::new(1).root() )); 310 | /// assert_eq!( iter.next(), Some( Tree::new(2).root() )); 311 | /// assert_eq!( iter.next(), None ); 312 | /// ``` 313 | pub fn iter<'a, 's:'a>( &'s self ) -> Iter<'a,T> { 314 | match self.head { 315 | Some( child ) => Iter::new( Some( child ), self.degree() ), 316 | None => Iter::new( None, 0 ), 317 | } 318 | } 319 | 320 | /// Provides a forward iterator over child `Node`s with mutable references. 321 | /// 322 | /// # Examples 323 | /// 324 | /// ``` 325 | /// use trees::Tree; 326 | /// 327 | /// let mut tree = Tree::::from_tuple(( 0, (1, 2, 3), )); 328 | /// tree.front_mut().unwrap() 329 | /// .iter_mut() 330 | /// .for_each( |mut child| *child.data_mut() *= 10 ); 331 | /// assert_eq!( tree.to_string(), "0( 1( 20 30 ) )" ); 332 | /// ``` 333 | pub fn iter_mut<'a, 's:'a>( &'s mut self ) -> IterMut<'a,T> { 334 | match self.head { 335 | Some( child ) => IterMut::new( Some( child ), self.degree() ), 336 | None => IterMut::new( None, 0 ), 337 | } 338 | } 339 | 340 | /// Returns the first child of this node, 341 | /// or None if it has no child. 342 | pub fn front( &self ) -> Option<&Node> { 343 | self.head.map( |head| unsafe{ &*head.as_ptr() }) 344 | } 345 | 346 | /// Returns a mutable pointer to the first child of this node, 347 | /// or None if it has no child. 348 | pub fn front_mut( &mut self ) -> Option>> { 349 | self.head.map( |head| unsafe{ Pin::new_unchecked( &mut *head.as_ptr() )}) 350 | } 351 | 352 | /// Returns the last child of this node, 353 | /// or None if it has no child. 354 | pub fn back( &self ) -> Option<&Node> { 355 | self.tail.map( |tail| unsafe{ &*tail.as_ptr() }) 356 | } 357 | 358 | /// Returns a mutable pointer to the last child of this node, 359 | /// or None if it has no child. 360 | pub fn back_mut( &mut self ) -> Option>> { 361 | self.tail.map( |tail| unsafe{ Pin::new_unchecked( &mut *tail.as_ptr() )}) 362 | } 363 | 364 | /// Adds the tree as the first child. 365 | /// 366 | /// # Examples 367 | /// 368 | /// ``` 369 | /// use trees::Tree; 370 | /// 371 | /// let mut tree = Tree::new(0); 372 | /// tree.root_mut().push_front( Tree::new(1) ); 373 | /// assert_eq!( tree.to_string(), "0( 1 )" ); 374 | /// tree.root_mut().push_front( Tree::new(2) ); 375 | /// assert_eq!( tree.to_string(), "0( 2 1 )" ); 376 | /// ``` 377 | pub fn push_front( &mut self, mut tree: Tree ) { 378 | tree.root_mut_().set_up( self ); 379 | if self.has_no_child() { 380 | self.set_tail( tree.root() ); 381 | } else { 382 | unsafe{ tree.root_mut_().connect_next( self.head.unwrap().as_mut() ); } 383 | } 384 | self.set_head( tree.root() ); 385 | self.inc_sizes( 1, tree.root().node_count() ); 386 | mem::forget( tree ); 387 | } 388 | 389 | /// Adds the tree as the last child. 390 | /// 391 | /// # Examples 392 | /// 393 | /// ``` 394 | /// use trees::Tree; 395 | /// 396 | /// let mut tree = Tree::new(0); 397 | /// tree.root_mut().push_back( Tree::new(1) ); 398 | /// assert_eq!( tree.to_string(), "0( 1 )" ); 399 | /// tree.root_mut().push_back( Tree::new(2) ); 400 | /// assert_eq!( tree.to_string(), "0( 1 2 )" ); 401 | /// ``` 402 | pub fn push_back( &mut self, mut tree: Tree ) { 403 | tree.root_mut_().set_up( self ); 404 | if self.has_no_child() { 405 | self.set_head( tree.root() ); 406 | } else { 407 | unsafe{ self.tail.unwrap().as_mut().connect_next( tree.root_mut_() ); } 408 | } 409 | self.set_tail( tree.root() ); 410 | self.inc_sizes( 1, tree.root().node_count() ); 411 | mem::forget( tree ); 412 | } 413 | 414 | /// Removes and return the first child. 415 | /// 416 | /// # Examples 417 | /// 418 | /// ``` 419 | /// use trees::Tree; 420 | /// 421 | /// let mut tree = Tree::::from_tuple(( 0, (1, 2, 3), )); 422 | /// assert_eq!( tree.to_string(), "0( 1( 2 3 ) )" ); 423 | /// assert_eq!( tree.front_mut().unwrap().pop_front(), Some( Tree::new(2) )); 424 | /// assert_eq!( tree.to_string(), "0( 1( 3 ) )" ); 425 | /// assert_eq!( tree.front_mut().unwrap().pop_front(), Some( Tree::new(3) )); 426 | /// assert_eq!( tree.to_string(), "0( 1 )" ); 427 | /// ``` 428 | pub fn pop_front( &mut self ) -> Option> { 429 | match self.size.degree { 430 | 0 => None, 431 | 1 => unsafe { 432 | let head = self.head.unwrap(); 433 | self.head = None; 434 | self.tail = None; 435 | self.dec_sizes( 1, head.as_ref().size.descendants+1 ); 436 | Some( Tree::from_node( head )) 437 | }, 438 | _ => unsafe { 439 | let mut head = self.head.unwrap(); 440 | let mut new_head = head.as_ref().next.unwrap(); 441 | new_head.as_mut().prev = None; 442 | head.as_mut().next = None; 443 | self.head = Some( new_head ); 444 | self.dec_sizes( 1, head.as_ref().size.descendants+1 ); 445 | Some( Tree::from_node( head )) 446 | }, 447 | } 448 | } 449 | 450 | /// Removes and return the last child. 451 | /// 452 | /// # Examples 453 | /// 454 | /// ``` 455 | /// use trees::Tree; 456 | /// 457 | /// let mut tree = Tree::::from_tuple(( 0, (1, 2, 3), )); 458 | /// assert_eq!( tree.to_string(), "0( 1( 2 3 ) )" ); 459 | /// assert_eq!( tree.front_mut().unwrap().pop_back(), Some( Tree::new(3) )); 460 | /// assert_eq!( tree.to_string(), "0( 1( 2 ) )" ); 461 | /// assert_eq!( tree.front_mut().unwrap().pop_back(), Some( Tree::new(2) )); 462 | /// assert_eq!( tree.to_string(), "0( 1 )" ); 463 | /// ``` 464 | pub fn pop_back( &mut self ) -> Option> { 465 | match self.size.degree { 466 | 0 => None, 467 | 1 => unsafe { 468 | let tail = self.tail.unwrap(); 469 | self.head = None; 470 | self.tail = None; 471 | self.dec_sizes( 1, tail.as_ref().size.descendants+1 ); 472 | Some( Tree::from_node( tail )) 473 | }, 474 | _ => unsafe { 475 | let mut tail = self.tail.unwrap(); 476 | let mut new_tail = tail.as_ref().prev.unwrap(); 477 | new_tail.as_mut().next = None; 478 | tail.as_mut().prev = None; 479 | self.tail = Some( new_tail ); 480 | self.dec_sizes( 1, tail.as_ref().size.descendants+1 ); 481 | Some( Tree::from_node( tail )) 482 | }, 483 | } 484 | } 485 | 486 | /// Adds all the forest's trees at front of children list. 487 | /// 488 | /// # Examples 489 | /// 490 | /// ``` 491 | /// use trees::{Forest, Tree}; 492 | /// let mut tree = Tree::new(0); 493 | /// tree.push_back( Tree::new(1) ); 494 | /// tree.push_back( Tree::new(2) ); 495 | /// let mut forest = Forest::new(); 496 | /// forest.push_back( Tree::new(3) ); 497 | /// forest.push_back( Tree::new(4) ); 498 | /// tree.root_mut().prepend( forest ); 499 | /// assert_eq!( tree.to_string(), "0( 3 4 1 2 )" ); 500 | /// ``` 501 | pub fn prepend( &mut self, mut forest: Forest ) { 502 | if !forest.has_no_child() { 503 | forest.set_up( self ); 504 | if self.has_no_child() { 505 | self.set_tail( forest.root_().back().unwrap() ); 506 | } else { 507 | unsafe{ forest.root_mut_().tail.unwrap().as_mut().connect_next( self.head.unwrap().as_mut() ); } 508 | } 509 | self.set_head( forest.front().unwrap() ); 510 | let size = forest.root_().size; 511 | self.inc_sizes( size.degree, size.descendants ); 512 | forest.clear(); 513 | } 514 | } 515 | 516 | /// Adds all the forest's trees at back of children list. 517 | /// 518 | /// # Examples 519 | /// 520 | /// ``` 521 | /// use trees::{Forest, Tree}; 522 | /// let mut tree = Tree::new(0); 523 | /// tree.root_mut().push_back( Tree::new(1) ); 524 | /// tree.root_mut().push_back( Tree::new(2) ); 525 | /// let mut forest = Forest::new(); 526 | /// forest.push_back( Tree::new(3) ); 527 | /// forest.push_back( Tree::new(4) ); 528 | /// tree.root_mut().append( forest ); 529 | /// assert_eq!( tree.to_string(), "0( 1 2 3 4 )" ); 530 | /// ``` 531 | pub fn append( &mut self, mut forest: Forest ) { 532 | if !forest.has_no_child() { 533 | forest.set_up( self ); 534 | if self.has_no_child() { 535 | self.set_head( forest.root_().front().unwrap() ); 536 | } else { 537 | unsafe{ self.tail.unwrap().as_mut().connect_next( forest.root_mut_().head.unwrap().as_mut() ); } 538 | } 539 | self.set_tail( forest.back().unwrap() ); 540 | let size = forest.root_().size; 541 | self.inc_sizes( size.degree, size.descendants ); 542 | forest.clear(); 543 | } 544 | } 545 | 546 | pub(crate) fn non_null( &self ) -> NonNull> { 547 | unsafe{ NonNull::new_unchecked( self as *const _ as *mut Node )} 548 | } 549 | 550 | pub(crate) fn set_head( &mut self, child: &Node ) { 551 | self.head = Some( child.non_null() ); 552 | } 553 | 554 | pub(crate) fn set_tail( &mut self, child: &Node ) { 555 | self.tail = Some( child.non_null() ); 556 | } 557 | 558 | pub(crate) fn set_up( &mut self, up: &Node ) { 559 | self.up = Some( up.non_null() ); 560 | } 561 | 562 | pub(crate) fn connect_next( &mut self, next: &mut Node ) { 563 | self.next = Some( next.non_null() ); 564 | next.prev = Some( self.non_null() ); 565 | } 566 | 567 | pub(crate) fn inc_sizes( &mut self, degree: usize, node_cnt: usize ) { 568 | self.size.degree += degree; 569 | self.size.descendants += node_cnt; 570 | let mut node = self.up; 571 | while let Some( mut pnode ) = node { 572 | unsafe { 573 | pnode.as_mut().size.descendants += node_cnt; 574 | node = pnode.as_ref().up; 575 | } 576 | } 577 | } 578 | 579 | pub(crate) fn dec_sizes( &mut self, degree: usize, node_cnt: usize ) { 580 | self.size.degree -= degree; 581 | self.size.descendants -= node_cnt; 582 | let mut node = self.up; 583 | while let Some( mut pnode ) = node { 584 | unsafe { 585 | pnode.as_mut().size.descendants -= node_cnt; 586 | node = pnode.as_ref().up; 587 | } 588 | } 589 | } 590 | 591 | pub(crate) fn is_forest( &self ) -> bool { 592 | match self.data { 593 | Data::PiledNone{ .. } => true, 594 | Data::ScatteredNone{ .. } => true, 595 | _ => false, 596 | } 597 | } 598 | } 599 | 600 | impl_debug_display_for_node!( Node, iter, data() ); 601 | impl_order_relations_for_node!( Node, iter, data() ); 602 | impl_hash_for_node!( Node, iter, data() ); 603 | 604 | #[cfg( miri )] 605 | mod miri_tests { 606 | #[test] fn has_no_child() { 607 | use crate::Tree; 608 | 609 | let mut tree = Tree::new(0); 610 | let mut root = tree.root_mut(); 611 | assert!( root.has_no_child() ); 612 | root.push_back( Tree::new(1) ); 613 | assert!( !root.has_no_child() ); 614 | } 615 | 616 | #[test] fn degree() { 617 | use crate::Tree; 618 | 619 | let mut tree = Tree::new(0); 620 | let mut root = tree.root_mut(); 621 | assert_eq!( root.degree(), 0 ); 622 | root.push_back( Tree::new(1) ); 623 | assert_eq!( root.degree(), 1 ); 624 | root.push_back( Tree::new(2) ); 625 | assert_eq!( root.degree(), 2 ); 626 | } 627 | 628 | #[test] fn node_count() { 629 | use crate::Tree; 630 | 631 | let tree = Tree::::from_tuple(( 0, (1,2), (3,4) )); 632 | assert_eq!( tree.root().node_count(), 5 ); 633 | } 634 | 635 | #[test] fn parent() { 636 | use crate::Tree; 637 | 638 | let tree = Tree::::from_tuple(( 0, 1, 2, 3 )); 639 | tree.root().iter().for_each( |child| { 640 | assert_eq!( child.parent(), Some( tree.root())) 641 | }); 642 | } 643 | 644 | #[test] fn insert_prev_sib() { 645 | use crate::tr; 646 | 647 | let mut tree = tr(0) /tr(1)/tr(2); 648 | tree.iter_mut().for_each( |mut sub| sub.insert_prev_sib( tr(3) )); 649 | assert_eq!( tree.to_string(), "0( 3 1 3 2 )" ); 650 | } 651 | 652 | #[test] fn insert_next_sib() { 653 | use crate::tr; 654 | 655 | let mut tree = tr(0) /tr(1)/tr(2); 656 | tree.iter_mut().for_each( |mut sub| sub.insert_next_sib( tr(3) )); 657 | assert_eq!( tree.to_string(), "0( 1 3 2 3 )" ); 658 | } 659 | 660 | #[test] fn detach() { 661 | use crate::{fr, tr}; 662 | 663 | let mut forest = -tr(1)-tr(2)-tr(3); 664 | forest.iter_mut().for_each( |mut sub| { sub.detach(); }); 665 | assert_eq!( forest, fr() ); 666 | } 667 | 668 | #[test] fn iter() { 669 | use crate::Tree; 670 | 671 | let mut tree = Tree::new(0); 672 | assert_eq!( tree.iter().next(), None ); 673 | 674 | tree.push_back( Tree::new(1) ); 675 | tree.push_back( Tree::new(2) ); 676 | let mut iter = tree.root().iter(); 677 | assert_eq!( iter.next(), Some( Tree::new(1).root() )); 678 | assert_eq!( iter.next(), Some( Tree::new(2).root() )); 679 | assert_eq!( iter.next(), None ); 680 | } 681 | 682 | #[test] fn iter_mut() { 683 | use crate::Tree; 684 | 685 | let mut tree = Tree::::from_tuple(( 0, (1, 2, 3), )); 686 | tree.front_mut().unwrap() 687 | .iter_mut() 688 | .for_each( |mut child| *child.data_mut() *= 10 ); 689 | assert_eq!( tree.to_string(), "0( 1( 20 30 ) )" ); 690 | } 691 | 692 | #[test] fn push_front() { 693 | use crate::Tree; 694 | 695 | let mut tree = Tree::new(0); 696 | tree.root_mut().push_front( Tree::new(1) ); 697 | assert_eq!( tree.to_string(), "0( 1 )" ); 698 | tree.root_mut().push_front( Tree::new(2) ); 699 | assert_eq!( tree.to_string(), "0( 2 1 )" ); 700 | } 701 | 702 | #[test] fn push_back() { 703 | use crate::Tree; 704 | 705 | let mut tree = Tree::new(0); 706 | tree.root_mut().push_back( Tree::new(1) ); 707 | assert_eq!( tree.to_string(), "0( 1 )" ); 708 | tree.root_mut().push_back( Tree::new(2) ); 709 | assert_eq!( tree.to_string(), "0( 1 2 )" ); 710 | } 711 | 712 | #[test] fn pop_front() { 713 | use crate::Tree; 714 | 715 | let mut tree = Tree::::from_tuple(( 0, (1, 2, 3), )); 716 | assert_eq!( tree.to_string(), "0( 1( 2 3 ) )" ); 717 | assert_eq!( tree.front_mut().unwrap().pop_front(), Some( Tree::new(2) )); 718 | assert_eq!( tree.to_string(), "0( 1( 3 ) )" ); 719 | assert_eq!( tree.front_mut().unwrap().pop_front(), Some( Tree::new(3) )); 720 | assert_eq!( tree.to_string(), "0( 1 )" ); 721 | } 722 | 723 | #[test] fn pop_back() { 724 | use crate::Tree; 725 | 726 | let mut tree = Tree::::from_tuple(( 0, (1, 2, 3), )); 727 | assert_eq!( tree.to_string(), "0( 1( 2 3 ) )" ); 728 | assert_eq!( tree.front_mut().unwrap().pop_back(), Some( Tree::new(3) )); 729 | assert_eq!( tree.to_string(), "0( 1( 2 ) )" ); 730 | assert_eq!( tree.front_mut().unwrap().pop_back(), Some( Tree::new(2) )); 731 | assert_eq!( tree.to_string(), "0( 1 )" ); 732 | } 733 | 734 | #[test] fn prepend() { 735 | use crate::{Forest, Tree}; 736 | 737 | let mut tree = Tree::new(0); 738 | tree.push_back( Tree::new(1) ); 739 | tree.push_back( Tree::new(2) ); 740 | let mut forest = Forest::new(); 741 | forest.push_back( Tree::new(3) ); 742 | forest.push_back( Tree::new(4) ); 743 | tree.root_mut().prepend( forest ); 744 | assert_eq!( tree.to_string(), "0( 3 4 1 2 )" ); 745 | } 746 | 747 | #[test] fn append() { 748 | use crate::{Forest, Tree}; 749 | 750 | let mut tree = Tree::new(0); 751 | tree.root_mut().push_back( Tree::new(1) ); 752 | tree.root_mut().push_back( Tree::new(2) ); 753 | let mut forest = Forest::new(); 754 | forest.push_back( Tree::new(3) ); 755 | forest.push_back( Tree::new(4) ); 756 | tree.root_mut().append( forest ); 757 | assert_eq!( tree.to_string(), "0( 1 2 3 4 )" ); 758 | } 759 | } 760 | -------------------------------------------------------------------------------- /deps/trees/src/node_vec.rs: -------------------------------------------------------------------------------- 1 | //! Buffer for storing nodes in contiguous memory allocation. 2 | 3 | use super::{Node, Data, rc::Shared}; 4 | use crate::Size; 5 | use crate::{TupleTree, TupleForest}; 6 | 7 | use crate::rust::*; 8 | 9 | /// Buffer for storing nodes in contiguous memory allocation. 10 | pub(crate) struct NodeVec { 11 | pub(crate) buf : Vec>>>, 12 | pub(crate) ref_cnt : Cell, // alive node count 13 | } 14 | 15 | impl NodeVec { 16 | pub(crate) fn new_raw_non_null( cap: usize ) -> NonNull> { 17 | unsafe { 18 | NonNull::new_unchecked( Box::into_raw( Box::new( NodeVec:: { 19 | buf: (0..cap).map( |_| Shared::new( RefCell::new( Node::default() ))).collect::>(), 20 | ref_cnt: Cell::new( cap ), 21 | }))) 22 | } 23 | } 24 | 25 | pub(crate) fn non_null( &self ) -> NonNull> { 26 | unsafe { 27 | NonNull::new_unchecked( self as *const NodeVec as *mut NodeVec ) 28 | } 29 | } 30 | 31 | pub(crate) fn non_null_node( &self, index: usize ) -> NonNull> { 32 | unsafe { 33 | NonNull::new_unchecked( self.buf.get_unchecked( index ).try_borrow_unguarded().unwrap() as *const Node as *mut Node ) 34 | } 35 | } 36 | 37 | pub(crate) fn node( &self, index: usize ) -> &Node { unsafe{ &*self.non_null_node( index ).as_ptr() }} 38 | pub(crate) fn node_mut( &mut self, index: usize ) -> &mut Node { unsafe{ &mut *self.non_null_node( index ).as_ptr() }} 39 | 40 | pub(crate) fn make_piled_node( &mut self, parent: Option>>, index: usize, data: T, size: Size ) -> NonNull> { 41 | self.make_node( parent, index, Data::Piled{ data, owner: self.non_null() }, size ) 42 | } 43 | 44 | pub(crate) fn make_node( &mut self, parent: Option>>, index: usize, data: Data, size: Size ) -> NonNull> { 45 | unsafe { 46 | let node = self.buf.get_unchecked_mut( index ); 47 | let mut node = node.deref().borrow_mut(); 48 | node.up = parent; 49 | node.size = size; 50 | node.data = data; 51 | 52 | node.non_null() 53 | } 54 | } 55 | 56 | pub(crate) fn append_child( &mut self, parent: usize, child: usize, data: T, size: Size ) { 57 | let parent_node = Some( self.non_null_node( parent )); 58 | let mut child = self.make_piled_node( parent_node, child, data, size ); 59 | 60 | match self.node( parent ).tail { 61 | Some( mut tail ) => unsafe{ tail.as_mut().connect_next( child.as_mut() )}, 62 | None => self.node_mut( parent ).head = Some( child ), 63 | } 64 | self.node_mut( parent ).tail = Some( child ); 65 | } 66 | 67 | pub(crate) fn construct_tree( &mut self, tuple: Tuple ) 68 | where Tuple: TupleTree 69 | { 70 | let height = Tuple::height(); 71 | let mut offsets = Vec::with_capacity( height ); 72 | offsets.push( 0 ); 73 | if height > 1 { 74 | offsets.push( 1 ); 75 | for depth in 2..height { 76 | let offset = offsets[ (depth-1) ] + Tuple::descendants( depth-2 ); 77 | offsets.push( offset ); 78 | } 79 | } 80 | 81 | use crate::tuple::Visit; 82 | 83 | let mut is_root = true; 84 | let mut leaf = false; 85 | let mut parent = 0; 86 | let mut depth = 1; 87 | let mut f = |visit, size| { 88 | if is_root { 89 | let data = match visit { 90 | Visit::Branch( data ) | 91 | Visit::Leaf( data ) => data, 92 | Visit::Frame => unreachable!(), 93 | }; 94 | self.make_piled_node( None, 0, data, size ); 95 | is_root = false; 96 | } else { 97 | match visit { 98 | Visit::Branch( data ) => { 99 | self.append_child( parent, offsets[ depth ], data, size ); 100 | parent = offsets[ depth ]; 101 | depth += 1; 102 | }, 103 | Visit::Leaf( data ) => { 104 | self.append_child( parent, offsets[ depth ], data, size ); 105 | offsets[ depth ] += 1; 106 | if !leaf { leaf = true; } 107 | }, 108 | Visit::Frame => { 109 | depth -= 1; 110 | if leaf { 111 | leaf = false; 112 | offsets[ depth ] += 1; 113 | if depth > 0 { 114 | parent = offsets[ depth-1 ]; 115 | } 116 | } 117 | }, 118 | } 119 | } 120 | }; 121 | Tuple::preorder_with_size_hint( tuple, &mut f ); 122 | } 123 | 124 | pub(crate) fn construct_forest( &mut self, tuple: Tuple ) 125 | where Tuple: TupleForest 126 | { 127 | let height = Tuple::height() + 1; 128 | let mut offsets = Vec::with_capacity( height ); 129 | offsets.push( 0 ); 130 | if height > 1 { 131 | offsets.push( 1 ); 132 | for depth in 2..height { 133 | let offset = offsets[ depth-1 ] + Tuple::descendants( depth-2 ); 134 | offsets.push( offset ); 135 | } 136 | } 137 | 138 | let fake_root = Data::PiledNone{ owner: unsafe{ NonNull::new_unchecked( self )}}; 139 | 140 | self.make_node( None, 0, fake_root, Tuple::SIZE ); 141 | 142 | let mut parent = 0; 143 | let mut depth = 1; 144 | let mut leaf = false; 145 | let mut f = |visit, size| { 146 | use crate::tuple::Visit; 147 | match visit { 148 | Visit::Branch( data ) => { 149 | self.append_child( parent, offsets[ depth ], data, size ); 150 | parent = offsets[ depth ]; 151 | depth += 1; 152 | }, 153 | Visit::Leaf( data ) => { 154 | self.append_child( parent, offsets[ depth ], data, size ); 155 | offsets[ depth ] += 1; 156 | if !leaf { leaf = true; } 157 | }, 158 | Visit::Frame => { 159 | depth -= 1; 160 | if leaf { 161 | leaf = false; 162 | offsets[ depth ] += 1; 163 | parent = offsets[ depth-1 ]; 164 | } 165 | }, 166 | } 167 | }; 168 | Tuple::preorder_with_size_hint( tuple, &mut f ); 169 | } 170 | 171 | pub(crate) fn decr_ref( owner: NonNull> ) { 172 | unsafe { 173 | let node_vec = owner.as_ref(); 174 | use super::rc::RefCount; 175 | if node_vec.ref_cnt.decr() == 0 { 176 | drop( Box::from_raw( owner.as_ptr() )); 177 | } 178 | } 179 | } 180 | } 181 | 182 | impl Drop for NodeVec { 183 | fn drop( &mut self ) { 184 | unsafe{ self.buf.set_len( 0 ); } 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /deps/trees/src/notation.rs: -------------------------------------------------------------------------------- 1 | //! Operator overloading of `-` and `/` for constructing tree expression. 2 | 3 | use super::{Forest, Tree}; 4 | 5 | macro_rules! impl_notations { 6 | ($tree:ident, $forest:ident, $tr:ident, $fr:ident) => { 7 | /// `tr` stands for `Tree` 8 | pub fn $tr( data: T ) -> $tree { $tree::::new( data )} 9 | 10 | /// `fr` stands for `Forest` 11 | pub fn $fr() -> $forest { $forest::::new() } 12 | 13 | // - $tree 14 | impl crate::rust::Neg for $tree { 15 | type Output = $forest; 16 | 17 | fn neg( self ) -> $forest { 18 | let mut forest = $fr(); 19 | forest.push_back( self ); 20 | forest 21 | } 22 | } 23 | 24 | // - &$tree 25 | impl<'a,T:Clone> crate::rust::Neg for &'a $tree { 26 | type Output = $forest; 27 | 28 | fn neg( self ) -> $forest { 29 | let mut forest = $fr(); 30 | forest.push_back( self.clone() ); 31 | forest 32 | } 33 | } 34 | 35 | // $tree - $tree 36 | impl crate::rust::Sub for $tree { 37 | type Output = $forest; 38 | 39 | fn sub( self, rhs: Self ) -> $forest { 40 | let mut forest = $fr(); 41 | forest.push_back( self ); 42 | forest.push_back( rhs ); 43 | forest 44 | } 45 | } 46 | 47 | // $tree - &$tree 48 | impl<'a,T:Clone> crate::rust::Sub<&'a $tree> for $tree { 49 | type Output = $forest; 50 | 51 | fn sub( self, rhs: &'a $tree ) -> $forest { 52 | let mut forest = $fr(); 53 | forest.push_back( self ); 54 | forest.push_back( rhs.clone() ); 55 | forest 56 | } 57 | } 58 | 59 | // &$tree - $tree 60 | impl<'a,T:Clone> crate::rust::Sub<$tree> for &'a $tree { 61 | type Output = $forest; 62 | 63 | fn sub( self, rhs: $tree ) -> $forest { 64 | let mut forest = $fr(); 65 | forest.push_back( self.clone() ); 66 | forest.push_back( rhs ); 67 | forest 68 | } 69 | } 70 | 71 | // &$tree - &$tree 72 | impl<'a,T:Clone> crate::rust::Sub for &'a $tree { 73 | type Output = $forest; 74 | 75 | fn sub( self, rhs: Self ) -> $forest { 76 | let mut forest = $fr(); 77 | forest.push_back( self.clone() ); 78 | forest.push_back( rhs.clone() ); 79 | forest 80 | } 81 | } 82 | 83 | // $tree / $forest 84 | impl crate::rust::Div<$forest> for $tree { 85 | type Output = $tree; 86 | 87 | fn div( mut self, rhs: $forest ) -> $tree { 88 | self.append( rhs ); 89 | self 90 | } 91 | } 92 | 93 | // $tree / &$forest 94 | impl<'a,T:Clone> crate::rust::Div<&'a $forest> for $tree { 95 | type Output = $tree; 96 | 97 | fn div( mut self, rhs: &'a $forest ) -> $tree { 98 | self.append( rhs.clone() ); 99 | self 100 | } 101 | } 102 | 103 | // &$tree / $forest 104 | impl<'a,T:Clone> crate::rust::Div<$forest> for &'a $tree { 105 | type Output = $tree; 106 | 107 | fn div( self, rhs: $forest ) -> $tree { 108 | let mut tree = self.clone(); 109 | tree.append( rhs ); 110 | tree 111 | } 112 | } 113 | 114 | // &$tree / &$forest 115 | impl<'a,T:Clone> crate::rust::Div<&'a $forest> for &'a $tree { 116 | type Output = $tree; 117 | 118 | fn div( self, rhs: &'a $forest ) -> $tree { 119 | let mut tree = self.clone(); 120 | tree.append( rhs.clone() ); 121 | tree 122 | } 123 | } 124 | 125 | // $tree / $tree 126 | impl crate::rust::Div<$tree> for $tree { 127 | type Output = $tree; 128 | 129 | fn div( mut self, rhs: $tree ) -> $tree { 130 | self.push_back( rhs ); 131 | self 132 | } 133 | } 134 | 135 | // $tree / &$tree 136 | impl<'a,T:Clone> crate::rust::Div<&'a $tree> for $tree { 137 | type Output = $tree; 138 | 139 | fn div( mut self, rhs: &'a $tree ) -> $tree { 140 | self.push_back( rhs.clone() ); 141 | self 142 | } 143 | } 144 | 145 | // &$tree / $tree 146 | impl<'a,T:Clone> crate::rust::Div<$tree> for &'a $tree { 147 | type Output = $tree; 148 | 149 | fn div( self, rhs: $tree ) -> $tree { 150 | let mut tree = self.clone(); 151 | tree.push_back( rhs ); 152 | tree 153 | } 154 | } 155 | 156 | // &$tree / &$tree 157 | impl<'a,T:Clone> crate::rust::Div for &'a $tree { 158 | type Output = $tree; 159 | 160 | fn div( self, rhs: Self ) -> $tree { 161 | let mut tree = self.clone(); 162 | tree.push_back( rhs.clone() ); 163 | tree 164 | } 165 | } 166 | 167 | // $tree / () 168 | impl crate::rust::Div<()> for $tree { 169 | type Output = $tree; 170 | 171 | fn div( self, _rhs: () ) -> $tree { 172 | self 173 | } 174 | } 175 | 176 | // &$tree / () 177 | impl<'a,T:Clone> crate::rust::Div<()> for &'a $tree { 178 | type Output = $tree; 179 | 180 | fn div( self, _rhs: () ) -> $tree { 181 | self.clone() 182 | } 183 | } 184 | 185 | // $forest - $tree 186 | impl crate::rust::Sub<$tree> for $forest { 187 | type Output = $forest; 188 | 189 | fn sub( mut self, rhs: $tree ) -> Self { 190 | self.push_back( rhs ); 191 | self 192 | } 193 | } 194 | 195 | // $forest - &$tree 196 | impl<'a,T:Clone> crate::rust::Sub<&'a $tree> for $forest { 197 | type Output = $forest; 198 | 199 | fn sub( mut self, rhs: &'a $tree ) -> Self { 200 | self.push_back( rhs.clone() ); 201 | self 202 | } 203 | } 204 | 205 | // &$forest - $tree 206 | impl<'a,T:Clone> crate::rust::Sub<$tree> for &'a $forest { 207 | type Output = $forest; 208 | 209 | fn sub( self, rhs: $tree ) -> $forest { 210 | let mut forest = self.clone(); 211 | forest.push_back( rhs ); 212 | forest 213 | } 214 | } 215 | 216 | // &$forest - &$tree 217 | impl<'a,'b,T:Clone> crate::rust::Sub<&'b $tree> for &'a $forest { 218 | type Output = $forest; 219 | 220 | fn sub( self, rhs: &'b $tree ) -> $forest { 221 | let mut forest = self.clone(); 222 | forest.push_back( rhs.clone() ); 223 | forest 224 | } 225 | } 226 | 227 | // $forest - $forest 228 | impl crate::rust::Sub<$forest> for $forest { 229 | type Output = $forest; 230 | 231 | fn sub( mut self, rhs: Self ) -> Self { 232 | self.append( rhs ); 233 | self 234 | } 235 | } 236 | 237 | // $forest - &$forest 238 | impl<'a,T:Clone> crate::rust::Sub<&'a $forest> for $forest { 239 | type Output = $forest; 240 | 241 | fn sub( mut self, rhs: &'a $forest ) -> Self { 242 | self.append( rhs.clone() ); 243 | self 244 | } 245 | } 246 | 247 | // &$forest - $forest 248 | impl<'a,T:Clone> crate::rust::Sub<$forest> for &'a $forest { 249 | type Output = $forest; 250 | 251 | fn sub( self, mut rhs: $forest ) -> $forest { 252 | rhs.prepend( self.clone() ); 253 | rhs 254 | } 255 | } 256 | 257 | // &$forest - &$forest 258 | impl<'a,'b,T:Clone> crate::rust::Sub<&'b $forest> for &'a $forest { 259 | type Output = $forest; 260 | 261 | fn sub( self, rhs: &'b $forest ) -> $forest { 262 | let mut forest = self.clone(); 263 | forest.append( rhs.clone() ); 264 | forest 265 | } 266 | } 267 | }; 268 | } 269 | 270 | impl_notations!{ Tree, Forest, tr, fr } 271 | -------------------------------------------------------------------------------- /deps/trees/src/rc.rs: -------------------------------------------------------------------------------- 1 | //! Reference-counting nodes. 2 | 3 | use crate::rust::*; 4 | 5 | use super::{Data, Forest, Node, NodeVec, IterRc, Tree}; 6 | 7 | // Replacement of std::rc::Rc to avoid heap allocations. 8 | pub(crate) struct Shared { 9 | pub(crate) data : T, 10 | pub(crate) count : Cell, // Only strong count is required. Weak count is shared as NodeVec::ref_cnt. 11 | } 12 | 13 | impl Shared { 14 | pub(crate) fn new( data: T ) -> Self { Shared{ data, count: Cell::new(1), }} 15 | } 16 | 17 | impl Deref for Shared { 18 | type Target = T; 19 | 20 | fn deref( &self ) -> &T { &self.data } 21 | } 22 | 23 | pub(crate) trait RefCount { 24 | fn incr( &self ); 25 | fn decr( &self ) -> usize; 26 | } 27 | 28 | impl RefCount for Cell { 29 | fn incr( &self ) { 30 | let count = self.get(); 31 | if count == 0 || count == usize::MAX { 32 | panic!(); 33 | } else { 34 | self.set( count + 1 ); 35 | } 36 | } 37 | 38 | fn decr( &self ) -> usize { 39 | match self.get().checked_sub( 1 ) { 40 | Some( count ) => { 41 | self.set( count ); 42 | count 43 | }, 44 | None => panic!(), 45 | } 46 | } 47 | } 48 | 49 | /// Reference-counting node which stored scatteredly. 50 | pub struct ScatteredRcNode( Rc>> ); 51 | 52 | /// Reference-counting node which stored contiguously. 53 | pub struct PiledRcNode( NonNull>, usize ); 54 | 55 | /// Reference-counting node. 56 | pub enum RcNode { 57 | Scattered( ScatteredRcNode ), 58 | Piled( PiledRcNode ), 59 | } 60 | 61 | impl From> for RcNode { 62 | fn from( tree: Tree ) -> Self { 63 | let rc = tree.root().into_rc(); 64 | mem::forget( tree ); 65 | rc 66 | } 67 | } 68 | 69 | impl Node { 70 | // increase ref count. 71 | pub(crate) fn rc( &self ) -> RcNode { 72 | match &self.data { 73 | Data::Scattered{ data: _, owner } => { 74 | let rc = unsafe{ Rc::from_raw( owner.as_ptr() )}; 75 | mem::forget( rc.clone() ); 76 | RcNode::Scattered( ScatteredRcNode( rc )) 77 | }, 78 | Data::Piled{ data: _, owner } => unsafe { 79 | let index = ( self as *const _ as usize - owner.as_ref().buf.as_ptr() as usize ) 80 | / mem::size_of::>>>(); 81 | let node_vec = owner.as_ref(); 82 | node_vec.ref_cnt.incr(); 83 | let node = node_vec.buf.get_unchecked( index ); 84 | node.count.incr(); 85 | RcNode::Piled( PiledRcNode( *owner, index )) 86 | }, 87 | _ => unreachable!(), 88 | } 89 | } 90 | 91 | // do not increase ref count. 92 | pub(crate) fn into_rc( &self ) -> RcNode { 93 | match &self.data { 94 | Data::Scattered{ data: _, owner } => { 95 | let rc = unsafe{ Rc::from_raw( owner.as_ptr() )}; 96 | RcNode::Scattered( ScatteredRcNode( rc )) 97 | }, 98 | Data::Piled{ data: _, owner } => unsafe { 99 | let index = ( self as *const _ as usize - owner.as_ref().buf.as_ptr() as usize ) 100 | / mem::size_of::>>>(); 101 | RcNode::Piled( PiledRcNode( *owner, index )) 102 | }, 103 | _ => unreachable!(), 104 | } 105 | } 106 | } 107 | 108 | impl Clone for RcNode { 109 | fn clone( &self ) -> RcNode { 110 | match self { 111 | RcNode::Scattered( ScatteredRcNode( rc )) => RcNode::Scattered( ScatteredRcNode( rc.clone() )), 112 | RcNode::Piled( PiledRcNode( node_vec, index )) => { 113 | unsafe { 114 | let node = node_vec.as_ref().buf.get_unchecked( *index ); 115 | node.count.incr(); 116 | } 117 | RcNode::Piled( PiledRcNode( node_vec.clone(), *index )) 118 | }, 119 | } 120 | } 121 | } 122 | 123 | impl Drop for RcNode { 124 | fn drop( &mut self ) { 125 | let mut drop_piled = false; 126 | match self { 127 | RcNode::Scattered( ScatteredRcNode( rc )) => { 128 | if Rc::strong_count( &rc ) == 1 { 129 | while let Some(_) = self.pop_front() {} 130 | } 131 | }, 132 | RcNode::Piled( PiledRcNode( node_vec, index )) => unsafe { 133 | let node = node_vec.as_ref().buf.get_unchecked( *index ); 134 | if node.count.decr() == 0 { 135 | drop_piled = true; 136 | while let Some(_) = self.pop_front() {} 137 | } 138 | }, 139 | } 140 | match self { 141 | RcNode::Piled( PiledRcNode( node_vec, index )) => unsafe { 142 | if drop_piled { 143 | let node = node_vec.as_mut().buf.get_unchecked_mut( *index ); 144 | ptr::drop_in_place( &mut node.data ); 145 | } 146 | NodeVec::decr_ref( *node_vec ); 147 | } 148 | _ => (), 149 | } 150 | } 151 | } 152 | 153 | impl RcNode { 154 | /// Checks if it is a root node. 155 | /// 156 | /// # Examples 157 | /// 158 | /// ```rust 159 | /// use trees::{RcNode, tr}; 160 | /// 161 | /// let root = RcNode::from( tr(0)/tr(1) ); 162 | /// assert!( root.is_root() ); 163 | /// assert!( !root.front().unwrap().is_root() ); 164 | /// ``` 165 | pub fn is_root( &self ) -> bool { self.node_borrow().parent().is_none() } 166 | 167 | /// Dynamically borrows the node's data. 168 | pub fn data( &self ) -> Ref { Ref::map( self.node_borrow(), |node| node.data() )} 169 | 170 | /// Mutably borrows the node's data. 171 | pub fn data_mut( &self ) -> RefMut { RefMut::map( self.node_borrow_mut(), |node| node.data_mut() )} 172 | 173 | /// Obtains a node reference 174 | pub unsafe fn node( &self ) -> Ref> { self.node_borrow() } 175 | 176 | /// Obtains a mutable node reference 177 | pub unsafe fn node_mut( &self ) -> RefMut> { self.node_borrow_mut() } 178 | 179 | pub(crate) fn node_borrow( &self ) -> Ref> { 180 | match self { 181 | RcNode::Scattered( ScatteredRcNode( rc )) => { 182 | let borrowed = rc.deref().borrow(); 183 | assert!( !borrowed.data.is_none() ); 184 | unsafe{ transmute( borrowed )} 185 | }, 186 | RcNode::Piled( PiledRcNode( node_vec, index )) => { 187 | let borrowed = unsafe{ node_vec.as_ref().buf.get_unchecked( *index ).deref().borrow() }; 188 | assert!( !borrowed.data.is_none() ); 189 | borrowed 190 | }, 191 | } 192 | } 193 | 194 | pub(crate) fn node_borrow_mut( &self ) -> RefMut> { 195 | match self { 196 | RcNode::Scattered( ScatteredRcNode( rc )) => { 197 | let borrowed = rc.deref().borrow_mut(); 198 | assert!( !borrowed.data.is_none() ); 199 | unsafe{ transmute( borrowed )} 200 | }, 201 | RcNode::Piled( PiledRcNode( node_vec, index )) => { 202 | let borrowed = unsafe{ node_vec.as_ref().buf.get_unchecked( *index ).deref().borrow_mut() }; 203 | assert!( !borrowed.data.is_none() ); 204 | borrowed 205 | }, 206 | } 207 | } 208 | 209 | /// Returns `true` if this `Node` has no child node, otherwise `false`. 210 | /// 211 | /// # Examples 212 | /// 213 | /// ```rust 214 | /// use trees::{RcNode, tr}; 215 | /// 216 | /// let root = RcNode::from( tr(0)/tr(1) ); 217 | /// assert!( !root.has_no_child() ); 218 | /// assert!( root.front().unwrap().has_no_child() ); 219 | /// ``` 220 | pub fn has_no_child( &self ) -> bool { self.node_borrow().has_no_child() } 221 | 222 | /// Returns the number of subtrees. 223 | /// 224 | /// # Examples 225 | /// 226 | /// ``` 227 | /// use trees::{RcNode, Tree}; 228 | /// 229 | /// let root = RcNode::from( Tree::::from_tuple(( 0, (1,2,3), (4,5,6), ))); 230 | /// assert_eq!( root.degree(), 2 ); 231 | /// ``` 232 | pub fn degree( &self ) -> usize { self.node_borrow().degree() } 233 | 234 | /// Returns the number of all subnodes, including itself. 235 | /// 236 | /// # Examples 237 | /// 238 | /// ``` 239 | /// use trees::{RcNode, Tree}; 240 | /// 241 | /// let root = RcNode::from( Tree::::from_tuple(( 0, (1,2,3), (4,5,6), ))); 242 | /// assert_eq!( root.node_count(), 7 ); 243 | /// ``` 244 | pub fn node_count( &self ) -> usize { self.node_borrow().node_count() } 245 | 246 | /// Returns the first child of the tree, 247 | /// or None if it is empty. 248 | /// 249 | /// # Examples 250 | /// 251 | /// ```rust 252 | /// use trees::{RcNode, tr}; 253 | /// 254 | /// let root = RcNode::from( tr(0)/tr(1)/tr(2) ); 255 | /// assert_eq!( root.front(), Some( RcNode::from( tr(1) ))); 256 | /// ``` 257 | pub fn front( &self ) -> Option> { self.node_borrow().front().map( |node| node.rc() )} 258 | 259 | /// Returns the last child of the tree, 260 | /// or None if it is empty. 261 | /// 262 | /// # Examples 263 | /// 264 | /// ```rust 265 | /// use trees::{RcNode, tr}; 266 | /// 267 | /// let root = RcNode::from( tr(0)/tr(1)/tr(2) ); 268 | /// assert_eq!( root.back(), Some( RcNode::from( tr(2) ))); 269 | /// ``` 270 | pub fn back( &self ) -> Option> { self.node_borrow().back().map( |node| node.rc() )} 271 | 272 | /// Returns the parent node of this node, 273 | /// or None if it is the root node. 274 | /// 275 | /// # Examples 276 | /// 277 | /// ``` 278 | /// use trees::{RcNode, tr}; 279 | /// 280 | /// let root = RcNode::from( tr(0)/tr(1) ); 281 | /// assert_eq!( root.parent(), None ); 282 | /// let tr_1 = root.front().unwrap(); 283 | /// assert_eq!( tr_1.parent(), Some( root )); 284 | /// ``` 285 | pub fn parent( &self ) -> Option> { self.node_borrow().parent().map( |node| node.rc() )} 286 | 287 | /// Adds the tree as the first child. 288 | /// 289 | /// # Examples 290 | /// 291 | /// ``` 292 | /// use trees::{RcNode, Tree}; 293 | /// 294 | /// let root = RcNode::from( Tree::new(0) ); 295 | /// root.push_front( Tree::new(1) ); 296 | /// assert_eq!( root.to_string(), "0( 1 )" ); 297 | /// root.push_front( Tree::new(2) ); 298 | /// assert_eq!( root.to_string(), "0( 2 1 )" ); 299 | /// ``` 300 | pub fn push_front( &self, tree: Tree ) { self.node_borrow_mut().push_front( tree )} 301 | 302 | /// Adds the tree as the last child. 303 | /// 304 | /// # Examples 305 | /// 306 | /// ``` 307 | /// use trees::{RcNode, Tree}; 308 | /// 309 | /// let root = RcNode::from( Tree::new(0) ); 310 | /// root.push_back( Tree::new(1) ); 311 | /// assert_eq!( root.to_string(), "0( 1 )" ); 312 | /// root.push_back( Tree::new(2) ); 313 | /// assert_eq!( root.to_string(), "0( 1 2 )" ); 314 | /// ``` 315 | pub fn push_back( &self, tree: Tree ) { self.node_borrow_mut().push_back( tree )} 316 | 317 | /// Removes and return the first child. 318 | /// 319 | /// # Examples 320 | /// 321 | /// ``` 322 | /// use trees::{RcNode, Tree}; 323 | /// 324 | /// let root = RcNode::from( Tree::::from_tuple(( 0,1,2 ))); 325 | /// let front = root.pop_front().unwrap(); 326 | /// assert_eq!( front, RcNode::from( Tree::new(1) )); 327 | /// assert_eq!( root.to_string(), "0( 2 )" ); 328 | /// let front = root.pop_front().unwrap(); 329 | /// assert_eq!( front, RcNode::from( Tree::new(2) )); 330 | /// assert_eq!( root.to_string(), "0" ); 331 | /// ``` 332 | pub fn pop_front( &self ) -> Option> { 333 | self.node_borrow_mut().pop_front().map( |tree| RcNode::from( tree )) 334 | } 335 | 336 | /// Removes and return the last child. 337 | /// 338 | /// # Examples 339 | /// 340 | /// ``` 341 | /// use trees::{RcNode, Tree}; 342 | /// 343 | /// let root = RcNode::from( Tree::::from_tuple(( 0,1,2 ))); 344 | /// let back = root.pop_back().unwrap(); 345 | /// assert_eq!( back, RcNode::from( Tree::new(2) )); 346 | /// assert_eq!( root.to_string(), "0( 1 )" ); 347 | /// let back = root.pop_back().unwrap(); 348 | /// assert_eq!( back, RcNode::from( Tree::new(1) )); 349 | /// assert_eq!( root.to_string(), "0" ); 350 | /// ``` 351 | pub fn pop_back( &self ) -> Option> { self.node_borrow_mut().pop_back().map( |tree| RcNode::from( tree ))} 352 | 353 | /// Adds all the forest's trees at front of children list. 354 | /// 355 | /// # Examples 356 | /// 357 | /// ``` 358 | /// use trees::{Forest, RcNode, Tree, tr}; 359 | /// 360 | /// let root = RcNode::from( Tree::::from_tuple(( 0, 1, 2 ))); 361 | /// let forest = Forest::::from_tuple(( 3, 4 )); 362 | /// root.prepend( forest ); 363 | /// assert_eq!( root.to_string(), "0( 3 4 1 2 )" ); 364 | /// ``` 365 | pub fn prepend( &self, forest: Forest ) { self.node_borrow_mut().prepend( forest )} 366 | 367 | /// Adds all the forest's trees at back of children list. 368 | /// 369 | /// # Examples 370 | /// 371 | /// ``` 372 | /// use trees::{Forest, RcNode, Tree, tr}; 373 | /// 374 | /// let root = RcNode::from( Tree::::from_tuple(( 0, 1, 2 ))); 375 | /// let forest = Forest::::from_tuple(( 3, 4 )); 376 | /// root.append( forest ); 377 | /// assert_eq!( root.to_string(), "0( 1 2 3 4 )" ); 378 | /// ``` 379 | pub fn append( &self, forest: Forest ) { self.node_borrow_mut().append( forest )} 380 | 381 | /// Inserts sib tree before `self`. 382 | /// The newly inserted node will not be iterated over by the currently running iterator. 383 | /// 384 | /// # Examples 385 | /// 386 | /// ``` 387 | /// use trees::{RcNode, tr}; 388 | /// 389 | /// let root = RcNode::from( tr(0) /tr(1)/tr(2) ); 390 | /// for sub in root.iter_rc() { sub.insert_prev_sib( tr(3) ); } 391 | /// assert_eq!( root.to_string(), "0( 3 1 3 2 )" ); 392 | /// ``` 393 | pub fn insert_prev_sib( &self, sib: Tree ) { 394 | self.node_borrow_mut().insert_prev_sib( sib ); 395 | } 396 | 397 | /// Inserts sib tree after `self`. 398 | /// The newly inserted node will not be iterated over by the currently running iterator. 399 | /// 400 | /// # Examples 401 | /// 402 | /// ``` 403 | /// use trees::{RcNode, tr}; 404 | /// 405 | /// let root = RcNode::from( tr(0) /tr(1)/tr(2) ); 406 | /// for sub in root.iter_rc() { sub.insert_next_sib( tr(3) ); } 407 | /// assert_eq!( root.to_string(), "0( 1 3 2 3 )" ); 408 | /// ``` 409 | pub fn insert_next_sib( &self, sib: Tree ) { 410 | self.node_borrow_mut().insert_next_sib( sib ); 411 | } 412 | 413 | /// The subtree departs from its parent and becomes an indepent `Tree`. 414 | /// 415 | /// # Examples 416 | /// ``` 417 | /// use trees::{RcNode, tr}; 418 | /// 419 | /// let root = RcNode::from( tr(0) /tr(1)/tr(2)/tr(3) ); 420 | /// for sub in root.iter_rc() { sub.detach(); } 421 | /// assert!( root.has_no_child() ); 422 | /// ``` 423 | pub fn detach( &self ) { 424 | drop( RcNode::from( self.node_borrow_mut().detach() )); 425 | } 426 | 427 | /// Provides a forward iterator over child `Node`s, with shared ownership. 428 | /// 429 | /// # Examples 430 | /// 431 | /// ``` 432 | /// use trees::{RcNode, tr}; 433 | /// 434 | /// let root = RcNode::from( tr(0) ); 435 | /// assert_eq!( root.iter_rc().next(), None ); 436 | /// 437 | /// let root = RcNode::from( tr(0) /tr(1)/tr(2) ); 438 | /// let mut iter = root.iter_rc(); 439 | /// assert_eq!( iter.next(), Some( RcNode::from( tr(1) ))); 440 | /// assert_eq!( iter.next(), Some( RcNode::from( tr(2) ))); 441 | /// assert_eq!( iter.next(), None ); 442 | /// ``` 443 | pub fn iter_rc( &self ) -> IterRc { 444 | let node = self.node_borrow(); 445 | if node.has_no_child() { 446 | IterRc::new( None, 0 ) 447 | } else { 448 | IterRc::new( node.front().map( |front| front.non_null() ), node.degree() ) 449 | } 450 | } 451 | 452 | /// Creates a new weak pointer to this node. 453 | pub fn downgrade( &self ) -> WeakNode { 454 | match self { 455 | RcNode::Scattered( ScatteredRcNode( rc )) => WeakNode::Scattered( ScatteredWeakNode( Rc::downgrade( &rc ))), 456 | RcNode::Piled( PiledRcNode( node_vec, index )) => WeakNode::Piled( PiledWeakNode( *node_vec, *index )), 457 | } 458 | } 459 | 460 | /// Converts to a tree which disables reference-counting. 461 | /// 462 | /// # Panics 463 | /// 464 | /// Only root node could be converted, otherwise it panics. 465 | /// 466 | /// # Examples 467 | /// 468 | /// ``` 469 | /// use trees::{RcNode, Tree, tr}; 470 | /// 471 | /// let root = RcNode::from( tr(0) /( tr(1)/tr(2) )); 472 | /// let tree = unsafe{ root.into_tree() }; 473 | /// assert_eq!( tree, tr(0) /( tr(1)/tr(2) )); 474 | /// 475 | /// let root = RcNode::from( Tree::::from_tuple(( 0, (1, 2), ))); 476 | /// let tree = unsafe{ root.into_tree() }; 477 | /// assert_eq!( tree, tr(0) /( tr(1)/tr(2) )); 478 | /// ``` 479 | pub unsafe fn into_tree( self ) -> Tree { 480 | assert!( self.is_root() ); 481 | let tree = Tree::from_node( match &self { 482 | RcNode::Scattered( ScatteredRcNode( rc )) => { 483 | NonNull::new_unchecked( &mut *rc.deref().borrow_mut() as *mut _ ) 484 | }, 485 | RcNode::Piled( PiledRcNode( node_vec, index )) => { 486 | node_vec.as_ref().non_null_node( *index ) 487 | }, 488 | }); 489 | mem::forget( self ); 490 | tree 491 | } 492 | } 493 | 494 | impl RcNode { 495 | /// Clones the node deeply and creates a new tree. 496 | /// 497 | /// # Examples 498 | /// 499 | /// ``` 500 | /// use trees::{RcNode, tr}; 501 | /// 502 | /// let root = RcNode::from( tr(0) /( tr(1)/tr(2) )); 503 | /// let new_tree = root.front().unwrap().deep_clone(); 504 | /// assert_eq!( new_tree, tr(1) /tr(2) ); 505 | /// ``` 506 | pub fn deep_clone( &self ) -> Tree { self.node_borrow().deep_clone() } 507 | } 508 | 509 | impl Extend> for RcNode { 510 | fn extend>>( &mut self, iter: I ) { 511 | for child in iter.into_iter() { 512 | self.node_borrow_mut().push_back( child ); 513 | } 514 | } 515 | } 516 | 517 | impl_debug_display_for_node!( RcNode, iter_rc, data().deref() ); 518 | impl_order_relations_for_node!( RcNode, iter_rc, data().deref() ); 519 | impl_hash_for_node!( RcNode, iter_rc, data().deref() ); 520 | 521 | /// Non-owning reference-counting node which stored scatteredly. 522 | pub struct ScatteredWeakNode( Weak>> ); 523 | 524 | /// Non-owning reference-counting node which stored contiguously. 525 | pub struct PiledWeakNode( NonNull>, usize ); 526 | 527 | /// Non-owning reference-counting node. 528 | pub enum WeakNode { 529 | Scattered( ScatteredWeakNode ), 530 | Piled( PiledWeakNode ), 531 | } 532 | 533 | impl WeakNode { 534 | /// Attempts to upgrade the `WeakNode` a `RcNode`, delaying dropping of the `Node` if successful. 535 | /// Returns None if the `Node` has since been dropped. 536 | pub fn upgrade( &self ) -> Option> { 537 | match self { 538 | WeakNode::Scattered( ScatteredWeakNode( weak )) => 539 | weak.upgrade().map( |rc| RcNode::Scattered( ScatteredRcNode( rc ))), 540 | WeakNode::Piled( PiledWeakNode( node_vec, index )) => unsafe { 541 | let node = node_vec.as_ref().buf.get_unchecked( *index ); 542 | if node.count.get() == 0 { 543 | None 544 | } else { 545 | node.count.incr(); 546 | Some( RcNode::Piled( PiledRcNode( *node_vec, *index ))) 547 | } 548 | }, 549 | } 550 | } 551 | } 552 | 553 | impl Drop for WeakNode { 554 | fn drop( &mut self ) { 555 | if let WeakNode::Piled( PiledWeakNode( node_vec, _ )) = self { 556 | unsafe { 557 | if node_vec.as_ref().ref_cnt.decr() == 0 { 558 | drop( Box::from_raw( node_vec.as_ptr() )); 559 | } 560 | } 561 | } 562 | } 563 | } 564 | 565 | #[cfg( test )] 566 | mod tests { 567 | #[test] 568 | fn rc_works() { 569 | use super::super::{RcNode, tr}; 570 | 571 | let rc_0 = RcNode::from( tr(0) /( tr(1)/tr(2) )); 572 | let rc_1 = rc_0.front().unwrap(); 573 | let rc_2 = rc_1.front().unwrap(); 574 | 575 | *rc_0.data_mut() = 3; 576 | *rc_1.data_mut() = 4; 577 | *rc_2.data_mut() = 5; 578 | assert_eq!( rc_0, RcNode::from( tr(3) /( tr(4)/tr(5) ))); 579 | 580 | { 581 | let rc_4 = rc_0.pop_back().unwrap(); 582 | assert_eq!( rc_4, RcNode::from( tr(4)/tr(5) )); 583 | } 584 | 585 | assert_eq!( *rc_1.data(), 4 ); 586 | assert_eq!( *rc_2.data(), 5 ); 587 | } 588 | } 589 | 590 | #[cfg( miri )] 591 | mod miri_tests { 592 | #[test] fn is_root() { 593 | use crate::{RcNode, tr}; 594 | 595 | let root = RcNode::from( tr(0)/tr(1) ); 596 | assert!( root.is_root() ); 597 | assert!( !root.front().unwrap().is_root() ); 598 | } 599 | 600 | #[test] fn has_no_child() { 601 | use crate::{RcNode, tr}; 602 | 603 | let root = RcNode::from( tr(0)/tr(1) ); 604 | assert!( !root.has_no_child() ); 605 | assert!( root.front().unwrap().has_no_child() ); 606 | } 607 | 608 | #[test] fn degree() { 609 | use crate::{RcNode, Tree}; 610 | 611 | let root = RcNode::from( Tree::::from_tuple(( 0, (1,2,3), (4,5,6), ))); 612 | assert_eq!( root.degree(), 2 ); 613 | } 614 | 615 | #[test] fn node_count() { 616 | use crate::{RcNode, Tree}; 617 | 618 | let root = RcNode::from( Tree::::from_tuple(( 0, (1,2,3), (4,5,6), ))); 619 | assert_eq!( root.node_count(), 7 ); 620 | } 621 | 622 | #[test] fn front() { 623 | use crate::{RcNode, tr}; 624 | 625 | let root = RcNode::from( tr(0)/tr(1)/tr(2) ); 626 | assert_eq!( root.front(), Some( RcNode::from( tr(1) ))); 627 | } 628 | 629 | #[test] fn back() { 630 | use crate::{RcNode, tr}; 631 | 632 | let root = RcNode::from( tr(0)/tr(1)/tr(2) ); 633 | assert_eq!( root.back(), Some( RcNode::from( tr(2) ))); 634 | } 635 | 636 | #[test] fn parent() { 637 | use crate::{RcNode, tr}; 638 | 639 | let root = RcNode::from( tr(0)/tr(1) ); 640 | assert_eq!( root.parent(), None ); 641 | let tr_1 = root.front().unwrap(); 642 | assert_eq!( tr_1.parent(), Some( root )); 643 | } 644 | 645 | #[test] fn push_front() { 646 | use crate::{RcNode, Tree}; 647 | 648 | let root = RcNode::from( Tree::new(0) ); 649 | root.push_front( Tree::new(1) ); 650 | assert_eq!( root.to_string(), "0( 1 )" ); 651 | root.push_front( Tree::new(2) ); 652 | assert_eq!( root.to_string(), "0( 2 1 )" ); 653 | } 654 | 655 | #[test] fn push_back() { 656 | use crate::{RcNode, Tree}; 657 | 658 | let root = RcNode::from( Tree::new(0) ); 659 | root.push_back( Tree::new(1) ); 660 | assert_eq!( root.to_string(), "0( 1 )" ); 661 | root.push_back( Tree::new(2) ); 662 | assert_eq!( root.to_string(), "0( 1 2 )" ); 663 | } 664 | 665 | #[test] fn pop_front() { 666 | use crate::{RcNode, Tree}; 667 | 668 | let root = RcNode::from( Tree::::from_tuple(( 0,1,2 ))); 669 | let front = root.pop_front().unwrap(); 670 | assert_eq!( front, RcNode::from( Tree::new(1) )); 671 | assert_eq!( root.to_string(), "0( 2 )" ); 672 | let front = root.pop_front().unwrap(); 673 | assert_eq!( front, RcNode::from( Tree::new(2) )); 674 | assert_eq!( root.to_string(), "0" ); 675 | } 676 | 677 | #[test] fn pop_back() { 678 | use crate::{RcNode, Tree}; 679 | 680 | let root = RcNode::from( Tree::::from_tuple(( 0,1,2 ))); 681 | let back = root.pop_back().unwrap(); 682 | assert_eq!( back, RcNode::from( Tree::new(2) )); 683 | assert_eq!( root.to_string(), "0( 1 )" ); 684 | let back = root.pop_back().unwrap(); 685 | assert_eq!( back, RcNode::from( Tree::new(1) )); 686 | assert_eq!( root.to_string(), "0" ); 687 | } 688 | 689 | #[test] fn prepend() { 690 | use crate::{Forest, RcNode, Tree}; 691 | 692 | let root = RcNode::from( Tree::::from_tuple(( 0, 1, 2 ))); 693 | let forest = Forest::::from_tuple(( 3, 4 )); 694 | root.prepend( forest ); 695 | assert_eq!( root.to_string(), "0( 3 4 1 2 )" ); 696 | } 697 | 698 | #[test] fn append() { 699 | use crate::{Forest, RcNode, Tree}; 700 | 701 | let root = RcNode::from( Tree::::from_tuple(( 0, 1, 2 ))); 702 | let forest = Forest::::from_tuple(( 3, 4 )); 703 | root.append( forest ); 704 | assert_eq!( root.to_string(), "0( 1 2 3 4 )" ); 705 | } 706 | 707 | #[test] fn insert_prev_sib() { 708 | use crate::{RcNode, tr}; 709 | 710 | let root = RcNode::from( tr(0) /tr(1)/tr(2) ); 711 | for sub in root.iter_rc() { sub.insert_prev_sib( tr(3) ); } 712 | assert_eq!( root.to_string(), "0( 3 1 3 2 )" ); 713 | } 714 | 715 | #[test] fn insert_next_sib() { 716 | use crate::{RcNode, tr}; 717 | 718 | let root = RcNode::from( tr(0) /tr(1)/tr(2) ); 719 | for sub in root.iter_rc() { sub.insert_next_sib( tr(3) ); } 720 | assert_eq!( root.to_string(), "0( 1 3 2 3 )" ); 721 | } 722 | 723 | #[test] fn detach() { 724 | use crate::{RcNode, tr}; 725 | 726 | let root = RcNode::from( tr(0) /tr(1)/tr(2)/tr(3) ); 727 | for sub in root.iter_rc() { sub.detach(); } 728 | assert!( root.has_no_child() ); 729 | } 730 | 731 | #[test] fn iter_rc() { 732 | use crate::{RcNode, tr}; 733 | 734 | let root = RcNode::from( tr(0) ); 735 | assert_eq!( root.iter_rc().next(), None ); 736 | 737 | let root = RcNode::from( tr(0) /tr(1)/tr(2) ); 738 | let mut iter = root.iter_rc(); 739 | assert_eq!( iter.next(), Some( RcNode::from( tr(1) ))); 740 | assert_eq!( iter.next(), Some( RcNode::from( tr(2) ))); 741 | assert_eq!( iter.next(), None ); 742 | } 743 | 744 | #[test] fn into_tree() { 745 | use crate::{RcNode, Tree, tr}; 746 | 747 | let root = RcNode::from( tr(0) /( tr(1)/tr(2) )); 748 | let tree = unsafe{ root.into_tree() }; 749 | assert_eq!( tree, tr(0) /( tr(1)/tr(2) )); 750 | 751 | let root = RcNode::from( Tree::::from_tuple(( 0, (1, 2), ))); 752 | let tree = unsafe{ root.into_tree() }; 753 | assert_eq!( tree, tr(0) /( tr(1)/tr(2) )); 754 | } 755 | 756 | #[test] fn deep_clone() { 757 | use crate::{RcNode, tr}; 758 | 759 | let root = RcNode::from( tr(0) /( tr(1)/tr(2) )); 760 | let new_tree = root.front().unwrap().deep_clone(); 761 | assert_eq!( new_tree, tr(1) /tr(2) ); 762 | } 763 | } 764 | -------------------------------------------------------------------------------- /deps/trees/src/size.rs: -------------------------------------------------------------------------------- 1 | //! size of a tree/forest/node, including degree and descendant node count 2 | 3 | use crate::rust::*; 4 | 5 | /// A struct keeping the node's children count and all its descendants count 6 | /// for resource management purpose. 7 | #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)] 8 | pub struct Size { 9 | pub degree : usize, // count of child nodes 10 | pub descendants : usize, // count of its descendant nodes 11 | } 12 | 13 | impl Add for Size { 14 | type Output = Self; 15 | fn add( self, rhs: Self ) -> Self { Size{ degree: self.degree+rhs.degree, descendants: self.descendants+rhs.descendants }} 16 | } 17 | 18 | impl AddAssign for Size { 19 | fn add_assign( &mut self, rhs: Self ) { 20 | *self = Size{ degree: self.degree+rhs.degree, descendants: self.descendants+rhs.descendants } 21 | } 22 | } 23 | 24 | impl Sub for Size { 25 | type Output = Self; 26 | fn sub( self, rhs: Self ) -> Self { Size{ degree: self.degree-rhs.degree, descendants: self.descendants-rhs.descendants }} 27 | } 28 | 29 | impl SubAssign for Size { 30 | fn sub_assign( &mut self, rhs: Self ) { 31 | *self = Size{ degree: self.degree-rhs.degree, descendants: self.descendants-rhs.descendants } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /deps/trees/src/tree.rs: -------------------------------------------------------------------------------- 1 | //! Composed of a root `Node` and a list of its child `Node`s. 2 | //! 3 | //! 1. Support adding and storing nodes only once on tree creation, in a 4 | //! contiguous memory address. 5 | //! 6 | //! 2. Support adding and storing nodes one by one, in scattered memory 7 | //! allocations. 8 | //! 9 | //! 3. Tuple notations for construction. 10 | //! 11 | //! 4. `tr()`,`-`,`/` notations for construction. 12 | //! 13 | //! 5. Can be converted to `RcNode` which has shared ownership. 14 | 15 | use crate::TupleTree; 16 | 17 | use crate::rust::*; 18 | 19 | use super::{Data, Forest, IterMut, Node, NodeVec, heap}; 20 | 21 | /// Composed of a root `Node` and a list of its child `Node`s. 22 | pub struct Tree{ 23 | pub(crate) root : NonNull>, 24 | pub(crate) mark : PhantomData>, 25 | } 26 | 27 | impl Tree { 28 | /// Creates a `Tree` containing only root node associated with given data. 29 | pub fn new( data: T ) -> Tree { 30 | Tree { 31 | root: heap::make_node( Data::Scattered{ data, owner: NonNull::dangling() }), 32 | mark: PhantomData, 33 | } 34 | } 35 | 36 | /// Constructs tree from tuple notations. 37 | /// 38 | /// # Examples 39 | /// 40 | /// ``` 41 | /// use trees::{Tree, tr}; 42 | /// 43 | /// let tree = Tree::::from_tuple(( 0, (1,2), (3,4) )); 44 | /// assert_eq!( tree, tr(0) /(tr(1)/tr(2)) /(tr(3)/tr(4)) ); 45 | /// assert_eq!( tree.to_string(), "0( 1( 2 ) 3( 4 ) )" ); 46 | /// ``` 47 | pub fn from_tuple( tuple: Tuple ) -> Self 48 | where Tuple: TupleTree 49 | { 50 | let node_count = >::SIZE.descendants+1; 51 | let mut node_vec = NodeVec::new_raw_non_null( node_count ); 52 | unsafe{ node_vec.as_mut().construct_tree( tuple )}; 53 | 54 | Tree::from_node( unsafe{ node_vec.as_ref().non_null_node(0) }) 55 | } 56 | 57 | pub(crate) fn into_data( mut self ) -> T { 58 | let value = self.root_mut_().data.replace( Data::None ).into_inner(); 59 | mem::forget( self ); 60 | value 61 | } 62 | 63 | pub(crate) fn from_node( mut root: NonNull> ) -> Tree { 64 | unsafe{ root.as_mut().up = None; } 65 | Tree{ root, mark: PhantomData } 66 | } 67 | 68 | /// Reference of the root node. 69 | pub fn root( &self ) -> &Node { unsafe{ &*self.root.as_ptr() }} 70 | 71 | /// Mutable reference of the root node. 72 | pub fn root_mut( &mut self ) -> Pin<&mut Node> { unsafe{ Pin::new_unchecked( self.root_mut_() )}} 73 | 74 | pub(crate) fn root_mut_( &mut self ) -> &mut Node { unsafe{ &mut *self.root.as_ptr() }} 75 | 76 | /// Provides a forward iterator over child `Node`s with mutable references. 77 | /// 78 | /// # Examples 79 | /// 80 | /// ``` 81 | /// use trees::Tree; 82 | /// 83 | /// let mut tree = Tree::::from_tuple(( 0, 1, 2, 3 )); 84 | /// tree.iter_mut().for_each( |mut child| *child.data_mut() *= 10 ); 85 | /// assert_eq!( tree.to_string(), "0( 10 20 30 )" ); 86 | /// ``` 87 | pub fn iter_mut<'a, 's:'a>( &'s mut self ) -> IterMut<'a,T> { self.root_mut_().iter_mut() } 88 | 89 | /// Adds the tree as the first child. 90 | /// 91 | /// # Examples 92 | /// 93 | /// ``` 94 | /// use trees::Tree; 95 | /// let mut tree = Tree::new(0); 96 | /// tree.push_front( Tree::new(1) ); 97 | /// assert_eq!( tree.to_string(), "0( 1 )" ); 98 | /// tree.push_front( Tree::new(2) ); 99 | /// assert_eq!( tree.to_string(), "0( 2 1 )" ); 100 | /// ``` 101 | pub fn push_front( &mut self, tree: Tree ) { 102 | self.root_mut_().push_front( tree ); 103 | } 104 | 105 | /// Adds the tree as the last child. 106 | /// 107 | /// # Examples 108 | /// 109 | /// ``` 110 | /// use trees::Tree; 111 | /// let mut tree = Tree::new(0); 112 | /// tree.push_back( Tree::new(1) ); 113 | /// assert_eq!( tree.to_string(), "0( 1 )" ); 114 | /// tree.push_back( Tree::new(2) ); 115 | /// assert_eq!( tree.to_string(), "0( 1 2 )" ); 116 | /// ``` 117 | pub fn push_back( &mut self, tree: Tree ) { 118 | self.root_mut_().push_back( tree ); 119 | } 120 | 121 | /// Adds all the forest's trees at front of children list. 122 | /// 123 | /// # Examples 124 | /// 125 | /// ``` 126 | /// use trees::{Forest, Tree}; 127 | /// 128 | /// let mut tree = Tree::new(0); 129 | /// tree.push_back( Tree::new(1) ); 130 | /// tree.push_back( Tree::new(2) ); 131 | /// let mut forest = Forest::new(); 132 | /// forest.push_back( Tree::new(3) ); 133 | /// forest.push_back( Tree::new(4) ); 134 | /// tree.prepend( forest ); 135 | /// assert_eq!( tree.to_string(), "0( 3 4 1 2 )" ); 136 | /// ``` 137 | pub fn prepend( &mut self, forest: Forest ) { 138 | self.root_mut_().prepend( forest ); 139 | } 140 | 141 | /// Adds all the forest's trees at back of children list. 142 | /// 143 | /// # Examples 144 | /// 145 | /// ``` 146 | /// use trees::{Forest, Tree}; 147 | /// 148 | /// let mut tree = Tree::new(0); 149 | /// tree.push_back( Tree::new(1) ); 150 | /// tree.push_back( Tree::new(2) ); 151 | /// let mut forest = Forest::new(); 152 | /// forest.push_back( Tree::new(3) ); 153 | /// forest.push_back( Tree::new(4) ); 154 | /// tree.root_mut().append( forest ); 155 | /// assert_eq!( tree.to_string(), "0( 1 2 3 4 )" ); 156 | /// ``` 157 | pub fn append( &mut self, forest: Forest ) { 158 | self.root_mut_().append( forest ); 159 | } 160 | 161 | /// Removes and returns the given `Tree`'s children. 162 | /// 163 | /// # Examples 164 | /// 165 | /// ``` 166 | /// use trees::{Forest, Tree}; 167 | /// 168 | /// let mut tree = Tree::new(0); 169 | /// tree.push_back( Tree::new(1) ); 170 | /// tree.push_back( Tree::new(2) ); 171 | /// let forest = tree.abandon(); 172 | /// assert_eq!( forest.to_string(), "( 1 2 )" ); 173 | /// assert_eq!( tree, Tree::new(0) ); 174 | /// ``` 175 | pub fn abandon( &mut self ) -> Forest { 176 | let new_root = heap::make_node( Data::Scattered{ 177 | data : self.root_mut_().data.take(), 178 | owner : NonNull::dangling(), 179 | }); 180 | let forest = Forest::from_node( self.root ); 181 | self.root = new_root; 182 | forest 183 | } 184 | 185 | /// Removes and returns the first child. 186 | /// 187 | /// # Examples 188 | /// 189 | /// ``` 190 | /// use trees::Tree; 191 | /// 192 | /// let mut tree = Tree::new(0); 193 | /// tree.push_back( Tree::new(1) ); 194 | /// tree.push_back( Tree::new(2) ); 195 | /// assert_eq!( tree.to_string(), "0( 1 2 )" ); 196 | /// assert_eq!( tree.pop_front(), Some( Tree::new(1) )); 197 | /// assert_eq!( tree.to_string(), "0( 2 )" ); 198 | /// assert_eq!( tree.pop_front(), Some( Tree::new(2) )); 199 | /// assert_eq!( tree.to_string(), "0" ); 200 | /// assert_eq!( tree.pop_front(), None ); 201 | /// ``` 202 | pub fn pop_front( &mut self ) -> Option> { self.root_mut_().pop_front() } 203 | 204 | /// Removes and returns the last child. 205 | /// 206 | /// # Examples 207 | /// 208 | /// ``` 209 | /// use trees::Tree; 210 | /// 211 | /// let mut tree = Tree::new(0); 212 | /// tree.push_back( Tree::new(1) ); 213 | /// tree.push_back( Tree::new(2) ); 214 | /// assert_eq!( tree.to_string(), "0( 1 2 )" ); 215 | /// assert_eq!( tree.pop_back(), Some( Tree::new(2) )); 216 | /// assert_eq!( tree.to_string(), "0( 1 )" ); 217 | /// assert_eq!( tree.pop_back(), Some( Tree::new(1) )); 218 | /// assert_eq!( tree.to_string(), "0" ); 219 | /// assert_eq!( tree.pop_back(), None ); 220 | /// ``` 221 | pub fn pop_back( &mut self ) -> Option> { self.root_mut_().pop_back() } 222 | 223 | /// Returns a mutable reference to the first child of this node, 224 | /// or None if it has no child. 225 | pub fn front_mut( &mut self ) -> Option>> { self.root_mut_().front_mut() } 226 | 227 | /// Returns a mutable reference to the last child of this node, 228 | /// or None if it has no child. 229 | pub fn back_mut( &mut self ) -> Option>> { self.root_mut_().back_mut() } 230 | } 231 | 232 | impl Clone for Tree { 233 | fn clone( &self ) -> Self { 234 | self.root().deep_clone() 235 | } 236 | } 237 | 238 | impl Deref for Tree { 239 | type Target = Node; 240 | 241 | fn deref( &self ) -> &Self::Target { self.root() } 242 | } 243 | 244 | impl Drop for Tree { 245 | fn drop( &mut self ) { 246 | while let Some(_) = self.root_mut_().pop_front() {} 247 | heap::drop_node( self.root ); 248 | } 249 | } 250 | 251 | impl_debug_display_for_collection!( Tree, root() ); 252 | impl_order_relations_for_collection!( Tree, root() ); 253 | impl_hash_for_collection!( Tree, root() ); 254 | 255 | #[cfg( test )] 256 | mod tests { 257 | use super::*; 258 | 259 | #[test] fn piled_tree_from_tuple() { 260 | let tuple = ( 0, (1,2,3), (4,5,6) ); 261 | let piled = Tree::::from_tuple( tuple ); 262 | assert_eq!( piled.to_string(), "0( 1( 2 3 ) 4( 5 6 ) )" ); 263 | } 264 | } 265 | 266 | #[cfg( miri )] 267 | mod miri_tests { 268 | #[test] fn iter_mut() { 269 | use crate::Tree; 270 | 271 | let mut tree = Tree::::from_tuple(( 0, 1, 2, 3 )); 272 | tree.iter_mut().for_each( |mut child| *child.data_mut() *= 10 ); 273 | assert_eq!( tree.to_string(), "0( 10 20 30 )" ); 274 | } 275 | 276 | #[test] fn push_front() { 277 | use crate::Tree; 278 | 279 | let mut tree = Tree::new(0); 280 | tree.push_front( Tree::new(1) ); 281 | assert_eq!( tree.to_string(), "0( 1 )" ); 282 | tree.push_front( Tree::new(2) ); 283 | assert_eq!( tree.to_string(), "0( 2 1 )" ); 284 | } 285 | 286 | #[test] fn push_back() { 287 | use crate::Tree; 288 | 289 | let mut tree = Tree::new(0); 290 | tree.push_back( Tree::new(1) ); 291 | assert_eq!( tree.to_string(), "0( 1 )" ); 292 | tree.push_back( Tree::new(2) ); 293 | assert_eq!( tree.to_string(), "0( 1 2 )" ); 294 | } 295 | 296 | #[test] fn prepend() { 297 | use crate::{Forest, Tree}; 298 | 299 | let mut tree = Tree::new(0); 300 | tree.push_back( Tree::new(1) ); 301 | tree.push_back( Tree::new(2) ); 302 | let mut forest = Forest::new(); 303 | forest.push_back( Tree::new(3) ); 304 | forest.push_back( Tree::new(4) ); 305 | tree.prepend( forest ); 306 | assert_eq!( tree.to_string(), "0( 3 4 1 2 )" ); 307 | } 308 | 309 | #[test] fn append() { 310 | use crate::{Forest, Tree}; 311 | 312 | let mut tree = Tree::new(0); 313 | tree.push_back( Tree::new(1) ); 314 | tree.push_back( Tree::new(2) ); 315 | let mut forest = Forest::new(); 316 | forest.push_back( Tree::new(3) ); 317 | forest.push_back( Tree::new(4) ); 318 | tree.root_mut().append( forest ); 319 | assert_eq!( tree.to_string(), "0( 1 2 3 4 )" ); 320 | } 321 | 322 | #[test] fn abandon() { 323 | use crate::Tree; 324 | 325 | let mut tree = Tree::new(0); 326 | tree.push_back( Tree::new(1) ); 327 | tree.push_back( Tree::new(2) ); 328 | let forest = tree.abandon(); 329 | assert_eq!( forest.to_string(), "( 1 2 )" ); 330 | assert_eq!( tree, Tree::new(0) ); 331 | } 332 | 333 | #[test] fn pop_front() { 334 | use crate::Tree; 335 | 336 | let mut tree = Tree::new(0); 337 | tree.push_back( Tree::new(1) ); 338 | tree.push_back( Tree::new(2) ); 339 | assert_eq!( tree.to_string(), "0( 1 2 )" ); 340 | assert_eq!( tree.pop_front(), Some( Tree::new(1) )); 341 | assert_eq!( tree.to_string(), "0( 2 )" ); 342 | assert_eq!( tree.pop_front(), Some( Tree::new(2) )); 343 | assert_eq!( tree.to_string(), "0" ); 344 | assert_eq!( tree.pop_front(), None ); 345 | } 346 | 347 | #[test] fn pop_back() { 348 | use crate::Tree; 349 | 350 | let mut tree = Tree::new(0); 351 | tree.push_back( Tree::new(1) ); 352 | tree.push_back( Tree::new(2) ); 353 | assert_eq!( tree.to_string(), "0( 1 2 )" ); 354 | assert_eq!( tree.pop_back(), Some( Tree::new(2) )); 355 | assert_eq!( tree.to_string(), "0( 1 )" ); 356 | assert_eq!( tree.pop_back(), Some( Tree::new(1) )); 357 | assert_eq!( tree.to_string(), "0" ); 358 | assert_eq!( tree.pop_back(), None ); 359 | } 360 | #[test] fn from_tuple() { 361 | use crate::{Tree, tr}; 362 | 363 | let tree = Tree::::from_tuple(( 0, (1,2), (3,4) )); 364 | assert_eq!( tree, tr(0) /(tr(1)/tr(2)) /(tr(3)/tr(4)) ); 365 | assert_eq!( tree.to_string(), "0( 1( 2 ) 3( 4 ) )" ); 366 | } 367 | } 368 | -------------------------------------------------------------------------------- /deps/trees/src/tuple.rs: -------------------------------------------------------------------------------- 1 | //! Traits for implementing tuple notations 2 | 3 | use crate::Size; 4 | 5 | use crate::rust::*; 6 | 7 | /// Visit one node in tree/forest building process, using tuple notations. 8 | #[derive( Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash )] 9 | pub enum Visit { 10 | Branch( T ), 11 | Leaf( T ), 12 | Frame, 13 | } 14 | 15 | /// For tuple notations to construct `Tree`. 16 | pub trait TupleTree: Sized { 17 | const SIZE: Size; 18 | fn descendants( indirect_level: usize ) -> usize; 19 | fn height() -> usize; 20 | fn preorder( self, f: &mut impl FnMut( Visit )); 21 | fn preorder_with_size_hint( self, f: &mut impl FnMut( Visit, Size )); 22 | fn postorder( self, f: &mut impl FnMut( Visit )); 23 | fn postorder_with_size_hint( self, f: &mut impl FnMut( Visit, Size )); 24 | } 25 | 26 | impl TupleTree for T { 27 | const SIZE: Size = Size{ degree: 0, descendants: 0 }; 28 | fn descendants( _indirect_level: usize ) -> usize { 0 } 29 | fn height() -> usize { 1 } 30 | 31 | fn preorder( self, f: &mut impl FnMut( Visit ) ) { 32 | f( Visit::Leaf( self )); 33 | } 34 | 35 | fn preorder_with_size_hint( self, f: &mut impl FnMut( Visit, Size )) { 36 | f( Visit::Leaf( self ), Size::default() ); 37 | } 38 | 39 | fn postorder( self, f: &mut impl FnMut( Visit ) ) { 40 | f( Visit::Leaf( self )); 41 | } 42 | 43 | fn postorder_with_size_hint( self, f: &mut impl FnMut( Visit, Size )) { 44 | f( Visit::Leaf( self ), Size::default() ); 45 | } 46 | } 47 | 48 | macro_rules! impl_tuple_tree { 49 | ($len:expr => ($($n:tt $name:ident $shape:ident)*)) => { 50 | impl TupleTree for (T,$($name,)*) 51 | where T: TupleTree $(,$name: TupleTree)* 52 | { 53 | const SIZE: Size = Size { 54 | degree : $len, 55 | descendants: 0 $(+ <$name as TupleTree>::SIZE.descendants+1 )*, 56 | }; 57 | 58 | fn descendants( indirect_level: usize ) -> usize { 59 | if indirect_level == 0 { 60 | $len 61 | } else { 62 | 0 $( + <$name as TupleTree>::descendants( indirect_level-1 ) )* 63 | } 64 | } 65 | 66 | fn height() -> usize { 67 | 1 + *[ 0 $(, <$name as TupleTree>::height() )* ].iter().max_by( |x,y| x.cmp(y) ).unwrap() 68 | } 69 | 70 | fn preorder( self, f: &mut impl FnMut( Visit ) ) { 71 | if >::SIZE.degree == 0 { 72 | f( Visit::Leaf( self.0 )); 73 | } else { 74 | f( Visit::Branch( self.0 )); 75 | $( (self.$n).preorder( f ); )* 76 | f( Visit::Frame ); 77 | } 78 | } 79 | 80 | fn preorder_with_size_hint( self, f: &mut impl FnMut( Visit, Size )) { 81 | let size = >::SIZE; 82 | if size.degree == 0 { 83 | f( Visit::Leaf( self.0 ), size ); 84 | } else { 85 | f( Visit::Branch( self.0 ), size ); 86 | $( (self.$n).preorder_with_size_hint( f ); )* 87 | f( Visit::Frame, size ); 88 | } 89 | } 90 | 91 | fn postorder( self, f: &mut impl FnMut( Visit ) ) { 92 | if >::SIZE.degree == 0 { 93 | f( Visit::Leaf( self.0 )); 94 | } else { 95 | f( Visit::Frame ); 96 | $( (self.$n).postorder( f ); )* 97 | f( Visit::Branch( self.0 )); 98 | } 99 | } 100 | 101 | fn postorder_with_size_hint( self, f: &mut impl FnMut( Visit, Size )) { 102 | let size = >::SIZE; 103 | if size.degree == 0 { 104 | f( Visit::Leaf( self.0 ), size ); 105 | } else { 106 | f( Visit::Branch( self.0 ), size ); 107 | $( (self.$n).postorder_with_size_hint( f ); )* 108 | f( Visit::Frame, size ); 109 | } 110 | } 111 | } 112 | } 113 | } 114 | 115 | /// For tuple notations to construct `Forest`. 116 | pub trait TupleForest: Sized { 117 | const SIZE: Size; 118 | fn descendants( indirect_level: usize ) -> usize; 119 | fn height() -> usize; 120 | fn preorder( self, f: &mut impl FnMut( Visit )); 121 | fn preorder_with_size_hint( self, f: &mut impl FnMut( Visit, Size )); 122 | fn postorder( self, f: &mut impl FnMut( Visit )); 123 | fn postorder_with_size_hint( self, f: &mut impl FnMut( Visit, Size )); 124 | } 125 | 126 | macro_rules! impl_tuple_forest { 127 | ($len:expr => ($($n:tt $name:ident $shape:ident)*)) => { 128 | impl TupleForest for ($($name,)*) 129 | where T: TupleTree $(,$name: TupleTree)* 130 | { 131 | const SIZE: Size = Size { 132 | degree : $len, 133 | descendants: 0 $(+ <$name as TupleTree>::SIZE.descendants+1 )*, 134 | }; 135 | 136 | fn descendants( indirect_level: usize ) -> usize { 137 | if indirect_level == 0 { 138 | $len 139 | } else { 140 | 0 $( + <$name as TupleTree>::descendants( indirect_level-1 ) )* 141 | } 142 | } 143 | 144 | fn height() -> usize { 145 | 0 + *[ 0 $(, <$name as TupleTree>::height() )* ].iter().max_by( |x,y| x.cmp(y) ).unwrap() 146 | } 147 | 148 | fn preorder( self, _f: &mut impl FnMut( Visit ) ) { 149 | $( (self.$n).preorder( _f ); )* 150 | } 151 | 152 | fn preorder_with_size_hint( self, _f: &mut impl FnMut( Visit, Size )) { 153 | $( (self.$n).preorder_with_size_hint( _f ); )* 154 | } 155 | 156 | fn postorder( self, _f: &mut impl FnMut( Visit ) ) { 157 | $( (self.$n).postorder( _f ); )* 158 | } 159 | 160 | fn postorder_with_size_hint( self, _f: &mut impl FnMut( Visit, Size )) { 161 | $( (self.$n).postorder_with_size_hint( _f ); )* 162 | } 163 | } 164 | } 165 | } 166 | 167 | macro_rules! tuple_tree_impls { 168 | ($($len:expr => ($($n:tt $name:ident $shape:ident)*))+) => {$( 169 | impl_tuple_tree!( $len => ($($n $name $shape)*) ); 170 | )+}; 171 | } 172 | 173 | tuple_tree_impls! { 174 | 0 => () 175 | 1 => (1 T1 S1) 176 | 2 => (1 T1 S1 2 T2 S2) 177 | 3 => (1 T1 S1 2 T2 S2 3 T3 S3) 178 | 4 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4) 179 | 5 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5) 180 | 6 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6) 181 | 7 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7) 182 | 8 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8) 183 | 9 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9) 184 | 10 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10) 185 | 11 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11) 186 | 12 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12) 187 | 13 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13) 188 | 14 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14) 189 | 15 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15) 190 | 16 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16) 191 | 17 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17) 192 | 18 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18) 193 | 19 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19) 194 | 20 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20) 195 | 21 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21) 196 | 22 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22) 197 | 23 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22 23 T23 S23) 198 | 24 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22 23 T23 S23 24 T24 S24) 199 | 25 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22 23 T23 S23 24 T24 S24 25 T25 S25) 200 | 26 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22 23 T23 S23 24 T24 S24 25 T25 S25 26 T26 S26) 201 | 27 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22 23 T23 S23 24 T24 S24 25 T25 S25 26 T26 S26 27 T27 S27) 202 | 28 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22 23 T23 S23 24 T24 S24 25 T25 S25 26 T26 S26 27 T27 S27 28 T28 S28) 203 | 29 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22 23 T23 S23 24 T24 S24 25 T25 S25 26 T26 S26 27 T27 S27 28 T28 S28 29 T29 S29) 204 | 30 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22 23 T23 S23 24 T24 S24 25 T25 S25 26 T26 S26 27 T27 S27 28 T28 S28 29 T29 S29 30 T30 S30) 205 | 31 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22 23 T23 S23 24 T24 S24 25 T25 S25 26 T26 S26 27 T27 S27 28 T28 S28 29 T29 S29 30 T30 S30 31 T31 S31) 206 | 32 => (1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22 23 T23 S23 24 T24 S24 25 T25 S25 26 T26 S26 27 T27 S27 28 T28 S28 29 T29 S29 30 T30 S30 31 T31 S31 32 T32 S32) 207 | } 208 | 209 | macro_rules! tuple_forest_impls { 210 | ($($len:expr => ($($n:tt $name:ident $shape:ident)*))+) => {$( 211 | impl_tuple_forest!( $len => ($($n $name $shape)*) ); 212 | )+}; 213 | } 214 | 215 | tuple_forest_impls! { 216 | 0 => () 217 | 1 => (0 T0 S0) 218 | 2 => (0 T0 S0 1 T1 S1) 219 | 3 => (0 T0 S0 1 T1 S1 2 T2 S2) 220 | 4 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3) 221 | 5 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4) 222 | 6 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5) 223 | 7 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6) 224 | 8 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7) 225 | 9 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8) 226 | 10 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9) 227 | 11 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10) 228 | 12 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11) 229 | 13 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12) 230 | 14 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13) 231 | 15 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14) 232 | 16 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15) 233 | 17 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16) 234 | 18 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17) 235 | 19 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18) 236 | 20 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19) 237 | 21 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20) 238 | 22 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21) 239 | 23 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22) 240 | 24 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22 23 T23 S23) 241 | 25 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22 23 T23 S23 24 T24 S24) 242 | 26 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22 23 T23 S23 24 T24 S24 25 T25 S25) 243 | 27 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22 23 T23 S23 24 T24 S24 25 T25 S25 26 T26 S26) 244 | 28 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22 23 T23 S23 24 T24 S24 25 T25 S25 26 T26 S26 27 T27 S27) 245 | 29 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22 23 T23 S23 24 T24 S24 25 T25 S25 26 T26 S26 27 T27 S27 28 T28 S28) 246 | 30 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22 23 T23 S23 24 T24 S24 25 T25 S25 26 T26 S26 27 T27 S27 28 T28 S28 29 T29 S29) 247 | 31 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22 23 T23 S23 24 T24 S24 25 T25 S25 26 T26 S26 27 T27 S27 28 T28 S28 29 T29 S29 30 T30 S30) 248 | 32 => (0 T0 S0 1 T1 S1 2 T2 S2 3 T3 S3 4 T4 S4 5 T5 S5 6 T6 S6 7 T7 S7 8 T8 S8 9 T9 S9 10 T10 S10 11 T11 S11 12 T12 S12 13 T13 S13 14 T14 S14 15 T15 S15 16 T16 S16 17 T17 S17 18 T18 S18 19 T19 S19 20 T20 S20 21 T21 S21 22 T22 S22 23 T23 S23 24 T24 S24 25 T25 S25 26 T26 S26 27 T27 S27 28 T28 S28 29 T29 S29 30 T30 S30 31 T31 S31) 249 | } 250 | 251 | #[cfg( test )] 252 | mod tests { 253 | use super::*; 254 | 255 | #[test] 256 | fn tree_preorder() { 257 | let mut visits = Vec::new(); 258 | let tree = (0, (1,3,4), (2,5,6), ); 259 | TupleTree::::preorder( tree, &mut |visit| visits.push( visit )); 260 | assert_eq!( visits, vec![ 261 | Visit::Branch(0), 262 | Visit::Branch(1), 263 | Visit::Leaf(3), 264 | Visit::Leaf(4), 265 | Visit::Frame, 266 | Visit::Branch(2), 267 | Visit::Leaf(5), 268 | Visit::Leaf(6), 269 | Visit::Frame, 270 | Visit::Frame, 271 | ]); 272 | } 273 | 274 | #[test] 275 | fn forest_preorder() { 276 | let mut visits = Vec::new(); 277 | let forest = ( (1,3,4), (2,5,6), ); 278 | TupleForest::::preorder( forest, &mut |visit| visits.push( visit )); 279 | assert_eq!( visits, vec![ 280 | Visit::Branch(1), 281 | Visit::Leaf(3), 282 | Visit::Leaf(4), 283 | Visit::Frame, 284 | Visit::Branch(2), 285 | Visit::Leaf(5), 286 | Visit::Leaf(6), 287 | Visit::Frame, 288 | ]); 289 | } 290 | #[test] 291 | fn tree_postorder() { 292 | let mut visits = Vec::new(); 293 | let tree = (0, (1,3,4), (2,5,6), ); 294 | TupleTree::::postorder( tree, &mut |visit| visits.push( visit )); 295 | assert_eq!( visits, vec![ 296 | Visit::Frame, 297 | Visit::Frame, 298 | Visit::Leaf(3), 299 | Visit::Leaf(4), 300 | Visit::Branch(1), 301 | Visit::Frame, 302 | Visit::Leaf(5), 303 | Visit::Leaf(6), 304 | Visit::Branch(2), 305 | Visit::Branch(0), 306 | ]); 307 | } 308 | 309 | #[test] 310 | fn forest_postorder() { 311 | let mut visits = Vec::new(); 312 | let forest = ( (1,3,4), (2,5,6), ); 313 | TupleForest::::postorder( forest, &mut |visit| visits.push( visit )); 314 | assert_eq!( visits, vec![ 315 | Visit::Frame, 316 | Visit::Leaf(3), 317 | Visit::Leaf(4), 318 | Visit::Branch(1), 319 | Visit::Frame, 320 | Visit::Leaf(5), 321 | Visit::Leaf(6), 322 | Visit::Branch(2), 323 | ]); 324 | } 325 | } 326 | -------------------------------------------------------------------------------- /docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Auth query entrypoint script, Switch redis mode by $1 4 | 5 | 6 | err() { 7 | echo -e "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" >&2 8 | } 9 | 10 | info() { 11 | echo -e "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" 12 | } 13 | 14 | function check_single_env() { 15 | info 'redis will start with single mode...' 16 | info "redis on port 6379" 17 | } 18 | 19 | # 和单点没有区别 20 | function check_master_env() { 21 | if [[ -z "${REDIS_PORT}" ]]; then 22 | REDIS_PORT=6379 23 | fi 24 | sed -i 's/^\(port .*\)$/# \1/' /etc/redis/redis.conf 25 | echo -e "\nport $REDIS_PORT" >> /etc/redis/redis.conf 26 | 27 | info "redis will start with master mode..." 28 | info "redis on port $REDIS_PORT" 29 | } 30 | 31 | function check_slave_env() { 32 | if [[ -z "${REDIS_PORT}" ]]; then 33 | REDIS_PORT=6379 34 | fi 35 | sed -i 's/^\(port .*\)$/# \1/' /etc/redis/redis.conf 36 | echo -e "\nport $REDIS_PORT" >> /etc/redis/redis.conf 37 | 38 | if [[ -z "${MASTER_IP}" ]]; then 39 | err "you must provide mater ip" 40 | exit 1 41 | fi 42 | 43 | if [[ -z "${MASTER_PORT}" ]]; then 44 | err "master port set 6379" 45 | MASTER_PORT=6379 46 | fi 47 | 48 | sed -i 's/^\(slaveof .*\)$/# \1/' /etc/redis/redis.conf 49 | echo -e "\nslaveof $MASTER_IP $MASTER_PORT" >> /etc/redis/redis.conf 50 | 51 | if [[ -n "${MASTER_USER}" ]]; then 52 | sed -i 's/^\(masteruser .*\)$/# \1/' /etc/redis/redis.conf 53 | echo -e "\nmasteruser $MASTER_USER" >> /etc/redis/redis.conf 54 | fi 55 | 56 | if [[ -n "${MASTER_PASS}" ]]; then 57 | sed -i 's/^\(masterauth .*\)$/# \1/' /etc/redis/redis.conf 58 | echo -e "\nmasterauth $MASTER_PASS" >> /etc/redis/redis.conf 59 | fi 60 | 61 | info "redis will start with slave mode, master is $MASTER_IP:$MASTER_PORT" 62 | info "redis on port $REDIS_PORT" 63 | } 64 | 65 | function check_sentinel_env() { 66 | if [[ -z "${REDIS_PORT}" ]]; then 67 | REDIS_PORT=26379 68 | fi 69 | sed -i 's/^\(port .*\)$/# \1/' /etc/redis/sentinel.conf 70 | echo -e "\nport $REDIS_PORT" >> /etc/redis/sentinel.conf 71 | 72 | if [[ -z "${MASTER_IP}" ]]; then 73 | err "you must provide mater ip" 74 | exit 1 75 | fi 76 | 77 | if [[ -z "${MASTER_PORT}" ]]; then 78 | err "master port set 6379" 79 | MASTER_PORT=6379 80 | fi 81 | 82 | sed -i 's/^\(sentinel monitor mymaster.*\)$/# \1/' /etc/redis/sentinel.conf 83 | echo -e "\nsentinel monitor mymaster $MASTER_IP $MASTER_PORT 2" >> /etc/redis/sentinel.conf 84 | 85 | if [[ -n "${MASTER_USER}" ]]; then 86 | sed -i 's/^\(sentinel auth-user mymaster .*\)$/# \1/' /etc/redis/sentinel.conf 87 | echo -e "\nsentinel auth-user mymaster $MASTER_USER" >> /etc/redis/sentinel.conf 88 | fi 89 | 90 | if [[ -n "${MASTER_PASS}" ]]; then 91 | sed -i 's/^\(sentinel auth-pass mymaster .*\)$/# \1/' /etc/redis/sentinel.conf 92 | echo -e "\nsentinel auth-pass mymaster $MASTER_PASS" >> /etc/redis/sentinel.conf 93 | fi 94 | 95 | info "redis will start with sentinel mode, master is $MASTER_IP:$MASTER_PORT" 96 | info "redis on port $REDIS_PORT" 97 | } 98 | 99 | # shellcheck disable=SC1009 100 | if [[ $1 == 'single' ]]; then 101 | check_single_env 102 | redis-server /etc/redis/redis.conf --loadmodule /usr/lib/redis/modules/retree.so /usr/lib/redis/modules/fdauth.so 103 | exit 1 104 | elif [[ $1 == 'master' ]]; then 105 | check_master_env 106 | redis-server /etc/redis/redis.conf --loadmodule /usr/lib/redis/modules/retree.so /usr/lib/redis/modules/fdauth.so 107 | exit 1 108 | elif [[ $1 == 'slave' ]]; then 109 | check_slave_env 110 | redis-server /etc/redis/redis.conf --loadmodule /usr/lib/redis/modules/retree.so /usr/lib/redis/modules/fdauth.so 111 | exit 1 112 | elif [[ $1 == 'sentinel' ]]; then 113 | check_sentinel_env 114 | redis-server /etc/redis/sentinel.conf --loadmodule /usr/lib/redis/modules/retree.so /usr/lib/redis/modules/fdauth.so --sentinel 115 | exit 1 116 | fi 117 | 118 | exec "$@" -------------------------------------------------------------------------------- /redis.conf: -------------------------------------------------------------------------------- 1 | bind 0.0.0.0 2 | protected-mode no 3 | tcp-backlog 511 4 | tcp-keepalive 300 5 | timeout 0 6 | always-show-logo no 7 | 8 | # bgsave 9 | appendonly no 10 | stop-writes-on-bgsave-error yes 11 | rdbcompression yes 12 | dbfilename dump.rdb 13 | dir /data 14 | #save "" 15 | save 900 1 16 | save 60 10000 17 | 18 | aclfile /etc/redis/acl.file 19 | 20 | maxmemory 1G 21 | maxmemory-policy volatile-lru 22 | 23 | # need to replace 24 | masterauth for123deal 25 | masteruser ops 26 | port 6379 27 | -------------------------------------------------------------------------------- /sentinel.conf: -------------------------------------------------------------------------------- 1 | protected-mode no 2 | daemonize no 3 | sentinel deny-scripts-reconfig yes 4 | dir /data 5 | logfile /data/sentinel.log 6 | sentinel down-after-milliseconds mymaster 1000 7 | sentinel failover-timeout mymaster 60000 8 | 9 | port 26379 10 | sentinel monitor mymaster masterip 6379 2 11 | sentinel auth-pass mymaster xxxxxxx 12 | sentinel auth-user mymaster penzai 13 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate redis_module; 3 | 4 | use redis_module::native_types::RedisType; 5 | use redis_module::{raw, Context, NextArg, RedisResult, RedisValue, RedisString, REDIS_OK}; 6 | use redis_module::logging::{log as redis_log}; 7 | use redis_module::LogLevel; 8 | use std::os::raw::{c_void, c_int, c_char}; 9 | use std::ptr; 10 | use std::ffi::{CStr, CString}; 11 | use trees::*; 12 | use std::convert::TryFrom; 13 | 14 | 15 | // ================================================================================================= 16 | // LOG 17 | // ================================================================================================= 18 | fn log(message: &str) { 19 | let mut info = "tree: ".to_string(); 20 | info.push_str(message); 21 | redis_log(LogLevel::Warning, &info) 22 | } 23 | 24 | 25 | #[derive(Debug)] 26 | pub struct Error { 27 | pub msg: String, 28 | } 29 | 30 | impl From for Error { 31 | fn from(e: String) -> Self { 32 | Error { msg: e } 33 | } 34 | } 35 | 36 | impl From<&str> for Error { 37 | fn from(e: &str) -> Self { 38 | Error { msg: e.to_string() } 39 | } 40 | } 41 | 42 | impl From for redis_module::RedisError { 43 | fn from(e: Error) -> Self { 44 | redis_module::RedisError::String(e.msg) 45 | } 46 | } 47 | 48 | 49 | use std::collections::HashMap; 50 | 51 | #[derive(Debug)] 52 | struct RedisTreeType { 53 | data: Tree, 54 | // map: HashMap 55 | } 56 | 57 | impl RedisTreeType { 58 | fn to_string(&self) -> String { 59 | self.data.to_string() 60 | } 61 | } 62 | 63 | 64 | #[allow(non_snake_case, unused)] 65 | pub extern "C" fn init(_: *mut raw::RedisModuleCtx) -> c_int { 66 | raw::Status::Ok as c_int 67 | } 68 | 69 | #[allow(non_snake_case, unused)] 70 | pub unsafe extern "C" fn rdb_load(rdb: *mut raw::RedisModuleIO, encver: c_int) -> *mut c_void { 71 | if let Ok(tree) = Tree::try_from(raw::load_string(rdb)) { 72 | Box::into_raw(Box::new(tree)) as *mut c_void 73 | } else { 74 | Box::into_raw(Box::new(Tree::new("rdb_load_fail"))) as *mut c_void 75 | } 76 | 77 | } 78 | 79 | #[allow(non_snake_case, unused)] 80 | pub unsafe extern "C" fn rdb_save(rdb: *mut raw::RedisModuleIO, value: *mut c_void) { 81 | let tree = (&*(value as *mut Tree)).to_string(); 82 | raw::save_string(rdb, tree.as_str()); 83 | 84 | 85 | // let tree = &*(value as *mut Tree); 86 | // let tree_string = tree.to_string(); 87 | // let c_str = CString::new(tree_string.as_str()).unwrap(); 88 | // raw::RedisModule_SaveStringBuffer.unwrap()(rdb, c_str.as_ptr() as *const c_char, tree_string.len()); 89 | } 90 | 91 | 92 | #[allow(non_snake_case, unused)] 93 | pub unsafe extern "C" fn aof_rewrite(aof: *mut raw::RedisModuleIO, key: *mut raw::RedisModuleString, value: *mut c_void) { 94 | // do nothing 95 | } 96 | 97 | 98 | 99 | #[allow(non_snake_case, unused)] 100 | pub unsafe extern "C" fn free(value: *mut c_void) { 101 | Box::from_raw(value as *mut RedisTreeType); 102 | } 103 | 104 | 105 | #[allow(non_snake_case, unused)] 106 | pub unsafe extern "C" fn aux_load(rdb: *mut raw::RedisModuleIO, encver: i32, when: i32) -> i32 { 107 | raw::Status::Ok as i32 108 | } 109 | 110 | #[allow(non_snake_case, unused)] 111 | pub unsafe extern "C" fn aux_save(rdb: *mut raw::RedisModuleIO, when: i32) { 112 | } 113 | 114 | 115 | static TREE_TYPE: RedisType = RedisType::new( 116 | "ReTreeYou", 117 | 0, 118 | raw::RedisModuleTypeMethods { 119 | version: raw::REDISMODULE_TYPE_METHOD_VERSION as u64, 120 | rdb_load: Some(rdb_load), 121 | rdb_save: Some(rdb_save), 122 | aof_rewrite: None, 123 | free: Some(free), 124 | mem_usage: None, 125 | digest: None, 126 | aux_load: None, 127 | aux_save: None, 128 | aux_save_triggers: 0, 129 | }, 130 | )execution failed error during connect: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.40/containers/he6j1i859tsdcm6s9ukcg8muicl3dxib/json: context canceled {"stage-d": 9095, "rep; 131 | 132 | 133 | 134 | fn init_tree(ctx: &Context, args: Vec) -> RedisResult { 135 | let mut args = args.into_iter().skip(1); 136 | let key = ctx.open_key_writable(&args.next_string()?); 137 | 138 | key.set_value(&TREE_TYPE, Tree::try_from(args.next_string()?)?)?; 139 | REDIS_OK 140 | } 141 | 142 | fn get_tree(ctx: &Context, args: Vec) -> RedisResult { 143 | let mut args = args.into_iter().skip(1); 144 | let key = ctx.open_key(&args.next_string()?); 145 | 146 | let value = match key.get_value::(&TREE_TYPE)? { 147 | Some(value) => value.to_string().into(), 148 | None => RedisValue::Null, 149 | }; 150 | 151 | Ok(value) 152 | } 153 | 154 | fn get_subtree(ctx: &Context, args: Vec) -> RedisResult { 155 | let mut args = args.into_iter().skip(1); 156 | let key = ctx.open_key(&args.next_string()?); 157 | let node_data = args.next_string()?; 158 | 159 | if let Some(value) = key.get_value::(&TREE_TYPE)? { 160 | if let Some(node) = value.data.root().locate_first_by_data(&node_data) { 161 | return Ok(node.to_string().into()) 162 | } 163 | } 164 | Ok(RedisValue::Null) 165 | } 166 | 167 | 168 | fn del_tree(ctx: &Context, args: Vec) -> RedisResult { 169 | let mut args = args.into_iter().skip(1); 170 | let key = ctx.open_key_writable(&args.next_string()?); 171 | 172 | match key.get_value::(&TREE_TYPE)? { 173 | Some(_) => { 174 | key.delete()?; 175 | REDIS_OK 176 | } 177 | None => Ok(RedisValue::Null), 178 | } 179 | } 180 | 181 | fn del_subtree(ctx: &Context, args: Vec) -> RedisResult { 182 | let mut args = args.into_iter().skip(1); 183 | let mut key = ctx.open_key_writable(&args.next_string()?); 184 | let node_data = args.next_string()?; 185 | 186 | 187 | if let Some(mut value) = key.get_value::(&TREE_TYPE)? { 188 | if let Some(mut node) = value.data.root_mut().locate_first_mut_by_data(&node_data) { 189 | return Ok(node.detach().to_string().into()) 190 | } 191 | } 192 | Ok(RedisValue::Null) 193 | } 194 | 195 | fn set_tail_child(ctx: &Context, args: Vec) -> RedisResult { 196 | let mut args = args.into_iter().skip(1); 197 | let mut key = ctx.open_key_writable(&args.next_string()?); 198 | let node_data = args.next_string()?; 199 | // let path = args.next_string()?.split(".").map(|v| v.to_string()).collect::>(); 200 | let sub_tree = Tree::try_from(args.next_string()?)?; 201 | 202 | 203 | if let Some(mut value) = key.get_value::(&TREE_TYPE)? { 204 | if let Some(mut node) = value.data.root_mut().locate_first_mut_by_data(&node_data) { 205 | node.push_back(sub_tree); 206 | return REDIS_OK; 207 | } 208 | } 209 | 210 | Ok(RedisValue::Null) 211 | } 212 | 213 | 214 | fn get_ancestors(ctx: &Context, args: Vec) -> RedisResult { 215 | let mut args = args.into_iter().skip(1); 216 | let key = ctx.open_key(&args.next_string()?); 217 | let node_data = args.next_string()?; 218 | 219 | if let Some(value) = key.get_value::(&TREE_TYPE)? { 220 | if let Some(node) = value.data.root().locate_first_by_data(&node_data) { 221 | let ancestors = node.ancestors(); 222 | if ancestors.len() > 0 { 223 | return Ok(RedisValue::Array(ancestors.into_iter().map(|v|{ 224 | v.clone().into() 225 | }).collect::>())) 226 | } 227 | } 228 | } 229 | 230 | Ok(RedisValue::Null) 231 | } 232 | 233 | 234 | fn get_descendants(ctx: &Context, args: Vec) -> RedisResult { 235 | let mut args = args.into_iter().skip(1); 236 | let key = ctx.open_key(&args.next_string()?); 237 | let node_data = args.next_string()?; 238 | 239 | if let Some(value) = key.get_value::(&TREE_TYPE)? { 240 | if let Some(node) = value.data.root().locate_first_by_data(&node_data) { 241 | let descendants = node.descendants(); 242 | if descendants.len() > 0 { 243 | return Ok(RedisValue::Array(descendants.into_iter().map(|v|{ 244 | v.clone().into() 245 | }).collect::>())) 246 | } 247 | } 248 | } 249 | 250 | Ok(RedisValue::Null) 251 | } 252 | 253 | 254 | fn get_father(ctx: &Context, args: Vec) -> RedisResult { 255 | let mut args = args.into_iter().skip(1); 256 | let key = ctx.open_key(&args.next_string()?); 257 | let node_data = args.next_string()?; 258 | 259 | if let Some(value) = key.get_value::(&TREE_TYPE)? { 260 | if let Some(node) = value.data.root().locate_first_by_data(&node_data) { 261 | if let Some(father) = node.father() { 262 | return Ok(father.into()); 263 | } 264 | } 265 | } 266 | 267 | Ok(RedisValue::Null) 268 | } 269 | 270 | 271 | fn get_children(ctx: &Context, args: Vec) -> RedisResult { 272 | let mut args = args.into_iter().skip(1); 273 | let key = ctx.open_key(&args.next_string()?); 274 | let node_data = args.next_string()?; 275 | 276 | if let Some(value) = key.get_value::(&TREE_TYPE)? { 277 | if let Some(node) = value.data.locate_first_by_data(&node_data) { 278 | let children = node.children(); 279 | if children.len() > 0 { 280 | return Ok(RedisValue::Array(children.into_iter().map(|v|{ 281 | v.clone().into() 282 | }).collect::>())) 283 | } 284 | } 285 | } 286 | 287 | Ok(RedisValue::Null) 288 | } 289 | 290 | 291 | 292 | redis_module! { 293 | name: "ReTree", 294 | version: 1, 295 | data_types: [ 296 | TREE_TYPE, 297 | ], 298 | init: init, 299 | commands: [ 300 | ["tree.init", init_tree, "write", 1, 1, 1], 301 | ["tree.get", get_tree, "readonly", 1, 1, 1], 302 | ["tree.del", del_tree, "write", 1, 1, 1], 303 | 304 | ["tree.get_subtree", get_subtree, "readonly", 1, 1, 1], 305 | ["tree.del_subtree", del_subtree, "write", 1, 1, 1], 306 | ["tree.set_subtree", set_tail_child, "write", 1, 1, 1], 307 | ["tree.get_ancestors", get_ancestors, "readonly", 1, 1, 1], 308 | ["tree.get_descendants", get_descendants, "readonly", 1, 1, 1], 309 | ["tree.get_father", get_father, "readonly", 1, 1, 1], 310 | ["tree.get_children", get_children, "readonly", 1, 1, 1], 311 | ], 312 | } -------------------------------------------------------------------------------- /tester.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ohbonsai/retree:latest as tmp 2 | 3 | 4 | FROM python:3.6-slim-buster 5 | COPY --from=tmp /usr/local/bin/redis-server /usr/local/bin/redis-server 6 | COPY --from=tmp /usr/local/bin/redis-cli /usr/local/bin/redis-cli 7 | COPY --from=tmp /usr/lib/redis/modules/retree.so /usr/lib/redis/modules/retree.so 8 | COPY --from=tmp /data/redis.conf /etc/redis/redis.conf 9 | 10 | 11 | # add python requirements 12 | ADD ./tests/requirements.txt /tmp/requirements.txt 13 | RUN pip install -r /tmp/requirements.txt --no-cache-dir -i https://mirrors.aliyun.com/pypi/simple 14 | 15 | 16 | # set some default setting when testing 17 | RUN mkdir -p /etc/redis \ 18 | && sed -i 's/^\(daemonize .*\)$/# \1/' /etc/redis/redis.conf \ 19 | && echo "\ndaemonize yes" >> /etc/redis/redis.conf \ 20 | && sed -i 's/^\(logfile .*\)$/# \1/' /etc/redis/redis.conf \ 21 | && sed -i 's/^\(Dir .*\)$/# \1/' /etc/redis/redis.conf \ 22 | && echo "\nlogfile /tmp/redis-server.log" >> /etc/redis/redis.conf \ 23 | && sed -i 's/^\(loglevel .*\)$/# \1/' /etc/redis/redis.conf \ 24 | && echo "\nloglevel notice" >> /etc/redis/redis.conf 25 | 26 | RUN echo "#!/bin/bash\n/usr/local/bin/redis-server /etc/redis/redis.conf --loadmodule /usr/lib/redis/modules/retree.so\npytest -s -v tests" > /run.sh 27 | RUN chmod +x /run.sh 28 | 29 | ENTRYPOINT ["/run.sh"] 30 | 31 | -------------------------------------------------------------------------------- /tests/README.md: -------------------------------------------------------------------------------- 1 | # System tests for redis tree 2 | This folder contains the system tests for RedisTree. System tests are 3 | written in Python and Pytest framework 4 | 5 | ## Running 6 | All test run in docker, So you need Docker installed. Then you can prepare 7 | the setup adn run all teh tests with: 8 | ``` 9 | make test 10 | ``` 11 | 12 | Running a single test, e.g.: 13 | ``` 14 | make test case="xab/test" 15 | ``` -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | 4 | 5 | def execute_commands_file(file_name, redis_client): 6 | cwd = os.getcwd() 7 | file_name = os.path.join(cwd, "./tests/files", file_name) 8 | 9 | for line in open(file_name, "r").readlines(): 10 | if line.strip().startswith("#"): 11 | continue 12 | 13 | args = json.loads(line) 14 | redis_client.execute_command(*args) 15 | 16 | 17 | if __name__ == '__main__': 18 | import pytest 19 | pytest.main(["test_commands.py::test_get_descendants"]) 20 | # pytest.main() 21 | -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import redis 3 | import time 4 | 5 | 6 | @pytest.fixture(scope="session") 7 | def redis_client(): 8 | client = redis.Redis(host="127.0.0.1", port=6379, decode_responses=True) 9 | client.ping() 10 | return client 11 | 12 | 13 | @pytest.fixture(scope="function", autouse=True) 14 | def clear_db(redis_client): 15 | redis_client.flushdb() -------------------------------------------------------------------------------- /tests/requirements.txt: -------------------------------------------------------------------------------- 1 | pytest==6.2.1 2 | redis==3.5.1 -------------------------------------------------------------------------------- /tests/test_commands.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from redis.exceptions import ResponseError 3 | 4 | 5 | def test_init(redis_client): 6 | # wrong format tree string will raise ResponseError 7 | with pytest.raises(ResponseError, match="() is not closed"): 8 | redis_client.execute_command("tree.init", "hello", "0 (1(2") 9 | 10 | with pytest.raises(ResponseError, match="no root in tree string"): 11 | redis_client.execute_command("tree.init", "hello", "(2)") 12 | 13 | assert redis_client.execute_command("tree.get", "hello") is None 14 | redis_client.execute_command("tree.init", "hello", "0 (1 2)") 15 | 16 | 17 | def test_get(redis_client): 18 | redis_client.execute_command("tree.init", "hello", "0 (1 2 (a b (d)) e f (g h))") 19 | assert redis_client.execute_command("tree.get", "hello") == "0( 1 2( a b( d ) ) e f( g h ) )" 20 | 21 | 22 | def test_del(redis_client): 23 | redis_client.execute_command("tree.init", "hello", "0 (1 2 (a b (d)) e f (g h))") 24 | redis_client.execute_command("tree.del", "hello") 25 | assert redis_client.execute_command("tree.get", "hello") is None 26 | 27 | 28 | def test_get_subtree(redis_client): 29 | redis_client.execute_command("tree.init", "hello", "0 (1 2 (a b (d)) e f (g h))") 30 | assert redis_client.execute_command("tree.get_subtree", "hello", "f") == "f( g h )" 31 | 32 | 33 | def test_set_subtree(redis_client): 34 | redis_client.execute_command("tree.init", "hello", "0 (1 2)") 35 | redis_client.execute_command("tree.set_subtree", "hello", "2", "3 ( 4 5)") 36 | assert redis_client.execute_command("tree.get", "hello") == "0( 1 2( 3( 4 5 ) ) )" 37 | 38 | 39 | def test_get_ancestors(redis_client): 40 | redis_client.execute_command("tree.init", "hello", "0 (1 2 (a b (d)) e f (g h))") 41 | assert redis_client.execute_command("tree.get_ancestors", "hello", "d") == ["b", "2", "0"] 42 | 43 | 44 | def test_get_descendants(redis_client): 45 | redis_client.execute_command("tree.init", "hello", "0 (1 2 (a (k (j) bb) b (d)) e f (g h))") 46 | assert redis_client.execute_command("tree.get_descendants", "hello", "2") == ["2", "a", "b", "k", "bb", "d", "j"] 47 | 48 | 49 | def test_get_father(redis_client): 50 | redis_client.execute_command("tree.init", "hello", "0 (1 2 (a (k (j) bb) b (d)) e f (g h))") 51 | assert redis_client.execute_command("tree.get_father", "hello", "j") == "k" 52 | 53 | 54 | def test_get_children(redis_client): 55 | redis_client.execute_command("tree.init", "hello", "0 (1 2 (a (k (j) bb) b (d)) e f (g h))") 56 | assert redis_client.execute_command("tree.get_children", "hello", "0") == ["1", "2", "e", "f"] 57 | --------------------------------------------------------------------------------