Big update, AppVeyor_Test

This commit is contained in:
Daniel S. 2020-03-28 14:53:52 +01:00
parent aec570d055
commit e71faf0b92
65 changed files with 2141 additions and 1355 deletions

413
rust/Cargo.lock generated
View file

@ -1,19 +1,11 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "ahash"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"const-random 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "aho-corasick"
version = "0.7.6"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -21,16 +13,11 @@ name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"hermit-abi 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "autocfg"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "autocfg"
version = "1.0.0"
@ -38,12 +25,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "backtrace"
version = "0.3.43"
version = "0.3.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -53,7 +40,7 @@ version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -61,7 +48,7 @@ name = "better-panic"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
"backtrace 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)",
"console 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -70,10 +57,15 @@ name = "bincode"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "block-buffer"
version = "0.7.3"
@ -81,7 +73,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -95,13 +87,13 @@ dependencies = [
[[package]]
name = "bstr"
version = "0.2.10"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -111,7 +103,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "1.3.2"
version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -131,10 +123,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cloudabi"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "console"
version = "0.9.2"
@ -143,44 +143,27 @@ dependencies = [
"clicolors-control 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"encode_unicode 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "const-random"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"const-random-macro 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "const-random-macro"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-channel"
version = "0.4.0"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-utils"
version = "0.7.0"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -190,28 +173,48 @@ name = "csv"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bstr 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"bstr 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"csv-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "csv-core"
version = "0.1.6"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ctor"
version = "0.1.12"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "derivative"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "dict_derive"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -228,19 +231,21 @@ version = "0.2.0"
dependencies = [
"better-panic 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-channel 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"csv 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"derivative 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"dict_derive 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"humantime 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"permutohedron 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"pyo3 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
"pyo3 0.9.0-alpha.1 (git+https://github.com/PyO3/pyo3)",
"rstar 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)",
"sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"simd-json 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"strsim 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
"strsim 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -248,14 +253,6 @@ name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "float-cmp"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fnv"
version = "1.0.6"
@ -269,16 +266,6 @@ dependencies = [
"typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "getrandom"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ghost"
version = "0.1.1"
@ -286,33 +273,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "halfbrown"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hashbrown 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hashbrown"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ahash 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hermit-abi"
version = "0.1.6"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -337,7 +306,7 @@ dependencies = [
"proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
"unindent 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -346,7 +315,7 @@ name = "inventory"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ctor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"ctor 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"ghost 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"inventory-impl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -358,7 +327,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -378,16 +347,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.66"
version = "0.2.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lock_api"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "maybe-uninit"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memchr"
version = "2.3.0"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
@ -397,29 +376,60 @@ dependencies = [
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num_cpus"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hermit-abi 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "opaque-debug"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "paste"
version = "0.1.6"
name = "parking_lot"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lock_api 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "parking_lot_core"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "paste"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"paste-impl 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "paste-impl"
version = "0.1.6"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -439,7 +449,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -452,43 +462,43 @@ dependencies = [
[[package]]
name = "pyo3"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
version = "0.9.0-alpha.1"
source = "git+https://github.com/PyO3/pyo3#74b22eb651aac14cd64524219943b77cf7e700ac"
dependencies = [
"indoc 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"inventory 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"pyo3cls 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
"spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"paste 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"pyo3cls 0.9.0-alpha.1 (git+https://github.com/PyO3/pyo3)",
"regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)",
"unindent 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pyo3-derive-backend"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
version = "0.9.0-alpha.1"
source = "git+https://github.com/PyO3/pyo3#74b22eb651aac14cd64524219943b77cf7e700ac"
dependencies = [
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pyo3cls"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
version = "0.9.0-alpha.1"
source = "git+https://github.com/PyO3/pyo3#74b22eb651aac14cd64524219943b77cf7e700ac"
dependencies = [
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"pyo3-derive-backend 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
"pyo3-derive-backend 0.9.0-alpha.1 (git+https://github.com/PyO3/pyo3)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -499,14 +509,19 @@ dependencies = [
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_syscall"
version = "0.1.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "regex"
version = "1.3.3"
version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
"aho-corasick 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -515,12 +530,12 @@ name = "regex-automata"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex-syntax"
version = "0.6.13"
version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -542,32 +557,37 @@ name = "ryu"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.104"
version = "1.0.105"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_derive"
version = "1.0.104"
version = "1.0.105"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_json"
version = "1.0.45"
version = "1.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -583,31 +603,18 @@ dependencies = [
]
[[package]]
name = "simd-json"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"float-cmp 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"halfbrown 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "spin"
version = "0.5.2"
name = "smallvec"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "strsim"
version = "0.9.3"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syn"
version = "1.0.14"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -620,7 +627,7 @@ name = "termios"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -651,11 +658,6 @@ name = "version_check"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.3.8"
@ -676,41 +678,37 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum ahash 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6f33b5018f120946c1dcf279194f238a9f146725593ead1c08fa47ff22b0b5d3"
"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
"checksum aho-corasick 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "743ad5a418686aad3b87fd14c43badd828cf26e214a00f92a384291cf22e1811"
"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
"checksum backtrace 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)" = "7f80256bc78f67e7df7e36d77366f636ed976895d91fe2ab9efa3973e8fe8c4f"
"checksum backtrace 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)" = "e4036b9bf40f3cf16aba72a3d65e8a520fc4bafcdc7079aea8f848c58c5b5536"
"checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491"
"checksum better-panic 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d12a680cc74d8c4a44ee08be4a00dedf671b089c2440b2e3fdaa776cd468476"
"checksum bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5753e2a71534719bf3f4e57006c3a4f0d2c672a4b676eec84161f763eca87dbf"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
"checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
"checksum bstr 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "fe8a65814ca90dfc9705af76bb6ba3c6e2534489a72270e797e603783bb4990b"
"checksum bstr 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "502ae1441a0a5adb8fbd38a5955a6416b9493e92b465de5e4a9bde6a539c2c48"
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
"checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
"checksum clicolors-control 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90082ee5dcdd64dc4e9e0d37fbf3ee325419e39c0092191e0393df65518f741e"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum console 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "45e0f3986890b3acbc782009e2629dfe2baa430ac091519ce3be26164a2ae6c0"
"checksum const-random 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "2f1af9ac737b2dd2d577701e59fd09ba34822f6f2ebdb30a7647405d9e55e16a"
"checksum const-random-macro 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "25e4c606eb459dd29f7c57b2e0879f2b6f14ee130918c2b78ccb58a9624e6c7a"
"checksum crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c"
"checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4"
"checksum crossbeam-channel 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cced8691919c02aac3cb0a1bc2e9b73d89e832bf9a06fc579d4e71b68a2da061"
"checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
"checksum csv 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "00affe7f6ab566df61b4be3ce8cf16bc2576bca0963ceb0955e45d514bf9a279"
"checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c"
"checksum ctor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8ce37ad4184ab2ce004c33bf6379185d3b1c95801cab51026bd271bf68eedc"
"checksum csv-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
"checksum ctor 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "47c5e5ac752e18207b12e16b10631ae5f7f68f8805f335f9b817ead83d9ffce1"
"checksum derivative 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1b94d2eb97732ec84b4e25eaf37db890e317b80e921f168c82cb5282473f8151"
"checksum dict_derive 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d7ee5676aa48357bd5e8bcf095167e6678837232a7b85bce424f46cd93a2c60"
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
"checksum encode_unicode 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
"checksum float-cmp 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75224bec9bfe1a65e2d34132933f2de7fe79900c96a0174307554244ece8150e"
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
"checksum ghost 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a36606a68532b5640dc86bb1f33c64b45c4682aad4c50f3937b317ea387f3d6"
"checksum halfbrown 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "f28ee31ba5bb3a3251606db26de2e807552c5f295429d03f756bdc4e00f54c7a"
"checksum hashbrown 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead"
"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772"
"checksum hermit-abi 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1010591b26bbfe835e9faeabeb11866061cc7dcebffd56ad7d0942d0e61aefd8"
"checksum humantime 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b9b6c53306532d3c8e8087b44e6580e10db51a023cf9b433cea2ac38066b92da"
"checksum indoc 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3f9553c1e16c114b8b77ebeb329e5f2876eed62a8d51178c8bc6bff0d65f98f8"
"checksum indoc-impl 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b714fc08d0961716390977cdff1536234415ac37b509e34e5a983def8340fb75"
@ -719,41 +717,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
"checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
"checksum memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3197e20c7edb283f87c071ddfc7a2cca8f8e0b888c242959846a6fce03c72223"
"checksum libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)" = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018"
"checksum lock_api 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "79b2de95ecb4691949fea4716ca53cdbcfccb2c612e19644a8bad05edcf9f47b"
"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
"checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
"checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6"
"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
"checksum paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "423a519e1c6e828f1e73b720f9d9ed2fa643dce8a7737fb43235ce0b41eeaa49"
"checksum paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5"
"checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc"
"checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1"
"checksum paste 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "63e1afe738d71b1ebab5f1207c055054015427dbfc7bbe9ee1266894156ec046"
"checksum paste-impl 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4dc4a7f6f743211c5aab239640a65091535d97d43d92a52bca435a640892bb"
"checksum pdqselect 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ec91767ecc0a0bbe558ce8c9da33c068066c57ecc8bb8477ef8c1ad3ef77c27"
"checksum permutohedron 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b687ff7b5da449d39e418ad391e5e08da53ec334903ddbb921db208908fc372c"
"checksum proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5"
"checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548"
"checksum pyo3 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e1bfe257586436fbe1296d917f14a167d4253d0873bf43e2c9b9bdd58a3f9f35"
"checksum pyo3-derive-backend 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4882d8237fd8c7373cc25cb802fe0dab9ff70830fd56f47ef6c7f3f287fcc057"
"checksum pyo3cls 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fdf321cfab555f7411298733c86d21e5136f5ded13f5872fabf9de3337beecda"
"checksum pyo3 0.9.0-alpha.1 (git+https://github.com/PyO3/pyo3)" = "<none>"
"checksum pyo3-derive-backend 0.9.0-alpha.1 (git+https://github.com/PyO3/pyo3)" = "<none>"
"checksum pyo3cls 0.9.0-alpha.1 (git+https://github.com/PyO3/pyo3)" = "<none>"
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
"checksum regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5508c1941e4e7cb19965abef075d35a9a8b5cdf0846f30b4050e9b55dc55e87"
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
"checksum regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8"
"checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9"
"checksum regex-syntax 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e734e891f5b408a29efbf8309e656876276f49ab6a6ac208600b4419bd893d90"
"checksum regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06"
"checksum rstar 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0650eaaa56cbd1726fd671150fce8ac6ed9d9a25d1624430d7ee9d196052f6b6"
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
"checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449"
"checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64"
"checksum serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "eab8f15f15d6c41a154c1b128a22f2dfabe350ef53c40953d84e36155c91192b"
"checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
"checksum serde 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)" = "e707fbbf255b8fc8c3b99abb91e7257a622caeb20a9818cbadbeeede4e0932ff"
"checksum serde_derive 1.0.105 (registry+https://github.com/rust-lang/crates.io-index)" = "ac5d00fc561ba2724df6758a17de23df5914f20e41cb00f94d5b7ae42fffaff8"
"checksum serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "9371ade75d4c2d6cb154141b9752cf3781ec9c05e0e5cf35060e1e70ee7b9c25"
"checksum sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf"
"checksum simd-json 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fb65296b57a8709ea32a87cefc0e1099cdd407ee3aed89114af11c74ab86f7bf"
"checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
"checksum strsim 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
"checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5"
"checksum smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc"
"checksum strsim 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
"checksum syn 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a0294dc449adc58bb6592fff1a23d3e5e6e235afc6a0ffca2657d19e7bbffe5"
"checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625"
"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum unindent 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "63f18aa3b0e35fed5a0048f029558b1518095ffe2a0a31fb87c93dece93a4993"
"checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View file

@ -20,18 +20,20 @@ codegen-units = 1
lto = true
[dependencies]
pyo3 = { version = "0.8.5", features = ["extension-module"] }
pyo3 = { git = "https://github.com/PyO3/pyo3", features = ["extension-module"] }
csv = "1.1.3"
serde = { version = "1.0.104", features = ["derive"] }
serde = { version = "1.0.105", features = ["derive"] }
humantime = "2.0.0"
permutohedron = "0.2.4"
serde_json = "1.0.45"
serde_json = "1.0.48"
fnv = "1.0.6"
bincode = "1.2.1"
sha3 = "0.8.2"
byteorder = "1.3.2"
strsim = "0.9.3"
byteorder = "1.3.4"
strsim = "0.10.0"
rstar = "0.7.1"
crossbeam-channel = "0.4.0"
simd-json = "0.2.3"
crossbeam-channel = "0.4.2"
better-panic = "0.2.0"
derivative = "2.0.2"
dict_derive = "0.2.0"
num_cpus = "1.12.0"

View file

@ -1,125 +1,145 @@
use crate::route::Router;
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::collections::HashMap;
use std::path::PathBuf;
pub fn find_matches(
path: &PathBuf,
names: Vec<String>,
exact: bool
) -> Result<HashMap<String, (f64, Option<System>)>, String> {
let mut best: HashMap<String, (f64, Option<System>)> = HashMap::new();
for name in &names {
best.insert(name.to_string(), (0.0, None));
}
let mut reader = match csv::ReaderBuilder::new().from_path(path) {
Ok(rdr) => rdr,
Err(e) => {
return Err(format!("Error opening {}: {}", path.to_str().unwrap(), e).to_string());
}
};
let systems = reader.deserialize::<SystemSerde>();
for sys in systems {
let sys = sys.unwrap();
for name in &names {
best.entry(name.clone()).and_modify(|ent| {
if (exact)&&(&sys.system==name) {
*ent = (1.0, Some(sys.clone().build()))
} else {
let d1 = strsim::normalized_levenshtein(&sys.system, &name);
let d2 = strsim::normalized_levenshtein(&sys.body, &name);
if d1 > ent.0 {
*ent = (d1, Some(sys.clone().build()))
} else if d2 > ent.0 {
*ent = (d2, Some(sys.clone().build()))
}
}
});
}
}
Ok(best)
}
#[derive(Debug, Clone,Copy, Serialize, Deserialize)]
pub struct TreeNode {
pub id: u32,
pub pos: [f32; 3],
pub mult: f32,
}
impl TreeNode {
pub fn get(&self,router:&Router) -> Option<System> {
let mut cache = router.cache.as_ref().unwrap().lock().unwrap();
cache.get(self.id)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemSerde {
pub id: u32,
pub star_type: String,
pub system: String,
pub body: String,
pub mult: f32,
pub distance: u32,
pub x: f32,
pub y: f32,
pub z: f32,
}
impl SystemSerde {
pub fn build(self) -> System {
System {
id: self.id,
star_type: self.star_type,
system: self.system,
body: self.body,
mult: self.mult,
distance: self.distance,
pos: [self.x, self.y, self.z],
}
}
pub fn to_node(&self) -> TreeNode {
TreeNode {
id: self.id,
pos: [self.x, self.y, self.z],
mult: self.mult,
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct System {
pub id: u32,
pub star_type: String,
pub system: String,
pub body: String,
pub mult: f32,
pub distance: u32,
pub pos: [f32; 3],
}
impl System {
pub fn to_node(&self) -> TreeNode {
TreeNode {
id: self.id,
pos: self.pos,
mult: self.mult,
}
}
}
impl Ord for System {
fn cmp(&self, other: &Self) -> Ordering {
self.id.cmp(&other.id)
}
}
impl PartialOrd for System {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
use crate::route::Router;
use dict_derive::IntoPyObject;
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::collections::HashMap;
use std::num::ParseIntError;
use std::path::PathBuf;
use std::str::FromStr;
pub enum SysEntry {
ID(u32),
Name(String)
}
impl SysEntry {
pub fn parse(s: &str) -> Self {
if let Ok(n) = s.parse() {
SysEntry::ID(n)
} else {
SysEntry::Name(s.to_owned())
}
}
}
pub fn find_matches(
path: &PathBuf,
names: Vec<String>,
exact: bool,
) -> Result<HashMap<String, (f64, Option<System>)>, String> {
let mut best: HashMap<String, (f64, Option<System>)> = HashMap::new();
if names.is_empty() {
return Ok(best);
}
for name in &names {
best.insert(name.to_string(), (0.0, None));
}
let mut reader = match csv::ReaderBuilder::new().from_path(path) {
Ok(rdr) => rdr,
Err(e) => {
return Err(format!("Error opening {}: {}", path.to_str().unwrap(), e).to_string());
}
};
let systems = reader.deserialize::<SystemSerde>();
for sys in systems {
let sys = sys.unwrap();
for name in &names {
best.entry(name.clone()).and_modify(|ent| {
if (exact) && (&sys.system == name) {
*ent = (1.0, Some(sys.clone().build()))
} else {
let d1 = strsim::normalized_levenshtein(&sys.system, &name);
let d2 = strsim::normalized_levenshtein(&sys.body, &name);
if d1 > ent.0 {
*ent = (d1, Some(sys.clone().build()))
} else if d2 > ent.0 {
*ent = (d2, Some(sys.clone().build()))
}
}
});
}
}
Ok(best)
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct TreeNode {
pub id: u32,
pub pos: [f32; 3],
pub mult: f32,
}
impl TreeNode {
pub fn get(&self, router: &Router) -> Option<System> {
let mut cache = router.cache.as_ref().unwrap().lock().unwrap();
cache.get(self.id)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, IntoPyObject)]
pub struct SystemSerde {
pub id: u32,
pub star_type: String,
pub system: String,
pub body: String,
pub mult: f32,
pub distance: u32,
pub x: f32,
pub y: f32,
pub z: f32,
}
impl SystemSerde {
pub fn build(self) -> System {
System {
id: self.id,
star_type: self.star_type,
system: self.system,
body: self.body,
mult: self.mult,
distance: self.distance,
pos: [self.x, self.y, self.z],
}
}
pub fn to_node(&self) -> TreeNode {
TreeNode {
id: self.id,
pos: [self.x, self.y, self.z],
mult: self.mult,
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct System {
pub id: u32,
pub star_type: String,
pub system: String,
pub body: String,
pub mult: f32,
pub distance: u32,
pub pos: [f32; 3],
}
impl System {
pub fn to_node(&self) -> TreeNode {
TreeNode {
id: self.id,
pos: self.pos,
mult: self.mult,
}
}
}
impl Ord for System {
fn cmp(&self, other: &Self) -> Ordering {
self.id.cmp(&other.id)
}
}
impl PartialOrd for System {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

View file

@ -1,68 +1,83 @@
use serde::Deserialize;
use serde_json::Result;
use serde_json;
use std::fs::File;
use std::io::Seek;
use std::io::{BufRead, BufReader, BufWriter, SeekFrom};
use std::path::PathBuf;
use std::str;
use std::time::Instant;
#[derive(Debug, Deserialize)]
struct Coords {
x: f32,
y: f32,
z: f32,
}
#[derive(Debug, Deserialize)]
struct Body {
name: String,
#[serde(rename = "type")]
body_type: String,
subType: String,
#[serde(rename = "distanceToArrival")]
distance: f32,
}
#[derive(Debug, Deserialize)]
struct System {
coords: Coords,
name: String,
bodies: Vec<Body>,
}
fn main() -> std::io::Result<()> {
better_panic::install();
let mut buffer = String::new();
let mut bz2_reader = std::process::Command::new("bzip2").args(
&["-d","-c",r#"E:\EDSM\galaxy.json.bz2"#]
).stdout(std::process::Stdio::piped())
.spawn()
.expect("Failed to spawn execute bzip2!");
let mut reader = BufReader::new(bz2_reader.stdout.as_mut().expect("Failed to open stdout of child process"));
let mut count = 0;
while let Ok(n) = reader.read_line(&mut buffer) {
if n==0 {
break;
}
buffer = buffer
.trim()
.trim_end_matches(|c| c == ',')
.trim()
.to_string();
if let Ok(sys) = serde_json::from_str::<System>(&buffer) {
for b in &sys.bodies {
if b.body_type == "Star" {
count += 1;
if (count % 100_000) == 0 {
println!("{}: {:?}", count, b);
}
}
}
}
buffer.clear();
}
println!("Total: {}", count);
Ok(())
}
use serde::Deserialize;
use serde_json;
use std::io::{BufRead, BufReader};
use std::str;
#[derive(Debug, Deserialize)]
struct Coords {
x: f32,
y: f32,
z: f32,
}
#[derive(Debug, Deserialize)]
struct Body {
name: String,
#[serde(rename = "type")]
body_type: String,
#[serde(rename = "subType")]
sub_type: String,
#[serde(rename = "distanceToArrival")]
distance: f32,
}
#[derive(Debug, Deserialize)]
struct System {
coords: Coords,
name: String,
bodies: Vec<Body>,
}
/*
pub id: u32,
pub star_type: String,
pub system: String,
pub body: String,
pub mult: f32,
pub distance: u32,
pub x: f32,
pub y: f32,
pub z: f32,
*/
fn main() -> std::io::Result<()> {
better_panic::install();
let mut buffer = String::new();
let mut bz2_reader = std::process::Command::new("bzip2")
.args(&["-d", "-c", r#"E:\EDSM\galaxy.json.bz2"#])
.stdout(std::process::Stdio::piped())
.spawn()
.expect("Failed to spawn execute bzip2!");
let mut reader = BufReader::new(
bz2_reader
.stdout
.as_mut()
.expect("Failed to open stdout of child process"),
);
let mut count = 0;
while let Ok(n) = reader.read_line(&mut buffer) {
if n == 0 {
break;
}
buffer = buffer
.trim()
.trim_end_matches(|c| c == ',')
.trim()
.to_string();
if let Ok(sys) = serde_json::from_str::<System>(&buffer) {
for b in &sys.bodies {
if b.body_type == "Star" {
count += 1;
if (count % 100_000) == 0 {
println!("{}: {:?}", count, b);
}
}
}
}
buffer.clear();
}
println!("Total: {}", count);
Ok(())
}

View file

@ -1,221 +1,382 @@
#![deny(warnings)]
mod common;
mod preprocess;
mod route;
use std::path::PathBuf;
use common::find_matches;
use pyo3::exceptions::*;
use pyo3::prelude::*;
use pyo3::types::{PyDict, PyList};
enum SysEntry {
ID(u32),
Name(String),
}
impl From<&str> for SysEntry {
fn from(s: &str) -> SysEntry {
if let Ok(n) = s.parse() {
SysEntry::ID(n)
} else {
SysEntry::Name(s.to_owned())
}
}
}
fn resolve(entries: &Vec<SysEntry>, path: &PathBuf) -> Result<Vec<u32>,String> {
let mut names: Vec<String> = Vec::new();
let mut ids: Vec<u32> = Vec::new();
let mut ret: Vec<u32> = Vec::new();
for ent in entries {
match ent {
SysEntry::Name(name) => names.push(name.to_owned()),
SysEntry::ID(id) => ids.push(*id),
}
};
let name_ids = find_matches(path, names, false)?;
for ent in entries {
match ent {
SysEntry::Name(name) => {
let ent_res=name_ids.get(&name.to_owned()).ok_or(format!("System {} not found",name))?;
let sys=ent_res.1.as_ref().ok_or(format!("System {} not found",name))?;
if ent_res.0<0.75 {
println!("WARNING: {} match to {} with low confidence ({}%)",name,sys.system,ent_res.0*100.0);
}
ret.push(sys.id);
}
SysEntry::ID(id) => ret.push(*id),
}
}
return Ok(ret);
}
#[pymodule]
pub fn _ed_lrr(_py: Python, m: &PyModule) -> PyResult<()> {
better_panic::install();
/// preprocess(infile_systems, infile_bodies, outfile, callback)
/// --
///
/// Preprocess bodies.json and systemsWithCoordinates.json into stars.csv
#[pyfn(m, "preprocess")]
fn ed_lrr_preprocess(
py: Python<'static>,
infile_systems: String,
infile_bodies: String,
outfile: String,
callback: PyObject,
) -> PyResult<PyObject> {
use preprocess::*;
let state = PyDict::new(py);
let state_dict = PyDict::new(py);
callback.call(py, (state_dict,), None).unwrap();
let callback_wrapped = move |state: &PreprocessState| {
// println!("SEND: {:?}",state);
state_dict.set_item("file", state.file.clone())?;
state_dict.set_item("total", state.total)?;
state_dict.set_item("count", state.count)?;
state_dict.set_item("done", state.done)?;
state_dict.set_item("message", state.message.clone())?;
callback.call(py, (state_dict,), None)
};
preprocess_files(
&PathBuf::from(infile_bodies),
&PathBuf::from(infile_systems),
&PathBuf::from(outfile),
&callback_wrapped,
)
.unwrap();
Ok(state.to_object(py))
}
///find_sys(sys_names, sys_list_path)
/// --
///
/// Find system by name
#[pyfn(m, "find_sys")]
fn find_sys(py: Python, sys_names: Vec<String>, sys_list: String) -> PyResult<PyObject> {
let path = PathBuf::from(sys_list);
match find_matches(&path, sys_names,false) {
Ok(vals) => {
let ret = PyDict::new(py);
for (key, (diff, sys)) in vals {
let ret_dict = PyDict::new(py);
if let Some(val) = sys {
let pos = PyList::new(py, val.pos.iter());
ret_dict.set_item("star_type", val.star_type.clone())?;
ret_dict.set_item("system", val.system.clone())?;
ret_dict.set_item("body", val.body.clone())?;
ret_dict.set_item("distance", val.distance)?;
ret_dict.set_item("pos", pos)?;
ret_dict.set_item("id", val.id)?;
ret.set_item(key, (diff, ret_dict).to_object(py))?;
}
}
Ok(ret.to_object(py))
}
Err(e) => Err(PyErr::new::<ValueError, _>(e)),
}
}
/// route(hops, range, prune, mode, primary, permute, keep_first, keep_last, greedyness, precomp, path, num_workers, callback)
/// --
///
/// Compute a Route using the suplied parameters
#[pyfn(m, "route")]
#[allow(clippy::too_many_arguments)]
fn py_route(
py: Python<'static>,
hops: Vec<&str>,
range: f32,
prune: Option<(usize, f32)>,
mode: String,
primary: bool,
permute: bool,
keep_first: bool,
keep_last: bool,
greedyness: Option<f32>,
precomp: Option<String>,
path: String,
num_workers: Option<usize>,
callback: PyObject,
) -> PyResult<PyObject> {
use route::*;
let num_workers=num_workers.unwrap_or(1);
let mode = match Mode::parse(&mode) {
Ok(val) => val,
Err(e) => {
return Err(PyErr::new::<ValueError, _>(e));
}
};
let state_dict = PyDict::new(py);
{
let cb_res = callback.call(py, (state_dict,), None);
if cb_res.is_err() {
println!("Error: {:?}",cb_res);
}
}
let callback_wrapped = move |state: &SearchState| {
state_dict.set_item("mode", state.mode.clone())?;
state_dict.set_item("system", state.system.clone())?;
state_dict.set_item("body", state.body.clone())?;
state_dict.set_item("depth", state.depth)?;
state_dict.set_item("queue_size", state.queue_size)?;
state_dict.set_item("d_rem", state.d_rem)?;
state_dict.set_item("d_total", state.d_total)?;
state_dict.set_item("prc_done", state.prc_done)?;
state_dict.set_item("n_seen", state.n_seen)?;
state_dict.set_item("prc_seen", state.prc_seen)?;
state_dict.set_item("from", state.from.clone())?;
state_dict.set_item("to", state.to.clone())?;
let cb_res=callback.call(py, (state_dict,), None);
if cb_res.is_err() {
println!("Error: {:?}",cb_res);
}
cb_res
};
let hops: Vec<SysEntry> = hops.iter().cloned().map(SysEntry::from).collect();
println!("Resolving systems...");
let hops: Vec<u32> = match resolve(&hops,&PathBuf::from(&path)) {
Ok(ids) => ids,
Err(err_msg) => {
return Err(PyErr::new::<ValueError, _>(err_msg));
}
};
let opts = RouteOpts {
systems: hops,
range: Some(range),
file_path: PathBuf::from(path),
precomp_file: precomp.map(PathBuf::from),
callback: Box::new(callback_wrapped),
mode,
factor: greedyness,
precompute: false,
permute,
keep_first,
keep_last,
primary,
prune,
workers: num_workers
};
let none = ().to_object(py);
match route(opts) {
Ok(Some(route)) => {
let hops = route.iter().map(|hop| {
let pos = PyList::new(py, hop.pos.iter());
let elem = PyDict::new(py);
elem.set_item("star_type", hop.star_type.clone()).unwrap();
elem.set_item("system", hop.system.clone()).unwrap();
elem.set_item("body", hop.body.clone()).unwrap();
elem.set_item("distance", hop.distance).unwrap();
elem.set_item("pos", pos).unwrap();
elem
});
let lst = PyList::new(py, hops);
Ok(lst.to_object(py))
}
Ok(None) => Ok(none),
Err(e) => Err(PyErr::new::<ValueError, _>(e)),
}
}
Ok(())
}
// #![deny(warnings)]
mod common;
mod preprocess;
mod route;
#[macro_use]
extern crate derivative;
use crate::common::SystemSerde;
use crate::common::{find_matches, SysEntry};
use crate::route::{Router, SearchState};
use pyo3::exceptions::*;
use pyo3::prelude::*;
use pyo3::types::{PyDict, PyList, PyTuple};
use pyo3::PyObjectProtocol;
use std::path::PathBuf;
/*
pub id: u32,
pub star_type: String,
pub system: String,
pub body: String,
pub mult: f32,
pub distance: u32,
pub x: f32,
pub y: f32,
pub z: f32,
*/
impl SystemSerde {
fn fill_dict(&self, dict: &PyDict) -> PyResult<()> {
dict.clear();
dict.set_item("id", self.id)?;
dict.set_item("star_type", self.star_type.clone())?;
dict.set_item("system", self.system.clone())?;
dict.set_item("body", self.body.clone())?;
dict.set_item("mult", self.mult)?;
dict.set_item("distance", self.distance)?;
dict.set_item("x", self.x)?;
dict.set_item("y", self.y)?;
dict.set_item("z", self.z)?;
return Ok(());
}
}
#[pyclass(dict)]
#[derive(Derivative)]
#[derivative(Debug)]
#[text_signature = "(callback, workers, /)"]
struct PyRouter {
router: Router,
stars_path: String,
}
#[pymethods]
impl PyRouter {
#[new]
#[args(callback = "None")]
fn new(callback: Option<PyObject>, py: Python<'static>) -> PyResult<Self> {
let cb_func = move |state: &SearchState| {
return match callback.as_ref() {
Some(cb) => cb.call(py, (state.clone(),), None),
None => Ok(py.None()),
};
};
let router = match Router::new(Box::new(cb_func)) {
Ok(router) => router,
Err(err_msg) => {
return Err(PyErr::new::<ValueError, _>(err_msg));
}
};
let ret = PyRouter {
router,
stars_path: String::from(""),
};
Ok(ret)
}
#[args(filter_func = "None")]
#[text_signature = "(path, /)"]
fn load(&mut self, path: String, py: Python<'static>) -> PyResult<PyObject> {
self.stars_path = path;
return Ok(py.None());
}
#[args(greedyness = "0.5", num_workers = "0", beam_width = "0")]
#[text_signature = "(hops, range, greedyness, beam_width, num_workers, /)"]
fn route(
&mut self,
hops: &PyList,
range: f32,
greedyness: f32,
beam_width: usize,
num_workers: usize,
py: Python,
) -> PyResult<PyObject> {
let route_res = self.router.load(&PathBuf::from(self.stars_path.clone()));
if let Err(err_msg) = route_res {
return Err(PyErr::new::<ValueError, _>(err_msg));
};
let mut sys_entries: Vec<SysEntry> = Vec::new();
for hop in hops {
if let Ok(id) = hop.extract() {
sys_entries.push(SysEntry::ID(id));
} else {
sys_entries.push(SysEntry::parse(hop.extract()?));
}
}
println!("Resolving systems...");
let ids: Vec<u32> = match resolve(&sys_entries, &self.router.path) {
Ok(ids) => ids,
Err(err_msg) => {
return Err(PyErr::new::<ValueError, _>(err_msg));
}
};
match self
.router
.computer_route(&ids, range, greedyness, beam_width, num_workers)
{
// TODO: return list of dicts (or objects)
Ok(route) => Ok(route.len().to_object(py)),
Err(err_msg) => Err(PyErr::new::<RuntimeError, _>(err_msg)),
}
}
#[args(hops = "*")]
#[text_signature = "(sys_1, sys_2, ..., /)"]
fn resolve_systems(&self, hops: &PyTuple, py: Python) -> PyResult<PyObject> {
let mut sys_entries: Vec<SysEntry> = Vec::new();
for hop in hops {
if let Ok(id) = hop.extract() {
sys_entries.push(SysEntry::ID(id));
} else {
sys_entries.push(SysEntry::parse(hop.extract()?));
}
}
println!("Resolving systems...");
let ids: Vec<u32> = match resolve(&sys_entries, &PathBuf::from(self.stars_path.clone())) {
Ok(ids) => ids,
Err(err_msg) => {
return Err(PyErr::new::<ValueError, _>(err_msg));
}
};
let ret: Vec<(_, u32)> = hops.into_iter().zip(ids.into_iter()).collect();
Ok(PyDict::from_sequence(py, ret.to_object(py))?.to_object(py))
}
#[staticmethod]
fn preprocess_edsm() -> PyResult<()> {
unimplemented!()
}
#[staticmethod]
fn preprocess_galaxy() -> PyResult<()> {
unimplemented!()
}
}
#[pyproto]
impl PyObjectProtocol for PyRouter {
fn __str__(&self) -> PyResult<String> {
Ok(format!("{:?}", &self))
}
fn __repr__(&self) -> PyResult<String> {
Ok(format!("{:?}", &self))
}
}
fn resolve(entries: &Vec<SysEntry>, path: &PathBuf) -> Result<Vec<u32>, String> {
let mut names: Vec<String> = Vec::new();
let mut ids: Vec<u32> = Vec::new();
let mut ret: Vec<u32> = Vec::new();
for ent in entries {
match ent {
SysEntry::Name(name) => names.push(name.to_owned()),
SysEntry::ID(id) => ids.push(*id),
}
}
if !path.exists() {
return Err(format!(
"Source file \"{:?}\" does not exist!",
path.display()
));
}
let name_ids = find_matches(path, names, false)?;
for ent in entries {
match ent {
SysEntry::Name(name) => {
let ent_res = name_ids
.get(&name.to_owned())
.ok_or(format!("System {} not found", name))?;
let sys = ent_res
.1
.as_ref()
.ok_or(format!("System {} not found", name))?;
if ent_res.0 < 0.75 {
println!(
"WARNING: {} match to {} with low confidence ({:.2}%)",
name,
sys.system,
ent_res.0 * 100.0
);
}
ret.push(sys.id);
}
SysEntry::ID(id) => ret.push(*id),
}
}
return Ok(ret);
}
#[pymodule]
pub fn _ed_lrr(_py: Python, m: &PyModule) -> PyResult<()> {
better_panic::install();
m.add_class::<PyRouter>()?;
Ok(())
}
/*
/// Preprocess bodies.json and systemsWithCoordinates.json into stars.csv
#[pyfn(m, "preprocess")]
#[text_signature = "(infile_systems, infile_bodies, outfile, callback, /)"]
fn ed_lrr_preprocess(
py: Python<'static>,
infile_systems: String,
infile_bodies: String,
outfile: String,
callback: PyObject,
) -> PyResult<PyObject> {
use preprocess::*;
let state = PyDict::new(py);
let state_dict = PyDict::new(py);
callback.call(py, (state_dict,), None).unwrap();
let callback_wrapped = move |state: &PreprocessState| {
// println!("SEND: {:?}",state);
state_dict.set_item("file", state.file.clone())?;
state_dict.set_item("total", state.total)?;
state_dict.set_item("count", state.count)?;
state_dict.set_item("done", state.done)?;
state_dict.set_item("message", state.message.clone())?;
callback.call(py, (state_dict,), None)
};
preprocess_files(
&PathBuf::from(infile_bodies),
&PathBuf::from(infile_systems),
&PathBuf::from(outfile),
&callback_wrapped,
)
.unwrap();
Ok(state.to_object(py))
}
/// Find system by name
#[pyfn(m, "find_sys")]
#[text_signature = "(sys_names, sys_list_path, /)"]
fn find_sys(py: Python, sys_names: Vec<String>, sys_list: String) -> PyResult<PyObject> {
let path = PathBuf::from(sys_list);
match find_matches(&path, sys_names, false) {
Ok(vals) => {
let ret = PyDict::new(py);
for (key, (diff, sys)) in vals {
let ret_dict = PyDict::new(py);
if let Some(val) = sys {
let pos = PyList::new(py, val.pos.iter());
ret_dict.set_item("star_type", val.star_type.clone())?;
ret_dict.set_item("system", val.system.clone())?;
ret_dict.set_item("body", val.body.clone())?;
ret_dict.set_item("distance", val.distance)?;
ret_dict.set_item("pos", pos)?;
ret_dict.set_item("id", val.id)?;
ret.set_item(key, (diff, ret_dict).to_object(py))?;
}
}
Ok(ret.to_object(py))
}
Err(e) => Err(PyErr::new::<ValueError, _>(e)),
}
}
/// Compute a Route using the suplied parameters
#[pyfn(m, "route")]
#[text_signature = "(hops, range, mode, primary, permute, keep_first, keep_last, greedyness, precomp, path, num_workers, callback, /)"]
#[allow(clippy::too_many_arguments)]
fn py_route(
py: Python<'static>,
hops: Vec<&str>,
range: f32,
mode: String,
primary: bool,
permute: bool,
keep_first: bool,
keep_last: bool,
greedyness: Option<f32>,
precomp: Option<String>,
path: String,
num_workers: Option<usize>,
callback: PyObject,
) -> PyResult<PyObject> {
use route::*;
let num_workers = num_workers.unwrap_or(1);
let mode = match Mode::parse(&mode) {
Ok(val) => val,
Err(e) => {
return Err(PyErr::new::<ValueError, _>(e));
}
};
let state_dict = PyDict::new(py);
{
let cb_res = callback.call(py, (state_dict,), None);
if cb_res.is_err() {
println!("Error: {:?}", cb_res);
}
}
let callback_wrapped = move |state: &SearchState| {
state_dict.set_item("mode", state.mode.clone())?;
state_dict.set_item("system", state.system.clone())?;
state_dict.set_item("body", state.body.clone())?;
state_dict.set_item("depth", state.depth)?;
state_dict.set_item("queue_size", state.queue_size)?;
state_dict.set_item("d_rem", state.d_rem)?;
state_dict.set_item("d_total", state.d_total)?;
state_dict.set_item("prc_done", state.prc_done)?;
state_dict.set_item("n_seen", state.n_seen)?;
state_dict.set_item("prc_seen", state.prc_seen)?;
state_dict.set_item("from", state.from.clone())?;
state_dict.set_item("to", state.to.clone())?;
let cb_res = callback.call(py, (state_dict,), None);
if cb_res.is_err() {
println!("Error: {:?}", cb_res);
}
cb_res
};
let hops: Vec<SysEntry> = (hops.iter().map(|v| SysEntry::from_str(&v)).collect::<Result<Vec<SysEntry>,_>>())?;
println!("Resolving systems...");
let hops: Vec<u32> = match resolve(&hops, &PathBuf::from(&path)) {
Ok(ids) => ids,
Err(err_msg) => {
return Err(PyErr::new::<ValueError, _>(err_msg));
}
};
let opts = RouteOpts {
systems: hops,
range: Some(range),
file_path: PathBuf::from(path),
precomp_file: precomp.map(PathBuf::from),
callback: Box::new(callback_wrapped),
mode,
factor: greedyness,
precompute: false,
permute,
keep_first,
keep_last,
primary,
workers: num_workers,
};
match route(opts) {
Ok(Some(route)) => {
let hops = route.iter().map(|hop| {
let pos = PyList::new(py, hop.pos.iter());
let elem = PyDict::new(py);
elem.set_item("star_type", hop.star_type.clone()).unwrap();
elem.set_item("system", hop.system.clone()).unwrap();
elem.set_item("body", hop.body.clone()).unwrap();
elem.set_item("distance", hop.distance).unwrap();
elem.set_item("pos", pos).unwrap();
elem
});
let lst = PyList::new(py, hops);
Ok(lst.to_object(py))
}
Ok(None) => Ok(py.None()),
Err(e) => Err(PyErr::new::<ValueError, _>(e)),
}
}
*/

View file

@ -116,7 +116,7 @@ fn process_systems(
ret
}
fn build_index(path: &PathBuf) -> std::io::Result<()> {
pub fn build_index(path: &PathBuf) -> std::io::Result<()> {
let mut wtr = BufWriter::new(File::create(path.with_extension("idx"))?);
let mut idx: Vec<u64> = Vec::new();
let mut records = (csv::Reader::from_path(path)?).into_deserialize::<SystemSerde>();

View file

@ -1,8 +1,9 @@
use crate::common::{System, SystemSerde, TreeNode};
use core::cmp::Ordering;
use crossbeam_channel::{
bounded, unbounded, Receiver, SendError, Sender, TryIter,
};
use crossbeam_channel::{bounded, unbounded, Receiver, SendError, Sender, TryIter};
use derivative::Derivative;
use dict_derive::IntoPyObject;
use crate::preprocess::build_index;
use fnv::{FnvHashMap, FnvHashSet};
use humantime::format_duration;
use permutohedron::LexicalPermutation;
@ -19,9 +20,25 @@ use std::thread;
use std::thread::JoinHandle;
use std::time::Instant;
const STATUS_INVERVAL: u128 = 500; //ms
const STATUS_INVERVAL: u128 = 5000; //ms
#[derive(Debug)]
struct Weight {
// TODO: implement
star_type: FnvHashMap<String, f32>,
dist_from_start: f32,
dist_to_goal: f32,
dist_to_point: Vec<(f32, [f32; 3])>,
}
impl Weight {
fn calc(&self, node: &TreeNode, dst: &TreeNode, src: &TreeNode) -> f32 {
let d_start = dist(&node.pos, &src.pos);
let d_goal = dist(&node.pos, &dst.pos);
return 0.0;
}
}
#[derive(Debug, Clone, IntoPyObject)]
pub struct SearchState {
pub mode: String,
pub system: String,
@ -48,7 +65,6 @@ pub struct RouteOpts {
pub keep_last: bool,
pub factor: Option<f32>,
pub mode: Mode,
pub prune: Option<(usize, f32)>,
pub systems: Vec<u32>,
pub callback: Box<dyn Fn(&SearchState) -> PyResult<PyObject>>,
pub workers: usize,
@ -58,9 +74,20 @@ pub struct RouteOpts {
#[allow(non_camel_case_types)]
pub enum Mode {
BFS,
BFS_old,
BiDir, // TODO: implement bidirectional BFS
Greedy,
AStar,
Shortest, // TODO: A-Star with distance as weight
}
#[derive(Debug)]
#[allow(non_camel_case_types)]
pub enum PrecomputeMode {
Full,
Route_From,
Route_To,
None
}
impl Mode {
@ -68,9 +95,9 @@ impl Mode {
let s = s.to_lowercase();
match s.as_ref() {
"bfs" => Ok(Mode::BFS),
"bfs_old" => Ok(Mode::BFS_old),
"greedy" => Ok(Mode::Greedy),
"astar" => Ok(Mode::AStar),
"bidir" => Ok(Mode::BiDir),
val => Err(format!("Invalid Mode: {}", val)),
}
}
@ -162,9 +189,25 @@ pub struct LineCache {
impl LineCache {
pub fn new(path: &PathBuf) -> Option<Arc<Mutex<Self>>> {
//TODO: Verify match between index file and csv file
let idx_path = path.with_extension("idx");
let cache =
bincode::deserialize_from(&mut BufReader::new(File::open(idx_path).ok()?)).ok()?;
if !idx_path.exists() {
eprintln!("No index found for {:?}, building...", path);
build_index(path).map_err(|e| {
eprintln!("Error creating index for {:?}: {}", path, e);
}).ok()?;
}
let cache = bincode::deserialize_from(&mut BufReader::new(
File::open(idx_path)
.map_err(|e| {
eprintln!("Error opening index for {:?}: {}", path, e);
})
.ok()?,
))
.map_err(|e| {
eprintln!("Reading index for {:?}: {}", path, e);
})
.ok()?;
let reader = csv::Reader::from_path(path).ok()?;
let ret = Self { reader, cache };
Some(Arc::new(Mutex::new(ret)))
@ -206,6 +249,7 @@ struct WorkUnit {
node: TreeNode,
depth: usize,
parent_id: Option<u32>,
range: f32,
}
#[derive(Debug)]
@ -218,30 +262,8 @@ enum WorkerSet {
},
}
fn neighbor_worker(
tree: &LargeNodeRTree<TreeNode>,
search_range: f32,
rx: Receiver<Option<WorkUnit>>,
tx: Sender<WorkUnit>,
) {
while let Ok(Some(unit)) = rx.recv() {
let range=search_range*unit.node.mult;
tree.locate_within_distance(unit.node.pos, range*range)
.cloned()
.for_each(|nb| {
let wu = WorkUnit {
node: nb,
depth: unit.depth + 1,
parent_id: Some(unit.node.id),
};
tx.send(wu).unwrap();
});
}
drop(tx);
}
impl WorkerSet {
fn new(tree: Arc<LargeNodeRTree<TreeNode>>, search_range: f32, num_workers: usize) -> Self {
fn new(tree: Arc<LargeNodeRTree<TreeNode>>, num_workers: usize) -> Self {
if num_workers == 0 {
return WorkerSet::Empty;
}
@ -254,7 +276,7 @@ impl WorkerSet {
let tx = result_tx.clone();
let tree = tree.clone();
move || {
neighbor_worker(&tree, search_range, rx, tx);
Self::work(&tree, rx, tx);
}
})
})
@ -266,29 +288,62 @@ impl WorkerSet {
};
}
fn close(self) -> Result<(),String> {
if let WorkerSet::Workers{mut handles,tx,rx} = self {
let t_start=Instant::now();
fn work(tree: &LargeNodeRTree<TreeNode>, rx: Receiver<Option<WorkUnit>>, tx: Sender<WorkUnit>) {
while let Ok(Some(unit)) = rx.recv() {
let range = unit.range * unit.node.mult;
tree.locate_within_distance(unit.node.pos, range * range)
.cloned()
.for_each(|nb| {
let wu = WorkUnit {
node: nb,
depth: unit.depth + 1,
parent_id: Some(unit.node.id),
range: unit.range,
};
tx.send(wu).unwrap();
});
}
drop(tx);
}
fn resize(self, tree: Arc<LargeNodeRTree<TreeNode>>, num: usize) -> Result<Self, String> {
self.close()?;
return Ok(WorkerSet::new(tree.clone(), num));
}
// fn replace(self, tree: Arc<LargeNodeRTree<TreeNode>>) -> Result<Self, String> {
// let num=self.num();
// return self.resize(tree.clone(),num);
// }
fn close(self) -> Result<(), String> {
if let WorkerSet::Workers {
mut handles,
tx,
rx,
} = self
{
let t_start = Instant::now();
loop {
if (rx.len()==0) && (tx.len()==0) {
if (rx.len() == 0) && (tx.len() == 0) {
break;
}
rx.try_iter().for_each(|_| {});
};
}
for _ in &handles {
match tx.send(None) {
Ok(_) => {},
Ok(_) => {}
Err(e) => {
return Err(format!("{:?}",e));
return Err(format!("{:?}", e));
}
}
};
}
drop(tx);
while let Some(handle)= handles.pop() {
while let Some(handle) = handles.pop() {
handle.join().unwrap();
}
drop(rx);
println!("cleared in {}",format_duration(t_start.elapsed()));
println!("cleared in {}", format_duration(t_start.elapsed()));
}
return Ok(());
}
@ -296,12 +351,12 @@ impl WorkerSet {
fn queue_size(&self) -> usize {
match self {
WorkerSet::Empty => 0,
WorkerSet::Workers{rx,tx,..} => tx.len() + rx.len()
WorkerSet::Workers { rx, tx, .. } => tx.len() + rx.len(),
}
}
fn queue_empty(&self) -> bool {
return self.queue_size()==0;
return self.queue_size() == 0;
}
fn send(&self, wu: WorkUnit) -> Result<(), SendError<Option<WorkUnit>>> {
@ -331,14 +386,10 @@ impl WorkerSet {
// impl Iterator<Item = &TreeNode>
fn iter(&self) -> Result<TryIter<WorkUnit>,String> {
fn iter(&self) -> Result<TryIter<WorkUnit>, String> {
match self {
WorkerSet::Empty => {
Err("can't iterate on empty WorkerSet".to_string())
}
WorkerSet::Workers { rx, .. } => {
Ok(rx.try_iter())
}
WorkerSet::Empty => Err("can't iterate on empty WorkerSet".to_string()),
WorkerSet::Workers { rx, .. } => Ok(rx.try_iter()),
}
}
@ -351,28 +402,43 @@ impl WorkerSet {
// }
}
#[derive(Derivative)]
#[derivative(Debug)]
pub struct Router {
#[derivative(Debug = "ignore")]
tree: Arc<LargeNodeRTree<TreeNode>>,
#[derivative(Debug = "ignore")]
scoopable: FnvHashSet<u32>,
#[derivative(Debug = "ignore")]
pub route_tree: Option<FnvHashMap<u32, u32>>,
#[derivative(Debug = "ignore")]
pub cache: Option<Arc<Mutex<LineCache>>>,
range: f32,
primary_only: bool,
path: PathBuf,
prune: Option<(usize, f32)>,
pub path: PathBuf,
#[derivative(Debug = "ignore")]
workers: WorkerSet,
callback: Box<dyn Fn(&SearchState) -> PyResult<PyObject>>,
#[derivative(Debug = "ignore")]
pub callback: Box<dyn Fn(&SearchState) -> PyResult<PyObject>>,
}
impl Router {
pub fn new(
path: &PathBuf,
range: f32,
prune: Option<(usize, f32)>,
primary_only: bool,
num_workers: usize,
callback: Box<dyn Fn(&SearchState) -> PyResult<PyObject>>,
) -> Result<Self, String> {
pub fn new(callback: Box<dyn Fn(&SearchState) -> PyResult<PyObject>>) -> Result<Self, String> {
let ret = Self {
tree: Arc::new(LargeNodeRTree::default()),
scoopable: FnvHashSet::default(),
route_tree: None,
cache: None,
callback,
workers: WorkerSet::Empty,
path: PathBuf::from(""),
};
Ok(ret)
}
pub fn load(&mut self, path: &PathBuf) -> Result<(), String> {
if self.path == path.to_path_buf() {
return Ok(());
}
self.tree = Arc::new(LargeNodeRTree::default()); // clear R*-Tree
let mut scoopable = FnvHashSet::default();
let mut reader = match csv::ReaderBuilder::new().from_path(path) {
Ok(rdr) => rdr,
@ -386,9 +452,9 @@ impl Router {
.deserialize::<SystemSerde>()
.filter_map(|res| {
let sys = res.expect("Failed to read");
if primary_only && sys.distance != 0 {
if sys.distance != 0 {
return None;
};
}
if sys.mult > 1.0f32 {
scoopable.insert(sys.id);
} else {
@ -408,37 +474,28 @@ impl Router {
format_duration(t_load.elapsed())
);
let t_load = Instant::now();
let tree = Arc::new(LargeNodeRTree::bulk_load_with_params(systems));
let workers = WorkerSet::new(Arc::clone(&tree), range, num_workers);
self.tree = Arc::new(LargeNodeRTree::bulk_load_with_params(systems));
self.path = path.to_path_buf();
self.cache = LineCache::new(&path.to_path_buf());
self.scoopable = scoopable;
println!("R*-Tree built in {}", format_duration(t_load.elapsed()));
let ret = Self {
tree,
scoopable,
route_tree: None,
range,
primary_only,
cache: LineCache::new(path),
path: path.clone(),
callback,
prune,
workers,
};
Ok(ret)
Ok(())
}
pub fn start_workers(&mut self, num: usize) -> Result<(), String> {
let mut w = WorkerSet::Empty;
std::mem::swap(&mut self.workers, &mut w);
self.workers = w.resize(self.tree.clone(), num)?;
Ok(())
}
pub fn from_file(
filename: &PathBuf,
callback: Box<dyn Fn(&SearchState) -> PyResult<PyObject>>,
) -> Result<(PathBuf, Self), String> {
) -> Result<(PathBuf, f32, Self), String> {
let mut reader = BufReader::new(match File::open(&filename) {
Ok(fh) => fh,
Err(e) => {
return Err(format!(
"Error opening file {}: {}",
filename.display(),
e
))
}
Err(e) => return Err(format!("Error opening file {}: {}", filename.display(), e)),
});
println!("Loading {}", filename.display());
let (primary, range, file_hash, path, route_tree): (
@ -449,13 +506,7 @@ impl Router {
FnvHashMap<u32, u32>,
) = match bincode::deserialize_from(&mut reader) {
Ok(res) => res,
Err(e) => {
return Err(format!(
"Error loading file {}: {}",
filename.display(),
e
))
}
Err(e) => return Err(format!("Error loading file {}: {}", filename.display(), e)),
};
if hash_file(&path) != file_hash {
return Err("File hash mismatch!".to_string());
@ -463,16 +514,14 @@ impl Router {
let cache = LineCache::new(&path);
Ok((
path.clone(),
range,
Self {
tree: Arc::new(RTree::default()),
scoopable: FnvHashSet::default(),
route_tree: Some(route_tree),
range,
cache,
primary_only: primary,
path,
callback,
prune: None,
workers: WorkerSet::Empty,
},
))
@ -482,8 +531,16 @@ impl Router {
self.tree.locate_within_distance(*center, radius * radius)
}
fn neighbours(&self, node: &TreeNode) -> impl Iterator<Item = &TreeNode> {
self.points_in_sphere(&node.pos, node.mult * self.range)
fn neighbours(&self, node: &TreeNode, range: f32) -> impl Iterator<Item = &TreeNode> {
self.points_in_sphere(&node.pos, node.mult * range)
}
fn neighbours_r(&self, node: &TreeNode, range: f32) -> impl Iterator<Item = &TreeNode> {
let pos = node.pos.clone();
self.points_in_sphere(&node.pos, range * 4.0)
.filter(move |s| {
return s.dist2(&pos) < (range * s.mult) * (range * s.mult);
})
}
fn valid(&self, id: u32) -> bool {
@ -492,11 +549,13 @@ impl Router {
}
pub fn best_multiroute(
&self,
&mut self,
waypoints: &[System],
range: f32,
keep: (bool, bool),
mode: Mode,
factor: f32,
beam_width: usize,
num_workers: usize,
) -> Result<Vec<System>, String> {
let mut best_score: f32 = std::f32::MAX;
let mut waypoints = waypoints.to_owned();
@ -529,16 +588,33 @@ impl Router {
}
}
println!("Best permutation: {:?}", best_permutation_waypoints);
self.multiroute(&best_permutation_waypoints, mode, factor)
self.multiroute(
&best_permutation_waypoints,
range,
factor,
beam_width,
num_workers,
)
}
pub fn multiroute(
&self,
&mut self,
waypoints: &[System],
mode: Mode,
range: f32,
factor: f32,
beam_width: usize,
num_workers: usize,
) -> Result<Vec<System>, String> {
if self.tree.size() == 0 {
return Err("No Systems loaded, pleased load some with the 'load' method!".to_string());
}
if factor < 0.0 || factor > 1.0 {
return Err("Factor needs to be between 0.0 (BFS) and 1.0 (Greedy Search)".to_string());
}
let mut route: Vec<System> = Vec::new();
if factor == 0.0 {
self.start_workers(num_workers)?;
}
for pair in waypoints.windows(2) {
match pair {
[src, dst] => {
@ -549,16 +625,11 @@ impl Router {
);
println!(
"Jump Range: {} Ly, Distance: {} Ly, Estimated Jumps: {}",
self.range,
range,
d_total,
d_total / self.range
d_total / range
);
let block = match mode {
Mode::BFS => self.route_bfs(&src, &dst)?,
Mode::BFS_old => self.route_bfs_old(&src, &dst)?,
Mode::Greedy => self.route_greedy(&src, &dst)?,
Mode::AStar => self.route_astar(&src, &dst, factor)?,
};
let block = self.route_astar(&src, &dst, factor, beam_width, range)?;
if route.is_empty() {
for sys in block.iter() {
route.push(sys.clone());
@ -582,9 +653,14 @@ impl Router {
src: &System,
dst: &System,
factor: f32,
beam_width: usize,
range: f32,
) -> Result<Vec<System>, String> {
if factor == 0.0 {
return self.route_bfs(src, dst);
return self.route_bfs(src, dst, range, beam_width);
}
if factor == 1.0 {
return self.route_greedy(src, dst, range, beam_width);
}
let src_name = src.system.clone();
let dst_name = dst.system.clone();
@ -614,8 +690,8 @@ impl Router {
let mut found = false;
let mut queue: Vec<(usize, usize, TreeNode)> = Vec::new();
queue.push((
0, // depth
(start_sys.distp(goal_sys) / self.range) as usize, // h
0, // depth
(start_sys.distp(goal_sys) / range) as usize, // h
start_sys.to_node(),
));
seen.insert(start_sys.id);
@ -647,7 +723,7 @@ impl Router {
break;
}
queue.extend(
self.neighbours(&node)
self.neighbours(&node, range)
.filter(|nb| (self.valid(nb.id) || (nb.id == goal_sys.id)))
.filter(|nb| seen.insert(nb.id))
.map(|nb| {
@ -656,14 +732,14 @@ impl Router {
if d_g < d_rem {
d_rem = d_g;
}
(depth + 1, (d_g / self.range) as usize, *nb)
(depth + 1, (d_g / (range * 4.0)) as usize, *nb)
}),
);
queue.sort_by(|b, a| {
let (a_0, a_1) = (a.0 as f32, a.1 as f32);
let (b_0, b_1) = (b.0 as f32, b.1 as f32);
let v_a = a_0 + a_1 * factor;
let v_b = b_0 + b_1 * factor;
let v_a = a_0 * (1.0 - factor) + a_1 * factor;
let v_b = b_0 * (1.0 - factor) + b_1 * factor;
fcmp(v_a, v_b)
});
// queue.reverse();
@ -693,7 +769,13 @@ impl Router {
Ok(v)
}
pub fn route_greedy(&self, src: &System, dst: &System) -> Result<Vec<System>, String> {
pub fn route_greedy(
&self,
src: &System,
dst: &System,
range: f32,
beam_width: usize,
) -> Result<Vec<System>, String> {
let src_name = src.system.clone();
let dst_name = dst.system.clone();
let start_sys = src;
@ -750,7 +832,7 @@ impl Router {
break;
}
queue.extend(
self.neighbours(&node)
self.neighbours(&node, range)
.filter(|nb| (self.valid(nb.id) || (nb.id == goal_sys.id)))
.filter(|nb| seen.insert(nb.id))
.map(|nb| {
@ -762,8 +844,7 @@ impl Router {
(d_g, depth + 1, nb.clone())
}),
);
queue.sort_by(|a, b| fcmp(a.0, b.0).then(a.1.cmp(&b.1)));
queue.reverse();
queue.sort_by(|a, b| fcmp(b.0, a.0).then(b.1.cmp(&a.1)));
}
if queue.is_empty() {
break;
@ -787,7 +868,18 @@ impl Router {
Ok(v)
}
pub fn precompute(&mut self, src: &System) -> Result<(), String> {
pub fn precompute_all(&mut self, range:f32) -> Result<(),String> {
// TODO: implement all-pairs shortest path based on optimized BFS
unimplemented!();
}
pub fn precompute_to(&mut self, dst: &System, range: f32) -> Result<(), String> {
// TODO: -> precompute to
unimplemented!();
}
pub fn precompute(&mut self, src: &System, range: f32) -> Result<(), String> {
// TODO: -> precompute from
let total = self.tree.size() as f32;
let t_start = Instant::now();
let mut prev = FnvHashMap::default();
@ -809,7 +901,7 @@ impl Router {
std::io::stdout().flush().unwrap();
while let Some((d, sys)) = queue.pop_front() {
queue_next.extend(
self.neighbours(&sys)
self.neighbours(&sys, range)
// .filter(|&nb| self.valid(nb))
.filter(|&nb| seen.insert(nb.id))
.map(|nb| {
@ -822,17 +914,23 @@ impl Router {
depth += 1;
}
self.route_tree = Some(prev);
let file_hash = hash_file(&self.path);
let file_hash_hex = file_hash
.iter()
.map(|v| format!("{:02x}", v))
.collect::<Vec<String>>()
.join("");
let ofn = format!(
"{}_{}{}.router",
"{}_{}_{}.router",
src.system.replace("*", "").replace(" ", "_"),
self.range,
if self.primary_only { "_primary" } else { "" }
range,
file_hash_hex
);
let mut out_fh = BufWriter::new(File::create(&ofn).unwrap());
let data = (
self.primary_only,
self.range,
hash_file(&self.path),
self.tree.size(),
range,
file_hash,
self.path.clone(),
self.route_tree.as_ref().unwrap(),
);
@ -913,6 +1011,9 @@ impl Router {
}
pub fn route_to(&self, dst: &System) -> Result<Vec<System>, String> {
if self.route_tree.is_none() {
return Err("Can't computer route without a precomputed route-tree".to_owned());
}
let prev = self.route_tree.as_ref().unwrap();
if !prev.contains_key(&dst.id) {
return Err(format!("System-ID {} not found", dst.id).to_string());
@ -943,9 +1044,15 @@ impl Router {
Ok(v)
}
pub fn route_bfs(&self, start_sys: &System, goal_sys: &System) -> Result<Vec<System>, String> {
pub fn route_bfs(
&self,
start_sys: &System,
goal_sys: &System,
range: f32,
beam_width: usize,
) -> Result<Vec<System>, String> {
if self.workers.is_empty() {
return self.route_bfs_old(start_sys, goal_sys);
return self.route_bfs_serial(start_sys, goal_sys, range, beam_width);
}
println!("Running BFS with {} worker(s)", self.workers.num());
let t_start = Instant::now();
@ -959,8 +1066,9 @@ impl Router {
node: start_sys.to_node(),
parent_id: None,
depth: 0,
range,
};
if wu.node.id==goal_sys.id {
if wu.node.id == goal_sys.id {
return Ok(vec![goal_sys.clone()]);
}
let mut found = false;
@ -968,7 +1076,7 @@ impl Router {
let d_total = dist(&start_sys.pos, &goal_sys.pos);
let mut d_rem = d_total;
let mut state = SearchState {
mode: "BFS".into(),
mode: format!("BFS_parallel({})", self.workers.num()),
depth: 0,
queue_size: 0,
d_rem,
@ -1019,14 +1127,18 @@ impl Router {
}
})
.collect();
if nbs.is_empty() && workers.queue_empty() && seen.len()>1 {
if nbs.is_empty() && workers.queue_empty() && seen.len() > 1 {
break;
}
// nbs.sort_by(|a, b| {
// let d_a=a.node.dist2(&goal_sys.pos);
// let d_b=b.node.dist2(&goal_sys.pos);
// return a.depth.cmp(&b.depth).then(fcmp(d_a,d_b));
// });
if beam_width != 0 && nbs.len() > beam_width {
nbs.sort_by(|a, b| {
let d_a = a.node.dist2(&goal_sys.pos);
let d_b = b.node.dist2(&goal_sys.pos);
return fcmp(d_a, d_b);
});
nbs = nbs.iter().take(beam_width).cloned().collect();
}
while let Some(wu) = nbs.pop() {
if let Some(parent_id) = wu.parent_id {
prev.insert(wu.node.id, parent_id);
@ -1065,25 +1177,24 @@ impl Router {
Ok(v)
}
pub fn route_bfs_old(
pub fn route_bfs_serial(
&self,
start_sys: &System,
goal_sys: &System,
range: f32,
beam_width: usize,
) -> Result<Vec<System>, String> {
if start_sys.id==goal_sys.id {
if start_sys.id == goal_sys.id {
return Ok(vec![goal_sys.clone()]);
}
let t_start = Instant::now();
println!("Running BFS");
if self.prune.is_some() {
println!("WARNING: search pruning is not implemented!");
}
let src_name = start_sys.system.clone();
let dst_name = goal_sys.system.clone();
let d_total = dist(&start_sys.pos, &goal_sys.pos);
let mut d_rem = d_total;
let mut state = SearchState {
mode: "BFS_old".into(),
mode: "BFS_serial".into(),
depth: 0,
queue_size: 0,
d_rem,
@ -1120,7 +1231,7 @@ impl Router {
state.d_rem = d_rem;
state.n_seen = seen.len();
state.prc_seen = ((seen.len() * 100) as f32) / total;
{
if !queue.is_empty() {
let s = queue.get(0).unwrap().get(&self).unwrap();
state.system = s.system.clone();
state.body = s.body.clone();
@ -1134,7 +1245,7 @@ impl Router {
t_last = Instant::now();
}
let valid_nbs = self
.neighbours(&node)
.neighbours(&node, range)
.filter(|nb| (self.valid(nb.id) || (nb.id == goal_sys.id)))
.filter(|nb| seen.insert(nb.id))
.map(|nb| {
@ -1147,7 +1258,25 @@ impl Router {
});
queue_next.extend(valid_nbs);
}
std::mem::swap(&mut queue, &mut queue_next);
if beam_width != 0 {
let mut q = Vec::new();
while let Some(v) = queue_next.pop_front() {
q.push(v);
}
q.sort_by(|a, b| {
let d_a = a.dist2(&goal_sys.pos);
let d_b = b.dist2(&goal_sys.pos);
return fcmp(d_a, d_b);
});
queue.clear();
for v in q.iter().take(beam_width).cloned() {
queue.push_back(v);
}
queue_next.clear();
} else {
std::mem::swap(&mut queue, &mut queue_next);
}
if found {
break;
}
@ -1179,67 +1308,21 @@ impl Router {
}
}
pub fn route(opts: RouteOpts) -> Result<Option<Vec<System>>, String> {
// TODO: implement pruning (check if dist to target improved by at least $n*jump_range$ Ly in the last $m$ steps)
if opts.systems.is_empty() {
if opts.precomp_file.is_some() {
return Err("Error: Please specify exatly one system".to_owned());
} else if opts.precompute {
return Err("Error: Please specify at least one system".to_owned());
} else {
return Err("Error: Please specify at least two systems".to_owned());
};
impl Router {
pub fn computer_route(
&mut self,
sys_ids: &[u32],
range: f32,
factor: f32,
beam_width: usize,
num_workers: usize,
) -> Result<Vec<System>, String> {
let id_map = self.get_systems_by_ids(sys_ids)?;
let hops: Vec<System> = sys_ids
.iter()
.map(|id| id_map.get(&id).unwrap())
.cloned()
.collect();
self.multiroute(&hops, range, factor, beam_width, num_workers)
}
let mut router: Router = if opts.precomp_file.is_some() {
let (_, ret) =
Router::from_file(&opts.precomp_file.clone().unwrap(), Box::new(opts.callback))?;
ret
} else if opts.range.is_some() {
Router::new(
&opts.file_path,
opts.range.unwrap(),
opts.prune,
opts.primary,
opts.workers,
Box::new(opts.callback),
)?
} else {
Router::new(
&opts.file_path,
opts.range.unwrap(),
opts.prune,
opts.primary,
opts.workers,
opts.callback,
)?
};
let mut systems: Vec<System> = Vec::new();
let sys_ht = router.get_systems_by_ids(&opts.systems)?;
for sys in opts.systems {
systems.push(sys_ht.get(&sys).unwrap().clone());
}
if opts.precompute {
for sys in systems {
router.route_tree = None;
router.precompute(&sys)?;
}
return Ok(None);
}
let route = if router.route_tree.is_some() {
router.route_to(systems.first().unwrap())?
} else if opts.permute {
router.best_multiroute(
&systems,
(opts.keep_first, opts.keep_last),
opts.mode,
opts.factor.unwrap_or(1.0),
)?
} else {
router.multiroute(&systems, opts.mode, opts.factor.unwrap_or(1.0))?
};
router.workers.close()?;
if route.is_empty() {
return Err("No route found!".to_string());
}
Ok(Some(route))
}