Bug 1681957 - Migrate gecko-fuzz-targets away from rkv 0.10. r=vporof

Differential Revision: https://phabricator.services.mozilla.com/D99453
This commit is contained in:
Xidorn Quan 2020-12-12 08:32:40 +00:00
Родитель 556f400fb6
Коммит 5b6e237eec
31 изменённых файлов: 32 добавлений и 5565 удалений

30
Cargo.lock сгенерированный
Просмотреть файл

@ -525,7 +525,7 @@ dependencies = [
"nserror",
"nsstring",
"rental",
"rkv 0.16.1",
"rkv",
"rust_cascade",
"sha2",
"storage_variant",
@ -1712,7 +1712,7 @@ dependencies = [
"lazy_static",
"libc",
"lmdb-rkv",
"rkv 0.10.4",
"rkv",
"tempfile",
]
@ -2088,7 +2088,7 @@ dependencies = [
"flate2",
"log",
"once_cell",
"rkv 0.16.1",
"rkv",
"serde",
"serde_json",
"uuid",
@ -2655,7 +2655,7 @@ dependencies = [
"moz_task",
"nserror",
"nsstring",
"rkv 0.16.1",
"rkv",
"storage_variant",
"tempfile",
"thin-vec",
@ -4246,26 +4246,6 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c2b29d87cfbdce39849012bb5020fff88b8f01f4f5b55846a0b6ef360774eae"
[[package]]
name = "rkv"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30a3dbc1f4971372545ed4175f23ef206c81e5874cd574d153646e7ee78f6793"
dependencies = [
"arrayref",
"bincode",
"bitflags",
"byteorder",
"failure",
"lazy_static",
"lmdb-rkv",
"ordered-float",
"serde",
"serde_derive",
"url",
"uuid",
]
[[package]]
name = "rkv"
version = "0.16.1"
@ -6066,7 +6046,7 @@ dependencies = [
"nserror",
"nsstring",
"once_cell",
"rkv 0.16.1",
"rkv",
"serde_json",
"tempfile",
"xpcom",

Просмотреть файл

@ -1 +0,0 @@
{"files":{"CODE_OF_CONDUCT.md":"902d5357af363426631d907e641e220b3ec89039164743f8442b3f120479b7cf","Cargo.lock":"a53a3ee5e3aa691db3a5580e6d623cd0762dba8d081eb6de893211a7791669f9","Cargo.toml":"0bb154d5139e53f095919e033abd41a72ea22db685a7a052c96087a09819d479","LICENSE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","README.md":"c75566740e7f581fe4cbd44ad82cabad5f2665bd72a4519c17a7f98fc69a5703","examples/README.md":"143767fc145bf167ce269a65138cb3f7086cb715b8bc4f73626da82966e646f4","examples/iterator.rs":"ddc3997e394a30ad82d78d2675a48c4617353f88b89bb9a3df5a3804d59b8ef9","examples/simple-store.rs":"cae63e39f2f98ee6ac2f387dcb02d6b929828a74f32f7d18d69c7fc9c3cce765","run-all-examples.sh":"7f9d11d01017f77e1c9d26e3e82dfca8c6930deaec85e864458e33a7fa267de0","src/bin/dump.rs":"da8543848e57893902751f4c4745e835b9c86263da2344af18d5717014f645f5","src/bin/rand.rs":"3da924fa0f1a118f606e2b94aee3a0553d9ebdbd17ee0152b85148adbf521bba","src/env.rs":"5deac6b35e49da1d47d7c852ed2e30ef96b6d15998fe7a79479cec64697626fc","src/error.rs":"f2cbab99691f36c98c24d297de3a303de258ddd3a06e2f54cb5efce20eb3740b","src/lib.rs":"4fe4e7d6a912a850b709ed23e372acd4f214890066322b4720376f7772bb776e","src/manager.rs":"ff2d76056e3a7200035b2e75c5bc2159f337e59c076dddd2476e3094b6ae3741","src/migrate.rs":"674cee0d027fc2eed3b09cebe686c837a97725099c967d8c2f49d19e793e6bfd","src/readwrite.rs":"fde695333e4845f4f53d63da6281f585919e2a3ac5cfe00d173cc139bc822763","src/store.rs":"409d13b1ea0d1254dae947ecbce50e741fb71c3ca118a78803b734336dce6a8f","src/store/integer.rs":"f386474c971f671c9b316a16ebff5b586be6837c886f443753ae13277a7e0070","src/store/integermulti.rs":"1a0912f97619297da31cc8c146e38941b88539d2857df81191a49c8dbd18625d","src/store/multi.rs":"2dec01c2202a2c9069cced4e1e42906b01d0b85df25d17e0ea810c05fa8395d0","src/store/single.rs":"c55c3600714f5ed9e820b16c2335ae00a0071174e0a32b9df89a34182a4b908c","src/value.rs":"7fae77a8291b951591e557ec694bfdadc9eb78557dad36a970cfcdcfb83fd238","tests/integer-store.rs":"f7e06c71b0dead2323c7c61fc8bcbffbdd3a4796eebf6138db9cce3dbba716a3","tests/manager.rs":"97ec61145dc227f4f5fbcb6449c096bbe5b9a09db4e61ff4491c0443fe9adf26","tests/multi-integer-store.rs":"83295b0135c502321304aa06b05d5a9eeab41b1438ed7ddf2cb1a3613dfef4d9","tests/test_txn.rs":"f486d8bd485398e49ae64eac59ca3b44dfa7f8340aab17483cd3e9864fadd88b"},"package":"30a3dbc1f4971372545ed4175f23ef206c81e5874cd574d153646e7ee78f6793"}

Просмотреть файл

@ -1,15 +0,0 @@
# Community Participation Guidelines
This repository is governed by Mozilla's code of conduct and etiquette guidelines.
For more details, please read the
[Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/).
## How to Report
For more information on how to report violations of the Community Participation Guidelines, please read our '[How to Report](https://www.mozilla.org/about/governance/policies/participation/reporting/)' page.
<!--
## Project Specific Etiquette
In some cases, there will be additional project etiquette i.e.: (https://bugzilla.mozilla.org/page.cgi?id=etiquette.html).
Please update for your project.
-->

418
third_party/rust/rkv-0.10.4/Cargo.lock сгенерированный поставляемый
Просмотреть файл

@ -1,418 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "arrayref"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
[[package]]
name = "autocfg"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
[[package]]
name = "backtrace"
version = "0.3.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad235dabf00f36301792cfe82499880ba54c6486be094d1047b02bacb67c14e8"
dependencies = [
"backtrace-sys",
"cfg-if",
"libc",
"rustc-demangle",
]
[[package]]
name = "backtrace-sys"
version = "0.1.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e17b52e737c40a7d75abca20b29a19a0eb7ba9fc72c5a72dd282a0a3c2c0dc35"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "bincode"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5753e2a71534719bf3f4e57006c3a4f0d2c672a4b676eec84161f763eca87dbf"
dependencies = [
"byteorder",
"serde",
]
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "byteorder"
version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
[[package]]
name = "cc"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "failure"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8529c2421efa3066a5cbd8063d2244603824daccb6936b079010bb2aa89464b"
dependencies = [
"backtrace",
"failure_derive",
]
[[package]]
name = "failure_derive"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "030a733c8287d6213886dd487564ff5c8f6aae10278b3588ed177f9d18f8d231"
dependencies = [
"proc-macro2",
"quote",
"syn",
"synstructure",
]
[[package]]
name = "getrandom"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "idna"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
dependencies = [
"matches",
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018"
[[package]]
name = "lmdb-rkv"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "447a296f7aca299cfbb50f4e4f3d49451549af655fb7215d7f8c0c3d64bad42b"
dependencies = [
"bitflags",
"byteorder",
"libc",
"lmdb-rkv-sys",
]
[[package]]
name = "lmdb-rkv-sys"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b27470ac25167b3afdfb6af8fcd3bc1be67de50ffbdaf4073378cfded6ae24a5"
dependencies = [
"cc",
"libc",
"pkg-config",
]
[[package]]
name = "matches"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
[[package]]
name = "num-traits"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
dependencies = [
"autocfg",
]
[[package]]
name = "ordered-float"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518"
dependencies = [
"num-traits",
]
[[package]]
name = "percent-encoding"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
name = "pkg-config"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
[[package]]
name = "ppv-lite86"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
[[package]]
name = "proc-macro2"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom",
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core",
]
[[package]]
name = "redox_syscall"
version = "0.1.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
[[package]]
name = "remove_dir_all"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
dependencies = [
"winapi",
]
[[package]]
name = "rkv"
version = "0.10.4"
dependencies = [
"arrayref",
"bincode",
"bitflags",
"byteorder",
"failure",
"lazy_static",
"lmdb-rkv",
"ordered-float",
"serde",
"serde_derive",
"tempfile",
"url",
"uuid",
]
[[package]]
name = "rustc-demangle"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
[[package]]
name = "serde"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449"
[[package]]
name = "serde_derive"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "smallvec"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc"
[[package]]
name = "syn"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "synstructure"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
dependencies = [
"proc-macro2",
"quote",
"syn",
"unicode-xid",
]
[[package]]
name = "tempfile"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
dependencies = [
"cfg-if",
"libc",
"rand",
"redox_syscall",
"remove_dir_all",
"winapi",
]
[[package]]
name = "unicode-bidi"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
dependencies = [
"matches",
]
[[package]]
name = "unicode-normalization"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4"
dependencies = [
"smallvec",
]
[[package]]
name = "unicode-xid"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
[[package]]
name = "url"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb"
dependencies = [
"idna",
"matches",
"percent-encoding",
]
[[package]]
name = "uuid"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11"
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "winapi"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

75
third_party/rust/rkv-0.10.4/Cargo.toml поставляемый
Просмотреть файл

@ -1,75 +0,0 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
edition = "2018"
name = "rkv"
version = "0.10.4"
authors = ["Richard Newman <rnewman@twinql.com>", "Nan Jiang <najiang@mozilla.com>", "Myk Melez <myk@mykzilla.org>", "Victor Porof <vporof@mozilla.com>"]
exclude = ["/tests/envs/*"]
description = "a simple, humane, typed Rust interface to LMDB"
homepage = "https://github.com/mozilla/rkv"
documentation = "https://docs.rs/rkv"
readme = "README.md"
keywords = ["lmdb", "database", "storage"]
categories = ["database"]
license = "Apache-2.0"
repository = "https://github.com/mozilla/rkv"
[dependencies.arrayref]
version = "0.3"
[dependencies.bincode]
version = "1.0"
[dependencies.bitflags]
version = "1"
[dependencies.byteorder]
version = "1"
[dependencies.failure]
version = "0.1"
features = ["derive"]
default_features = false
[dependencies.lazy_static]
version = "1.0"
[dependencies.lmdb-rkv]
version = "0.14"
[dependencies.ordered-float]
version = "1.0"
[dependencies.serde]
version = "1.0"
[dependencies.serde_derive]
version = "1.0"
[dependencies.url]
version = "2.0"
[dependencies.uuid]
version = "0.8"
[dev-dependencies.byteorder]
version = "1"
[dev-dependencies.tempfile]
version = "3"
[features]
backtrace = ["failure/backtrace", "failure/std"]
default = []
with-asan = ["lmdb-rkv/with-asan"]
with-fuzzer = ["lmdb-rkv/with-fuzzer"]
with-fuzzer-no-link = ["lmdb-rkv/with-fuzzer-no-link"]

202
third_party/rust/rkv-0.10.4/LICENSE поставляемый
Просмотреть файл

@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

91
third_party/rust/rkv-0.10.4/README.md поставляемый
Просмотреть файл

@ -1,91 +0,0 @@
# rkv
[![Travis CI Build Status](https://travis-ci.org/mozilla/rkv.svg?branch=master)](https://travis-ci.org/mozilla/rkv)
[![Appveyor Build Status](https://ci.appveyor.com/api/projects/status/lk936u5y5bi6qafb/branch/master?svg=true)](https://ci.appveyor.com/project/mykmelez/rkv/branch/master)
[![Documentation](https://docs.rs/rkv/badge.svg)](https://docs.rs/rkv/)
[![Crate](https://img.shields.io/crates/v/rkv.svg)](https://crates.io/crates/rkv)
The [rkv Rust crate](https://crates.io/crates/rkv) is a simple, humane, typed key-value storage solution. It supports multiple backend engines with varying guarantees, such as [LMDB](http://www.lmdb.tech/doc/) for performance, or "SafeMode" for reliability.
This master branch only supports the LMDB backend. We're looking into supporting multiple backends, starting with "SafeMode" in the [feature branch](https://github.com/mozilla/rkv/tree/safe-mode).
## ⚠️ Warning ⚠️
The LMDB backend is currently unstable and crash-prone. We're attempting to fix these crashes in bugs [1538539](https://bugzilla.mozilla.org/show_bug.cgi?id=1538539), [1538541](https://bugzilla.mozilla.org/show_bug.cgi?id=1538541) and [1550174](https://bugzilla.mozilla.org/show_bug.cgi?id=1550174).
To use rkv in production/release environments at Mozilla, you may do so with the "SafeMode" backend, for example:
```toml
rkv = { git = "https://github.com/mozilla/rkv", branch="safe-mode", default-features = false }
```
```rust
use rkv::{Manager, Rkv};
use rkv::backend::{SafeMode, SafeModeEnvironment};
let mut manager = Manager::<SafeModeEnvironment>::singleton().write().unwrap();
let shared_rkv = manager.get_or_create(path, Rkv::new::<SafeMode>).unwrap();
...
```
Instead of a branch, we suggest using a specific `rev` instead. For example, `4a1cc23906865626fa715fd99d98620169d3fd7b` is the latest stable version for "safe-mode".
The "SafeMode` backend performs well, with two caveats: the entire database is stored in memory, and write transactions are synchronously written to disk on commit.
In the future, it will be advisable to switch to a different backend with better performance guarantees. We're working on either fixing the LMDB crashes, or offering more choices of backend engines (e.g. SQLite).
## Use
Comprehensive information about using rkv is available in its [online documentation](https://docs.rs/rkv/), which can also be generated for local consumption:
```sh
cargo doc --open
```
## Build
Build this project as you would build other Rust crates:
```sh
cargo build
```
### Features
There are several features that you can opt-in and out of when using rkv:
By default, `db-dup-sort` and `db-int-key` features offer high level database APIs which allow multiple values per key, and optimizations around integer-based keys respectively. Opt out of these default features when specifying the rkv dependency in your Cargo.toml file to disable them; doing so avoids a certain amount of overhead required to support them.
If you specify the `backtrace` feature, backtraces will be enabled in "failure"
errors. This feature is disabled by default.
To aid fuzzing efforts, `with-asan`, `with-fuzzer`, and `with-fuzzer-no-link` configure the build scripts responsible with compiling the underlying backing engines (e.g. LMDB) to build with these LLMV features enabled. Please refer to the official LLVM/Clang documentation on them for more informatiuon. These features are also disabled by default.
## Test
Test this project as you would test other Rust crates:
```sh
cargo test
```
The project includes unit and doc tests embedded in the `src/` files, integration tests in the `tests/` subdirectory, and usage examples in the `examples/` subdirectory. To ensure your changes don't break examples, also run them via the run-all-examples.sh shell script:
```sh
./run-all-examples.sh
```
Note: the test fixtures in the `tests/envs/` subdirectory aren't included in the package published to crates.io, so you must clone this repository in order to run the tests that depend on those fixtures or use the `rand` and `dump` executables to recreate them.
## Contribute
Of the various open source archetypes described in [A Framework for Purposeful Open Source](https://medium.com/mozilla-open-innovation/whats-your-open-source-strategy-here-are-10-answers-383221b3f9d3), the rkv project most closely resembles the Specialty Library, and we welcome contributions. Please report problems or ask questions using this repo's GitHub [issue tracker](https://github.com/mozilla/rkv/issues) and submit [pull requests](https://github.com/mozilla/rkv/pulls) for code and documentation changes.
rkv relies on the latest [rustfmt](https://github.com/rust-lang-nursery/rustfmt) for code formatting, so please make sure your pull request passes the rustfmt before submitting it for review. See rustfmt's [quick start](https://github.com/rust-lang-nursery/rustfmt#quick-start) for installation details.
We follow Mozilla's [Community Participation Guidelines](https://www.mozilla.org/en-US/about/governance/policies/participation/) while contributing to this project.
## License
The rkv source code is licensed under the Apache License, Version 2.0, as described in the [LICENSE](https://github.com/mozilla/rkv/blob/master/LICENSE) file.

Просмотреть файл

@ -1,11 +0,0 @@
## Examples of how to use rkv
All examples can be executed with:
```
cargo run --example $name
```
* [`simple-store`](simple-store.rs) - a simple key/value store that showcases the basic usage of rkv.
* [`iterator`](iterator.rs) - a demo that showcases the basic usage of iterators in rkv.

Просмотреть файл

@ -1,75 +0,0 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/publicdomain/zero/1.0/
//! A demo that showcases the basic usage of iterators in rkv.
//!
//! You can test this out by running:
//!
//! cargo run --example iterator
use rkv::{
Manager,
Rkv,
SingleStore,
StoreError,
StoreOptions,
Value,
};
use tempfile::Builder;
use std::fs;
use std::str;
fn main() {
let root = Builder::new().prefix("iterator").tempdir().unwrap();
fs::create_dir_all(root.path()).unwrap();
let p = root.path();
let created_arc = Manager::singleton().write().unwrap().get_or_create(p, Rkv::new).unwrap();
let k = created_arc.read().unwrap();
let store = k.open_single("store", StoreOptions::create()).unwrap();
populate_store(&k, store).unwrap();
let reader = k.read().unwrap();
println!("Iterating from the beginning...");
// Reader::iter_start() iterates from the first item in the store, and
// returns the (key, value) tuples in order.
let mut iter = store.iter_start(&reader).unwrap();
while let Some(Ok((country, city))) = iter.next() {
println!("{}, {:?}", str::from_utf8(country).unwrap(), city);
}
println!();
println!("Iterating from the given key...");
// Reader::iter_from() iterates from the first key equal to or greater
// than the given key.
let mut iter = store.iter_from(&reader, "Japan").unwrap();
while let Some(Ok((country, city))) = iter.next() {
println!("{}, {:?}", str::from_utf8(country).unwrap(), city);
}
println!();
println!("Iterating from the given prefix...");
let mut iter = store.iter_from(&reader, "Un").unwrap();
while let Some(Ok((country, city))) = iter.next() {
println!("{}, {:?}", str::from_utf8(country).unwrap(), city);
}
}
fn populate_store(k: &Rkv, store: SingleStore) -> Result<(), StoreError> {
let mut writer = k.write()?;
for (country, city) in vec![
("Canada", Value::Str("Ottawa")),
("United States of America", Value::Str("Washington")),
("Germany", Value::Str("Berlin")),
("France", Value::Str("Paris")),
("Italy", Value::Str("Rome")),
("United Kingdom", Value::Str("London")),
("Japan", Value::Str("Tokyo")),
] {
store.put(&mut writer, country, &city)?;
}
writer.commit()
}

Просмотреть файл

@ -1,183 +0,0 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/publicdomain/zero/1.0/
//! A simple rkv demo that showcases the basic usage (put/get/delete) of rkv.
//!
//! You can test this out by running:
//!
//! cargo run --example simple-store
use rkv::{
Manager,
MultiStore,
Rkv,
StoreOptions,
Value,
Writer,
};
use tempfile::Builder;
use std::fs;
fn getput<'env, 's>(store: MultiStore, writer: &'env mut Writer, ids: &'s mut Vec<String>) {
let keys = vec!["str1", "str2", "str3"];
// we convert the writer into a cursor so that we can safely read
for k in keys.iter() {
// this is a multi-valued database, so get returns an iterator
let mut iter = store.get(writer, k).unwrap();
while let Some(Ok((_key, val))) = iter.next() {
if let Value::Str(s) = val.unwrap() {
ids.push(s.to_owned());
} else {
panic!("didn't get a string back!");
}
}
}
for id in ids {
store.put(writer, &id, &Value::Blob(b"weeeeeee")).unwrap();
}
}
fn delete(store: MultiStore, writer: &mut Writer) {
let keys = vec!["str1", "str2", "str3"];
let vals = vec!["string uno", "string quatro", "string siete"];
// we convert the writer into a cursor so that we can safely read
for i in 0..keys.len() {
store.delete(writer, &keys[i], &Value::Str(vals[i])).unwrap();
}
}
fn main() {
let root = Builder::new().prefix("simple-db").tempdir().unwrap();
fs::create_dir_all(root.path()).unwrap();
let p = root.path();
// The manager enforces that each process opens the same lmdb environment at most once
let created_arc = Manager::singleton().write().unwrap().get_or_create(p, Rkv::new).unwrap();
let k = created_arc.read().unwrap();
// Creates a store called "store"
let store = k.open_single("store", StoreOptions::create()).unwrap();
let multistore = k.open_multi("multistore", StoreOptions::create()).unwrap();
println!("Inserting data...");
{
// Use a writer to mutate the store
let mut writer = k.write().unwrap();
store.put(&mut writer, "int", &Value::I64(1234)).unwrap();
store.put(&mut writer, "uint", &Value::U64(1234_u64)).unwrap();
store.put(&mut writer, "float", &Value::F64(1234.0.into())).unwrap();
store.put(&mut writer, "instant", &Value::Instant(1_528_318_073_700)).unwrap();
store.put(&mut writer, "boolean", &Value::Bool(true)).unwrap();
store.put(&mut writer, "string", &Value::Str("héllo, yöu")).unwrap();
store.put(&mut writer, "json", &Value::Json(r#"{"foo":"bar", "number": 1}"#)).unwrap();
store.put(&mut writer, "blob", &Value::Blob(b"blob")).unwrap();
writer.commit().unwrap();
}
println!("Testing getput");
{
let mut ids = Vec::new();
let mut writer = k.write().unwrap();
multistore.put(&mut writer, "str1", &Value::Str("string uno")).unwrap();
multistore.put(&mut writer, "str1", &Value::Str("string dos")).unwrap();
multistore.put(&mut writer, "str1", &Value::Str("string tres")).unwrap();
multistore.put(&mut writer, "str2", &Value::Str("string quatro")).unwrap();
multistore.put(&mut writer, "str2", &Value::Str("string cinco")).unwrap();
multistore.put(&mut writer, "str2", &Value::Str("string seis")).unwrap();
multistore.put(&mut writer, "str3", &Value::Str("string siete")).unwrap();
multistore.put(&mut writer, "str3", &Value::Str("string ocho")).unwrap();
multistore.put(&mut writer, "str3", &Value::Str("string nueve")).unwrap();
getput(multistore, &mut writer, &mut ids);
writer.commit().unwrap();
let mut writer = k.write().unwrap();
delete(multistore, &mut writer);
writer.commit().unwrap();
}
println!("Looking up keys...");
{
// Use a reader to query the store
let reader = k.read().unwrap();
println!("Get int {:?}", store.get(&reader, "int").unwrap());
println!("Get uint {:?}", store.get(&reader, "uint").unwrap());
println!("Get float {:?}", store.get(&reader, "float").unwrap());
println!("Get instant {:?}", store.get(&reader, "instant").unwrap());
println!("Get boolean {:?}", store.get(&reader, "boolean").unwrap());
println!("Get string {:?}", store.get(&reader, "string").unwrap());
println!("Get json {:?}", store.get(&reader, "json").unwrap());
println!("Get blob {:?}", store.get(&reader, "blob").unwrap());
println!("Get non-existent {:?}", store.get(&reader, "non-existent").unwrap());
}
println!("Looking up keys via Writer.get()...");
{
let mut writer = k.write().unwrap();
store.put(&mut writer, "foo", &Value::Str("bar")).unwrap();
store.put(&mut writer, "bar", &Value::Str("baz")).unwrap();
store.delete(&mut writer, "foo").unwrap();
println!("It should be None! ({:?})", store.get(&writer, "foo").unwrap());
println!("Get bar ({:?})", store.get(&writer, "bar").unwrap());
writer.commit().unwrap();
let reader = k.read().expect("reader");
println!("It should be None! ({:?})", store.get(&reader, "foo").unwrap());
println!("Get bar {:?}", store.get(&reader, "bar").unwrap());
}
println!("Aborting transaction...");
{
// Aborting a write transaction rollbacks the change(s)
let mut writer = k.write().unwrap();
store.put(&mut writer, "foo", &Value::Str("bar")).unwrap();
writer.abort();
let reader = k.read().expect("reader");
println!("It should be None! ({:?})", store.get(&reader, "foo").unwrap());
// Explicitly aborting a transaction is not required unless an early
// abort is desired, since both read and write transactions will
// implicitly be aborted once they go out of scope.
}
println!("Deleting keys...");
{
// Deleting a key/value also requires a write transaction
let mut writer = k.write().unwrap();
store.put(&mut writer, "foo", &Value::Str("bar")).unwrap();
store.delete(&mut writer, "foo").unwrap();
println!("It should be None! ({:?})", store.get(&writer, "foo").unwrap());
writer.commit().unwrap();
// Committing a transaction consumes the writer, preventing you
// from reusing it by failing and reporting a compile-time error.
// This line would report error[E0382]: use of moved value: `writer`.
// store.put(&mut writer, "baz", &Value::Str("buz")).unwrap();
}
println!("Clearing store...");
{
// Clearing a store deletes all the entries in that store
let mut writer = k.write().unwrap();
store.put(&mut writer, "foo", &Value::Str("bar")).unwrap();
store.put(&mut writer, "bar", &Value::Str("baz")).unwrap();
store.clear(&mut writer).unwrap();
writer.commit().unwrap();
let reader = k.read().expect("reader");
println!("It should be None! ({:?})", store.get(&reader, "foo").unwrap());
println!("It should be None! ({:?})", store.get(&reader, "bar").unwrap());
}
println!("Write and read on multiple stores...");
{
let another_store = k.open_single("another_store", StoreOptions::create()).unwrap();
let mut writer = k.write().unwrap();
store.put(&mut writer, "foo", &Value::Str("bar")).unwrap();
another_store.put(&mut writer, "foo", &Value::Str("baz")).unwrap();
writer.commit().unwrap();
let reader = k.read().unwrap();
println!("Get from store value: {:?}", store.get(&reader, "foo").unwrap());
println!("Get from another store value: {:?}", another_store.get(&reader, "foo").unwrap());
}
println!("Environment statistics: btree depth = {}", k.stat().unwrap().depth());
}

Просмотреть файл

@ -1,14 +0,0 @@
#!/bin/bash
set -e
cargo build --examples
for file in examples/*; do
filename=$(basename ${file})
extension=${filename##*.}
example_name=${filename%.*}
if [[ "${extension}" = "rs" ]]; then
cargo run --example ${example_name}
fi
done

55
third_party/rust/rkv-0.10.4/src/bin/dump.rs поставляемый
Просмотреть файл

@ -1,55 +0,0 @@
// Copyright 2018-2019 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
extern crate rkv;
use rkv::{
error::MigrateError,
migrate::Migrator,
};
use std::{
env::args,
io,
path::Path,
};
fn main() -> Result<(), MigrateError> {
let mut cli_args = args();
let mut db_name = None;
let mut env_path = None;
// The first arg is the name of the program, which we can ignore.
cli_args.next();
while let Some(arg) = cli_args.next() {
if &arg[0..1] == "-" {
match &arg[1..] {
"s" => {
db_name = match cli_args.next() {
None => return Err("-s must be followed by database name".into()),
Some(str) => Some(str),
};
},
str => return Err(format!("arg -{} not recognized", str).into()),
}
} else {
if env_path.is_some() {
return Err("must provide only one path to the LMDB environment".into());
}
env_path = Some(arg);
}
}
let env_path = env_path.ok_or("must provide a path to the LMDB environment")?;
let mut migrator: Migrator = Migrator::new(Path::new(&env_path))?;
migrator.dump(db_name.as_ref().map(String::as_str), io::stdout()).unwrap();
Ok(())
}

114
third_party/rust/rkv-0.10.4/src/bin/rand.rs поставляемый
Просмотреть файл

@ -1,114 +0,0 @@
// Copyright 2018-2019 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//! A command-line utility to create an LMDB environment containing random data.
//! It requires one flag, `-s path/to/environment`, which specifies the location
//! where the tool should create the environment. Optionally, you may specify
//! the number of key/value pairs to create via the `-n <number>` flag
//! (for which the default value is 50).
extern crate rkv;
use rkv::{
Rkv,
SingleStore,
StoreOptions,
Value,
};
use std::{
env::args,
fs::{
create_dir_all,
File,
},
io::Read,
path::Path,
};
fn main() {
let mut args = args();
let mut database = None;
let mut path = None;
let mut num_pairs = 50;
// The first arg is the name of the program, which we can ignore.
args.next();
while let Some(arg) = args.next() {
if &arg[0..1] == "-" {
match &arg[1..] {
"s" => {
database = match args.next() {
None => panic!("-s must be followed by database arg"),
Some(str) => Some(str),
};
},
"n" => {
num_pairs = match args.next() {
None => panic!("-s must be followed by number of pairs"),
Some(str) => str.parse().expect("number"),
};
},
str => panic!("arg -{} not recognized", str),
}
} else {
if path.is_some() {
panic!("must provide only one path to the LMDB environment");
}
path = Some(arg);
}
}
if path.is_none() {
panic!("must provide a path to the LMDB environment");
}
let path = path.unwrap();
create_dir_all(&path).expect("dir created");
let mut builder = Rkv::environment_builder();
builder.set_max_dbs(2);
// Allocate enough map to accommodate the largest random collection.
// We currently do this by allocating twice the maximum possible size
// of the pairs (assuming maximum key and value sizes).
builder.set_map_size((511 + 65535) * num_pairs * 2);
let rkv = Rkv::from_env(Path::new(&path), builder).expect("Rkv");
let store: SingleStore =
rkv.open_single(database.as_ref().map(|x| x.as_str()), StoreOptions::create()).expect("opened");
let mut writer = rkv.write().expect("writer");
// Generate random values for the number of keys and key/value lengths.
// On Linux, "Just use /dev/urandom!" <https://www.2uo.de/myths-about-urandom/>.
// On macOS it doesn't matter (/dev/random and /dev/urandom are identical).
let mut random = File::open("/dev/urandom").unwrap();
let mut nums = [0u8; 4];
random.read_exact(&mut nums).unwrap();
// Generate 0–255 pairs.
for _ in 0..num_pairs {
// Generate key and value lengths. The key must be 1–511 bytes long.
// The value length can be 0 and is essentially unbounded; we generate
// value lengths of 0–0xffff (65535).
// NB: the modulus method for generating a random number within a range
// introduces distribution skew, but we don't need it to be perfect.
let key_len = ((u16::from(nums[0]) + (u16::from(nums[1]) << 8)) % 511 + 1) as usize;
let value_len = (u16::from(nums[2]) + (u16::from(nums[3]) << 8)) as usize;
let mut key: Vec<u8> = vec![0; key_len];
random.read_exact(&mut key[0..key_len]).unwrap();
let mut value: Vec<u8> = vec![0; value_len];
random.read_exact(&mut value[0..value_len]).unwrap();
store.put(&mut writer, key, &Value::Blob(&value)).expect("wrote");
}
writer.commit().expect("committed");
}

1336
third_party/rust/rkv-0.10.4/src/env.rs поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

190
third_party/rust/rkv-0.10.4/src/error.rs поставляемый
Просмотреть файл

@ -1,190 +0,0 @@
// Copyright 2018-2019 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use std::path::PathBuf;
use bincode;
use failure::Fail;
use lmdb;
use crate::value::Type;
#[derive(Debug, Fail)]
pub enum DataError {
#[fail(display = "unknown type tag: {}", _0)]
UnknownType(u8),
#[fail(display = "unexpected type tag: expected {}, got {}", expected, actual)]
UnexpectedType {
expected: Type,
actual: Type,
},
#[fail(display = "empty data; expected tag")]
Empty,
#[fail(display = "invalid value for type {}: {}", value_type, err)]
DecodingError {
value_type: Type,
err: Box<bincode::ErrorKind>,
},
#[fail(display = "couldn't encode value: {}", _0)]
EncodingError(Box<bincode::ErrorKind>),
#[fail(display = "invalid uuid bytes")]
InvalidUuid,
}
impl From<Box<bincode::ErrorKind>> for DataError {
fn from(e: Box<bincode::ErrorKind>) -> DataError {
DataError::EncodingError(e)
}
}
#[derive(Debug, Fail)]
pub enum StoreError {
#[fail(display = "I/O error: {:?}", _0)]
IoError(::std::io::Error),
#[fail(display = "directory does not exist or not a directory: {:?}", _0)]
DirectoryDoesNotExistError(PathBuf),
#[fail(display = "data error: {:?}", _0)]
DataError(DataError),
#[fail(display = "lmdb error: {}", _0)]
LmdbError(lmdb::Error),
#[fail(display = "read transaction already exists in thread {:?}", _0)]
ReadTransactionAlreadyExists(::std::thread::ThreadId),
#[fail(display = "attempted to open DB during transaction in thread {:?}", _0)]
OpenAttemptedDuringTransaction(::std::thread::ThreadId),
}
impl StoreError {
pub fn open_during_transaction() -> StoreError {
StoreError::OpenAttemptedDuringTransaction(::std::thread::current().id())
}
}
impl From<lmdb::Error> for StoreError {
fn from(e: lmdb::Error) -> StoreError {
match e {
lmdb::Error::BadRslot => StoreError::ReadTransactionAlreadyExists(::std::thread::current().id()),
e => StoreError::LmdbError(e),
}
}
}
impl From<DataError> for StoreError {
fn from(e: DataError) -> StoreError {
StoreError::DataError(e)
}
}
impl From<::std::io::Error> for StoreError {
fn from(e: ::std::io::Error) -> StoreError {
StoreError::IoError(e)
}
}
#[derive(Debug, Fail)]
pub enum MigrateError {
#[fail(display = "database not found: {:?}", _0)]
DatabaseNotFound(String),
#[fail(display = "{}", _0)]
FromString(String),
#[fail(display = "couldn't determine bit depth")]
IndeterminateBitDepth,
#[fail(display = "I/O error: {:?}", _0)]
IoError(::std::io::Error),
#[fail(display = "invalid DatabaseFlags bits")]
InvalidDatabaseBits,
#[fail(display = "invalid data version")]
InvalidDataVersion,
#[fail(display = "invalid magic number")]
InvalidMagicNum,
#[fail(display = "invalid NodeFlags bits")]
InvalidNodeBits,
#[fail(display = "invalid PageFlags bits")]
InvalidPageBits,
#[fail(display = "invalid page number")]
InvalidPageNum,
#[fail(display = "lmdb error: {}", _0)]
LmdbError(lmdb::Error),
#[fail(display = "string conversion error")]
StringConversionError,
#[fail(display = "TryFromInt error: {:?}", _0)]
TryFromIntError(::std::num::TryFromIntError),
#[fail(display = "unexpected Page variant")]
UnexpectedPageVariant,
#[fail(display = "unexpected PageHeader variant")]
UnexpectedPageHeaderVariant,
#[fail(display = "unsupported PageHeader variant")]
UnsupportedPageHeaderVariant,
#[fail(display = "UTF8 error: {:?}", _0)]
Utf8Error(::std::str::Utf8Error),
}
impl From<::std::io::Error> for MigrateError {
fn from(e: ::std::io::Error) -> MigrateError {
MigrateError::IoError(e)
}
}
impl From<::std::str::Utf8Error> for MigrateError {
fn from(e: ::std::str::Utf8Error) -> MigrateError {
MigrateError::Utf8Error(e)
}
}
impl From<::std::num::TryFromIntError> for MigrateError {
fn from(e: ::std::num::TryFromIntError) -> MigrateError {
MigrateError::TryFromIntError(e)
}
}
impl From<&str> for MigrateError {
fn from(e: &str) -> MigrateError {
MigrateError::FromString(e.to_string())
}
}
impl From<String> for MigrateError {
fn from(e: String) -> MigrateError {
MigrateError::FromString(e)
}
}
impl From<lmdb::Error> for MigrateError {
fn from(e: lmdb::Error) -> MigrateError {
match e {
e => MigrateError::LmdbError(e),
}
}
}

260
third_party/rust/rkv-0.10.4/src/lib.rs поставляемый
Просмотреть файл

@ -1,260 +0,0 @@
// Copyright 2018-2019 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//! a simple, humane, typed Rust interface to [LMDB](http://www.lmdb.tech/doc/)
//!
//! It aims to achieve the following:
//!
//! - Avoid LMDB's sharp edges (e.g., obscure error codes for common situations).
//! - Report errors via [failure](https://docs.rs/failure/).
//! - Correctly restrict access to one handle per process via a [Manager](struct.Manager.html).
//! - Use Rust's type system to make single-typed key stores (including LMDB's own integer-keyed stores)
//! safe and ergonomic.
//! - Encode and decode values via [bincode](https://docs.rs/bincode/)/[serde](https://docs.rs/serde/)
//! and type tags, achieving platform-independent storage and input/output flexibility.
//!
//! It exposes these primary abstractions:
//!
//! - [Manager](struct.Manager.html): a singleton that controls access to LMDB environments
//! - [Rkv](struct.Rkv.html): an LMDB environment that contains a set of key/value databases
//! - [SingleStore](store/single/struct.SingleStore.html): an LMDB database that contains a set of key/value pairs
//!
//! Keys can be anything that implements `AsRef<[u8]>` or integers
//! (when accessing an [IntegerStore](store/integer/struct.IntegerStore.html)).
//! Values can be any of the types defined by the [Value](value/enum.Value.html) enum, including:
//!
//! - booleans (`Value::Bool`)
//! - integers (`Value::I64`, `Value::U64`)
//! - floats (`Value::F64`)
//! - strings (`Value::Str`)
//! - blobs (`Value::Blob`)
//!
//! See [Value](value/enum.Value.html) for the complete list of supported types.
//!
//! ## Basic Usage
//! ```
//! use rkv::{Manager, Rkv, SingleStore, Value, StoreOptions};
//! use std::fs;
//! use tempfile::Builder;
//!
//! // First determine the path to the environment, which is represented
//! // on disk as a directory containing two files:
//! //
//! // * a data file containing the key/value stores
//! // * a lock file containing metadata about current transactions
//! //
//! // In this example, we use the `tempfile` crate to create the directory.
//! //
//! let root = Builder::new().prefix("simple-db").tempdir().unwrap();
//! fs::create_dir_all(root.path()).unwrap();
//! let path = root.path();
//!
//! // The Manager enforces that each process opens the same environment
//! // at most once by caching a handle to each environment that it opens.
//! // Use it to retrieve the handle to an opened environment—or create one
//! // if it hasn't already been opened:
//! let created_arc = Manager::singleton().write().unwrap().get_or_create(path, Rkv::new).unwrap();
//! let env = created_arc.read().unwrap();
//!
//! // Then you can use the environment handle to get a handle to a datastore:
//! let store: SingleStore = env.open_single("mydb", StoreOptions::create()).unwrap();
//!
//! {
//! // Use a write transaction to mutate the store via a `Writer`.
//! // There can be only one writer for a given environment, so opening
//! // a second one will block until the first completes.
//! let mut writer = env.write().unwrap();
//!
//! // Keys are `AsRef<[u8]>`, while values are `Value` enum instances.
//! // Use the `Blob` variant to store arbitrary collections of bytes.
//! // Putting data returns a `Result<(), StoreError>`, where StoreError
//! // is an enum identifying the reason for a failure.
//! store.put(&mut writer, "int", &Value::I64(1234)).unwrap();
//! store.put(&mut writer, "uint", &Value::U64(1234_u64)).unwrap();
//! store.put(&mut writer, "float", &Value::F64(1234.0.into())).unwrap();
//! store.put(&mut writer, "instant", &Value::Instant(1528318073700)).unwrap();
//! store.put(&mut writer, "boolean", &Value::Bool(true)).unwrap();
//! store.put(&mut writer, "string", &Value::Str("Héllo, wörld!")).unwrap();
//! store.put(&mut writer, "json", &Value::Json(r#"{"foo":"bar", "number": 1}"#)).unwrap();
//! store.put(&mut writer, "blob", &Value::Blob(b"blob")).unwrap();
//!
//! // You must commit a write transaction before the writer goes out
//! // of scope, or the transaction will abort and the data won't persist.
//! writer.commit().unwrap();
//! }
//!
//! {
//! // Use a read transaction to query the store via a `Reader`.
//! // There can be multiple concurrent readers for a store, and readers
//! // never block on a writer nor other readers.
//! let reader = env.read().expect("reader");
//!
//! // Keys are `AsRef<u8>`, and the return value is `Result<Option<Value>, StoreError>`.
//! println!("Get int {:?}", store.get(&reader, "int").unwrap());
//! println!("Get uint {:?}", store.get(&reader, "uint").unwrap());
//! println!("Get float {:?}", store.get(&reader, "float").unwrap());
//! println!("Get instant {:?}", store.get(&reader, "instant").unwrap());
//! println!("Get boolean {:?}", store.get(&reader, "boolean").unwrap());
//! println!("Get string {:?}", store.get(&reader, "string").unwrap());
//! println!("Get json {:?}", store.get(&reader, "json").unwrap());
//! println!("Get blob {:?}", store.get(&reader, "blob").unwrap());
//!
//! // Retrieving a non-existent value returns `Ok(None)`.
//! println!("Get non-existent value {:?}", store.get(&reader, "non-existent").unwrap());
//!
//! // A read transaction will automatically close once the reader
//! // goes out of scope, so isn't necessary to close it explicitly,
//! // although you can do so by calling `Reader.abort()`.
//! }
//!
//! {
//! // Aborting a write transaction rolls back the change(s).
//! let mut writer = env.write().unwrap();
//! store.put(&mut writer, "foo", &Value::Str("bar")).unwrap();
//! writer.abort();
//! let reader = env.read().expect("reader");
//! println!("It should be None! ({:?})", store.get(&reader, "foo").unwrap());
//! }
//!
//! {
//! // Explicitly aborting a transaction is not required unless an early
//! // abort is desired, since both read and write transactions will
//! // implicitly be aborted once they go out of scope.
//! {
//! let mut writer = env.write().unwrap();
//! store.put(&mut writer, "foo", &Value::Str("bar")).unwrap();
//! }
//! let reader = env.read().expect("reader");
//! println!("It should be None! ({:?})", store.get(&reader, "foo").unwrap());
//! }
//!
//! {
//! // Deleting a key/value pair also requires a write transaction.
//! let mut writer = env.write().unwrap();
//! store.put(&mut writer, "foo", &Value::Str("bar")).unwrap();
//! store.put(&mut writer, "bar", &Value::Str("baz")).unwrap();
//! store.delete(&mut writer, "foo").unwrap();
//!
//! // A write transaction also supports reading, and the version of the
//! // store that it reads includes the changes it has made regardless of
//! // the commit state of that transaction.
//! // In the code above, "foo" and "bar" were put into the store,
//! // then "foo" was deleted so only "bar" will return a result when the
//! // database is queried via the writer.
//! println!("It should be None! ({:?})", store.get(&writer, "foo").unwrap());
//! println!("Get bar ({:?})", store.get(&writer, "bar").unwrap());
//!
//! // But a reader won't see that change until the write transaction
//! // is committed.
//! {
//! let reader = env.read().expect("reader");
//! println!("Get foo {:?}", store.get(&reader, "foo").unwrap());
//! println!("Get bar {:?}", store.get(&reader, "bar").unwrap());
//! }
//! writer.commit().unwrap();
//! {
//! let reader = env.read().expect("reader");
//! println!("It should be None! ({:?})", store.get(&reader, "foo").unwrap());
//! println!("Get bar {:?}", store.get(&reader, "bar").unwrap());
//! }
//!
//! // Committing a transaction consumes the writer, preventing you
//! // from reusing it by failing at compile time with an error.
//! // This line would report error[E0382]: borrow of moved value: `writer`.
//! // store.put(&mut writer, "baz", &Value::Str("buz")).unwrap();
//! }
//!
//! {
//! // Clearing all the entries in the store with a write transaction.
//! {
//! let mut writer = env.write().unwrap();
//! store.put(&mut writer, "foo", &Value::Str("bar")).unwrap();
//! store.put(&mut writer, "bar", &Value::Str("baz")).unwrap();
//! writer.commit().unwrap();
//! }
//!
//! {
//! let mut writer = env.write().unwrap();
//! store.clear(&mut writer).unwrap();
//! writer.commit().unwrap();
//! }
//!
//! {
//! let reader = env.read().expect("reader");
//! println!("It should be None! ({:?})", store.get(&reader, "foo").unwrap());
//! println!("It should be None! ({:?})", store.get(&reader, "bar").unwrap());
//! }
//!
//! }
//!
//! ```
#![allow(dead_code)]
pub use lmdb::{
DatabaseFlags,
EnvironmentBuilder,
EnvironmentFlags,
WriteFlags,
};
mod env;
pub mod error;
mod manager;
pub mod migrate;
mod readwrite;
pub mod store;
pub mod value;
pub use lmdb::{
Cursor,
Database,
Info,
Iter as LmdbIter,
RoCursor,
Stat,
};
pub use self::readwrite::{
Readable,
Reader,
Writer,
};
pub use self::store::integer::{
IntegerStore,
PrimitiveInt,
};
pub use self::store::integermulti::MultiIntegerStore;
pub use self::store::multi::MultiStore;
pub use self::store::single::SingleStore;
pub use self::store::Options as StoreOptions;
pub use self::env::Rkv;
pub use self::error::{
DataError,
StoreError,
};
pub use self::manager::Manager;
pub use self::value::{
OwnedValue,
Value,
};
fn read_transform(val: Result<&[u8], lmdb::Error>) -> Result<Option<Value>, StoreError> {
match val {
Ok(bytes) => Value::from_tagged_slice(bytes).map(Some).map_err(StoreError::DataError),
Err(lmdb::Error::NotFound) => Ok(None),
Err(e) => Err(StoreError::LmdbError(e)),
}
}

196
third_party/rust/rkv-0.10.4/src/manager.rs поставляемый
Просмотреть файл

@ -1,196 +0,0 @@
// Copyright 2018-2019 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use lazy_static::lazy_static;
use std::collections::BTreeMap;
use std::io::{
self,
Error,
ErrorKind,
};
use std::collections::btree_map::Entry;
use std::os::raw::c_uint;
use std::path::{
Path,
PathBuf,
};
use std::sync::{
Arc,
RwLock,
};
use url::Url;
use crate::error::StoreError;
use crate::Rkv;
lazy_static! {
/// A process is only permitted to have one open handle to each Rkv environment.
/// This manager exists to enforce that constraint: don't open environments directly.
static ref MANAGER: RwLock<Manager> = RwLock::new(Manager::new());
}
// Workaround the UNC path on Windows, see https://github.com/rust-lang/rust/issues/42869.
// Otherwise, `Env::from_env()` will panic with error_no(123).
fn canonicalize_path<'p, P>(path: P) -> io::Result<PathBuf>
where
P: Into<&'p Path>,
{
let canonical = path.into().canonicalize()?;
if cfg!(target_os = "windows") {
let url = Url::from_file_path(&canonical).map_err(|_e| Error::new(ErrorKind::Other, "URL passing error"))?;
return url.to_file_path().map_err(|_e| Error::new(ErrorKind::Other, "path canonicalization error"));
}
Ok(canonical)
}
/// A process is only permitted to have one open handle to each Rkv environment.
/// This manager exists to enforce that constraint: don't open environments directly.
pub struct Manager {
environments: BTreeMap<PathBuf, Arc<RwLock<Rkv>>>,
}
impl Manager {
fn new() -> Manager {
Manager {
environments: Default::default(),
}
}
pub fn singleton() -> &'static RwLock<Manager> {
&*MANAGER
}
/// Return the open env at `path`, returning `None` if it has not already been opened.
pub fn get<'p, P>(&self, path: P) -> Result<Option<Arc<RwLock<Rkv>>>, ::std::io::Error>
where
P: Into<&'p Path>,
{
let canonical = canonicalize_path(path)?;
Ok(self.environments.get(&canonical).cloned())
}
/// Return the open env at `path`, or create it by calling `f`.
pub fn get_or_create<'p, F, P>(&mut self, path: P, f: F) -> Result<Arc<RwLock<Rkv>>, StoreError>
where
F: FnOnce(&Path) -> Result<Rkv, StoreError>,
P: Into<&'p Path>,
{
let canonical = canonicalize_path(path)?;
Ok(match self.environments.entry(canonical) {
Entry::Occupied(e) => e.get().clone(),
Entry::Vacant(e) => {
let k = Arc::new(RwLock::new(f(e.key().as_path())?));
e.insert(k).clone()
},
})
}
/// Return the open env at `path` with capacity `capacity`,
/// or create it by calling `f`.
pub fn get_or_create_with_capacity<'p, F, P>(
&mut self,
path: P,
capacity: c_uint,
f: F,
) -> Result<Arc<RwLock<Rkv>>, StoreError>
where
F: FnOnce(&Path, c_uint) -> Result<Rkv, StoreError>,
P: Into<&'p Path>,
{
let canonical = canonicalize_path(path)?;
Ok(match self.environments.entry(canonical) {
Entry::Occupied(e) => e.get().clone(),
Entry::Vacant(e) => {
let k = Arc::new(RwLock::new(f(e.key().as_path(), capacity)?));
e.insert(k).clone()
},
})
}
}
#[cfg(test)]
mod tests {
use std::fs;
use tempfile::Builder;
use super::*;
/// Test that the manager will return the same Rkv instance each time for each path.
#[test]
fn test_same() {
let root = Builder::new().prefix("test_same").tempdir().expect("tempdir");
fs::create_dir_all(root.path()).expect("dir created");
let mut manager = Manager::new();
let p = root.path();
assert!(manager.get(p).expect("success").is_none());
let created_arc = manager.get_or_create(p, Rkv::new).expect("created");
let fetched_arc = manager.get(p).expect("success").expect("existed");
assert!(Arc::ptr_eq(&created_arc, &fetched_arc));
}
/// Test that one can mutate managed Rkv instances in surprising ways.
#[test]
fn test_mutate_managed_rkv() {
let mut manager = Manager::new();
let root1 = Builder::new().prefix("test_mutate_managed_rkv_1").tempdir().expect("tempdir");
fs::create_dir_all(root1.path()).expect("dir created");
let path1 = root1.path();
let arc = manager.get_or_create(path1, Rkv::new).expect("created");
// Arc<RwLock<>> has interior mutability, so we can replace arc's Rkv
// instance with a new instance that has a different path.
let root2 = Builder::new().prefix("test_mutate_managed_rkv_2").tempdir().expect("tempdir");
fs::create_dir_all(root2.path()).expect("dir created");
let path2 = root2.path();
{
let mut rkv = arc.write().expect("guard");
let rkv2 = Rkv::new(path2).expect("Rkv");
*rkv = rkv2;
}
// arc now has a different internal Rkv with path2, but it's still
// mapped to path1 in manager, so its pointer is equal to a new Arc
// for path1.
let path1_arc = manager.get(path1).expect("success").expect("existed");
assert!(Arc::ptr_eq(&path1_arc, &arc));
// Meanwhile, a new Arc for path2 has a different pointer, even though
// its Rkv's path is the same as arc's current path.
let path2_arc = manager.get_or_create(path2, Rkv::new).expect("success");
assert!(!Arc::ptr_eq(&path2_arc, &arc));
}
/// Test that the manager will return the same Rkv instance each time for each path.
#[test]
fn test_same_with_capacity() {
let root = Builder::new().prefix("test_same").tempdir().expect("tempdir");
fs::create_dir_all(root.path()).expect("dir created");
let mut manager = Manager::new();
let p = root.path();
assert!(manager.get(p).expect("success").is_none());
let created_arc = manager.get_or_create_with_capacity(p, 10, Rkv::with_capacity).expect("created");
let fetched_arc = manager.get(p).expect("success").expect("existed");
assert!(Arc::ptr_eq(&created_arc, &fetched_arc));
}
}

1028
third_party/rust/rkv-0.10.4/src/migrate.rs поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

95
third_party/rust/rkv-0.10.4/src/readwrite.rs поставляемый
Просмотреть файл

@ -1,95 +0,0 @@
// Copyright 2018-2019 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use lmdb::{
Database,
RoCursor,
RoTransaction,
RwTransaction,
Transaction,
WriteFlags,
};
use crate::error::StoreError;
use crate::read_transform;
use crate::value::Value;
pub struct Reader<'env>(pub RoTransaction<'env>);
pub struct Writer<'env>(pub RwTransaction<'env>);
pub trait Readable {
fn get<K: AsRef<[u8]>>(&self, db: Database, k: &K) -> Result<Option<Value>, StoreError>;
fn open_ro_cursor(&self, db: Database) -> Result<RoCursor, StoreError>;
}
impl<'env> Readable for Reader<'env> {
fn get<K: AsRef<[u8]>>(&self, db: Database, k: &K) -> Result<Option<Value>, StoreError> {
let bytes = self.0.get(db, &k);
read_transform(bytes)
}
fn open_ro_cursor(&self, db: Database) -> Result<RoCursor, StoreError> {
self.0.open_ro_cursor(db).map_err(StoreError::LmdbError)
}
}
impl<'env> Reader<'env> {
pub(crate) fn new(txn: RoTransaction) -> Reader {
Reader(txn)
}
pub fn abort(self) {
self.0.abort();
}
}
impl<'env> Readable for Writer<'env> {
fn get<K: AsRef<[u8]>>(&self, db: Database, k: &K) -> Result<Option<Value>, StoreError> {
let bytes = self.0.get(db, &k);
read_transform(bytes)
}
fn open_ro_cursor(&self, db: Database) -> Result<RoCursor, StoreError> {
self.0.open_ro_cursor(db).map_err(StoreError::LmdbError)
}
}
impl<'env> Writer<'env> {
pub(crate) fn new(txn: RwTransaction) -> Writer {
Writer(txn)
}
pub fn commit(self) -> Result<(), StoreError> {
self.0.commit().map_err(StoreError::LmdbError)
}
pub fn abort(self) {
self.0.abort();
}
pub(crate) fn put<K: AsRef<[u8]>>(
&mut self,
db: Database,
k: &K,
v: &Value,
flags: WriteFlags,
) -> Result<(), StoreError> {
// TODO: don't allocate twice.
self.0.put(db, &k, &v.to_bytes()?, flags).map_err(StoreError::LmdbError)
}
pub(crate) fn delete<K: AsRef<[u8]>>(&mut self, db: Database, k: &K, v: Option<&[u8]>) -> Result<(), StoreError> {
self.0.del(db, &k, v).map_err(StoreError::LmdbError)
}
pub(crate) fn clear(&mut self, db: Database) -> Result<(), StoreError> {
self.0.clear_db(db).map_err(StoreError::LmdbError)
}
}

21
third_party/rust/rkv-0.10.4/src/store.rs поставляемый
Просмотреть файл

@ -1,21 +0,0 @@
pub mod integer;
pub mod integermulti;
pub mod multi;
pub mod single;
use lmdb::DatabaseFlags;
#[derive(Default, Debug, Copy, Clone)]
pub struct Options {
pub create: bool,
pub flags: DatabaseFlags,
}
impl Options {
pub fn create() -> Options {
Options {
create: true,
flags: DatabaseFlags::empty(),
}
}
}

Просмотреть файл

@ -1,172 +0,0 @@
// Copyright 2018-2019 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use std::marker::PhantomData;
use bincode::serialize;
use serde::Serialize;
use lmdb::Database;
use crate::error::{
DataError,
StoreError,
};
use crate::readwrite::{
Readable,
Writer,
};
use crate::value::Value;
use crate::store::single::SingleStore;
pub trait EncodableKey {
fn to_bytes(&self) -> Result<Vec<u8>, DataError>;
}
pub trait PrimitiveInt: EncodableKey {}
impl PrimitiveInt for u32 {}
impl<T> EncodableKey for T
where
T: Serialize,
{
fn to_bytes(&self) -> Result<Vec<u8>, DataError> {
serialize(self) // TODO: limited key length.
.map_err(Into::into)
}
}
pub(crate) struct Key<K> {
bytes: Vec<u8>,
phantom: PhantomData<K>,
}
impl<K> AsRef<[u8]> for Key<K>
where
K: EncodableKey,
{
fn as_ref(&self) -> &[u8] {
self.bytes.as_ref()
}
}
impl<K> Key<K>
where
K: EncodableKey,
{
#[allow(clippy::new_ret_no_self)]
pub(crate) fn new(k: &K) -> Result<Key<K>, DataError> {
Ok(Key {
bytes: k.to_bytes()?,
phantom: PhantomData,
})
}
}
pub struct IntegerStore<K>
where
K: PrimitiveInt,
{
inner: SingleStore,
phantom: PhantomData<K>,
}
impl<K> IntegerStore<K>
where
K: PrimitiveInt,
{
pub(crate) fn new(db: Database) -> IntegerStore<K> {
IntegerStore {
inner: SingleStore::new(db),
phantom: PhantomData,
}
}
pub fn get<'env, T: Readable>(&self, reader: &'env T, k: K) -> Result<Option<Value<'env>>, StoreError> {
self.inner.get(reader, Key::new(&k)?)
}
pub fn put(&self, writer: &mut Writer, k: K, v: &Value) -> Result<(), StoreError> {
self.inner.put(writer, Key::new(&k)?, v)
}
pub fn delete(&self, writer: &mut Writer, k: K) -> Result<(), StoreError> {
self.inner.delete(writer, Key::new(&k)?)
}
pub fn clear(&self, writer: &mut Writer) -> Result<(), StoreError> {
self.inner.clear(writer)
}
}
#[cfg(test)]
mod tests {
use std::fs;
use tempfile::Builder;
use super::*;
use crate::*;
#[test]
fn test_integer_keys() {
let root = Builder::new().prefix("test_integer_keys").tempdir().expect("tempdir");
fs::create_dir_all(root.path()).expect("dir created");
let k = Rkv::new(root.path()).expect("new succeeded");
let s = k.open_integer("s", StoreOptions::create()).expect("open");
macro_rules! test_integer_keys {
($type:ty, $key:expr) => {{
let mut writer = k.write().expect("writer");
s.put(&mut writer, $key, &Value::Str("hello!")).expect("write");
assert_eq!(s.get(&writer, $key).expect("read"), Some(Value::Str("hello!")));
writer.commit().expect("committed");
let reader = k.read().expect("reader");
assert_eq!(s.get(&reader, $key).expect("read"), Some(Value::Str("hello!")));
}};
}
test_integer_keys!(u32, std::u32::MIN);
test_integer_keys!(u32, std::u32::MAX);
}
#[test]
fn test_clear() {
let root = Builder::new().prefix("test_integer_clear").tempdir().expect("tempdir");
fs::create_dir_all(root.path()).expect("dir created");
let k = Rkv::new(root.path()).expect("new succeeded");
let s = k.open_integer("s", StoreOptions::create()).expect("open");
{
let mut writer = k.write().expect("writer");
s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
s.put(&mut writer, 2, &Value::Str("hello!")).expect("write");
s.put(&mut writer, 3, &Value::Str("hello!")).expect("write");
writer.commit().expect("committed");
}
{
let mut writer = k.write().expect("writer");
s.clear(&mut writer).expect("cleared");
writer.commit().expect("committed");
let reader = k.read().expect("reader");
assert_eq!(s.get(&reader, 1).expect("read"), None);
assert_eq!(s.get(&reader, 2).expect("read"), None);
assert_eq!(s.get(&reader, 3).expect("read"), None);
}
}
}

Просмотреть файл

@ -1,144 +0,0 @@
// Copyright 2018 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use lmdb::{
Database,
WriteFlags,
};
use std::marker::PhantomData;
use crate::error::StoreError;
use crate::readwrite::{
Readable,
Writer,
};
use crate::value::Value;
use crate::store::multi::{
Iter,
MultiStore,
};
use crate::store::integer::{
Key,
PrimitiveInt,
};
pub struct MultiIntegerStore<K>
where
K: PrimitiveInt,
{
inner: MultiStore,
phantom: PhantomData<K>,
}
impl<K> MultiIntegerStore<K>
where
K: PrimitiveInt,
{
pub(crate) fn new(db: Database) -> MultiIntegerStore<K> {
MultiIntegerStore {
inner: MultiStore::new(db),
phantom: PhantomData,
}
}
pub fn get<'env, T: Readable>(&self, reader: &'env T, k: K) -> Result<Iter<'env>, StoreError> {
self.inner.get(reader, Key::new(&k)?)
}
pub fn get_first<'env, T: Readable>(&self, reader: &'env T, k: K) -> Result<Option<Value<'env>>, StoreError> {
self.inner.get_first(reader, Key::new(&k)?)
}
pub fn put(&self, writer: &mut Writer, k: K, v: &Value) -> Result<(), StoreError> {
self.inner.put(writer, Key::new(&k)?, v)
}
pub fn put_with_flags(&self, writer: &mut Writer, k: K, v: &Value, flags: WriteFlags) -> Result<(), StoreError> {
self.inner.put_with_flags(writer, Key::new(&k)?, v, flags)
}
pub fn delete_all(&self, writer: &mut Writer, k: K) -> Result<(), StoreError> {
self.inner.delete_all(writer, Key::new(&k)?)
}
pub fn delete(&self, writer: &mut Writer, k: K, v: &Value) -> Result<(), StoreError> {
self.inner.delete(writer, Key::new(&k)?, v)
}
pub fn clear(&self, writer: &mut Writer) -> Result<(), StoreError> {
self.inner.clear(writer)
}
}
#[cfg(test)]
mod tests {
extern crate tempfile;
use self::tempfile::Builder;
use std::fs;
use super::*;
use crate::*;
#[test]
fn test_integer_keys() {
let root = Builder::new().prefix("test_integer_keys").tempdir().expect("tempdir");
fs::create_dir_all(root.path()).expect("dir created");
let k = Rkv::new(root.path()).expect("new succeeded");
let s = k.open_multi_integer("s", StoreOptions::create()).expect("open");
macro_rules! test_integer_keys {
($type:ty, $key:expr) => {{
let mut writer = k.write().expect("writer");
s.put(&mut writer, $key, &Value::Str("hello!")).expect("write");
assert_eq!(s.get_first(&writer, $key).expect("read"), Some(Value::Str("hello!")));
writer.commit().expect("committed");
let reader = k.read().expect("reader");
assert_eq!(s.get_first(&reader, $key).expect("read"), Some(Value::Str("hello!")));
}};
}
test_integer_keys!(u32, std::u32::MIN);
test_integer_keys!(u32, std::u32::MAX);
}
#[test]
fn test_clear() {
let root = Builder::new().prefix("test_multi_integer_clear").tempdir().expect("tempdir");
fs::create_dir_all(root.path()).expect("dir created");
let k = Rkv::new(root.path()).expect("new succeeded");
let s = k.open_multi_integer("s", StoreOptions::create()).expect("open");
{
let mut writer = k.write().expect("writer");
s.put(&mut writer, 1, &Value::Str("hello!")).expect("write");
s.put(&mut writer, 1, &Value::Str("hello1!")).expect("write");
s.put(&mut writer, 2, &Value::Str("hello!")).expect("write");
writer.commit().expect("committed");
}
{
let mut writer = k.write().expect("writer");
s.clear(&mut writer).expect("cleared");
writer.commit().expect("committed");
let reader = k.read().expect("reader");
assert_eq!(s.get_first(&reader, 1).expect("read"), None);
assert_eq!(s.get_first(&reader, 2).expect("read"), None);
}
}
}

151
third_party/rust/rkv-0.10.4/src/store/multi.rs поставляемый
Просмотреть файл

@ -1,151 +0,0 @@
// Copyright 2018 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use crate::{
error::StoreError,
read_transform,
readwrite::{
Readable,
Writer,
},
value::Value,
};
use lmdb::{
Cursor,
Database,
Iter as LmdbIter,
// IterDup as LmdbIterDup,
RoCursor,
WriteFlags,
};
#[derive(Copy, Clone)]
pub struct MultiStore {
db: Database,
}
pub struct Iter<'env> {
iter: LmdbIter<'env>,
cursor: RoCursor<'env>,
}
impl MultiStore {
pub(crate) fn new(db: Database) -> MultiStore {
MultiStore {
db,
}
}
/// Provides a cursor to all of the values for the duplicate entries that match this key
pub fn get<T: Readable, K: AsRef<[u8]>>(self, reader: &T, k: K) -> Result<Iter, StoreError> {
let mut cursor = reader.open_ro_cursor(self.db)?;
let iter = cursor.iter_dup_of(k);
Ok(Iter {
iter,
cursor,
})
}
/// Provides the first value that matches this key
pub fn get_first<T: Readable, K: AsRef<[u8]>>(self, reader: &T, k: K) -> Result<Option<Value>, StoreError> {
reader.get(self.db, &k)
}
/// Insert a value at the specified key.
/// This put will allow duplicate entries. If you wish to have duplicate entries
/// rejected, use the `put_with_flags` function and specify NO_DUP_DATA
pub fn put<K: AsRef<[u8]>>(self, writer: &mut Writer, k: K, v: &Value) -> Result<(), StoreError> {
writer.put(self.db, &k, v, WriteFlags::empty())
}
pub fn put_with_flags<K: AsRef<[u8]>>(
self,
writer: &mut Writer,
k: K,
v: &Value,
flags: WriteFlags,
) -> Result<(), StoreError> {
writer.put(self.db, &k, v, flags)
}
pub fn delete_all<K: AsRef<[u8]>>(self, writer: &mut Writer, k: K) -> Result<(), StoreError> {
writer.delete(self.db, &k, None)
}
pub fn delete<K: AsRef<[u8]>>(self, writer: &mut Writer, k: K, v: &Value) -> Result<(), StoreError> {
writer.delete(self.db, &k, Some(&v.to_bytes()?))
}
/* TODO - Figure out how to solve the need to have the cursor stick around when
* we are producing iterators from MultiIter
/// Provides an iterator starting at the lexographically smallest value in the store
pub fn iter_start(&self, store: MultiStore) -> Result<MultiIter, StoreError> {
let mut cursor = self.tx.open_ro_cursor(store.0).map_err(StoreError::LmdbError)?;
// We call Cursor.iter() instead of Cursor.iter_start() because
// the latter panics at "called `Result::unwrap()` on an `Err` value:
// NotFound" when there are no items in the store, whereas the former
// returns an iterator that yields no items.
//
// And since we create the Cursor and don't change its position, we can
// be sure that a call to Cursor.iter() will start at the beginning.
//
let iter = cursor.iter_dup();
Ok(MultiIter {
iter,
cursor,
})
}
*/
pub fn clear(self, writer: &mut Writer) -> Result<(), StoreError> {
writer.clear(self.db)
}
}
/*
fn read_transform_owned(val: Result<&[u8], lmdb::Error>) -> Result<Option<OwnedValue>, StoreError> {
match val {
Ok(bytes) => Value::from_tagged_slice(bytes).map(|v| Some(OwnedValue::from(&v))).map_err(StoreError::DataError),
Err(lmdb::Error::NotFound) => Ok(None),
Err(e) => Err(StoreError::LmdbError(e)),
}
}
impl<'env> Iterator for MultiIter<'env> {
type Item = Iter<'env>;
fn next(&mut self) -> Option<Self::Item> {
match self.iter.next() {
None => None,
Some(iter) => Some(Iter {
iter,
cursor,
}),
}
}
}
*/
impl<'env> Iterator for Iter<'env> {
type Item = Result<(&'env [u8], Option<Value<'env>>), StoreError>;
fn next(&mut self) -> Option<Self::Item> {
match self.iter.next() {
None => None,
Some(Ok((key, bytes))) => match read_transform(Ok(bytes)) {
Ok(val) => Some(Ok((key, val))),
Err(err) => Some(Err(err)),
},
Some(Err(err)) => Some(Err(StoreError::LmdbError(err))),
}
}
}

Просмотреть файл

@ -1,104 +0,0 @@
// Copyright 2018 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use crate::{
error::StoreError,
read_transform,
readwrite::{
Readable,
Writer,
},
value::Value,
};
use lmdb::{
Cursor,
Database,
Iter as LmdbIter,
RoCursor,
WriteFlags,
};
#[derive(Copy, Clone)]
pub struct SingleStore {
db: Database,
}
pub struct Iter<'env> {
iter: LmdbIter<'env>,
cursor: RoCursor<'env>,
}
impl SingleStore {
pub(crate) fn new(db: Database) -> SingleStore {
SingleStore {
db,
}
}
pub fn get<T: Readable, K: AsRef<[u8]>>(self, reader: &T, k: K) -> Result<Option<Value>, StoreError> {
reader.get(self.db, &k)
}
// TODO: flags
pub fn put<K: AsRef<[u8]>>(self, writer: &mut Writer, k: K, v: &Value) -> Result<(), StoreError> {
writer.put(self.db, &k, v, WriteFlags::empty())
}
pub fn delete<K: AsRef<[u8]>>(self, writer: &mut Writer, k: K) -> Result<(), StoreError> {
writer.delete(self.db, &k, None)
}
pub fn iter_start<T: Readable>(self, reader: &T) -> Result<Iter, StoreError> {
let mut cursor = reader.open_ro_cursor(self.db)?;
// We call Cursor.iter() instead of Cursor.iter_start() because
// the latter panics at "called `Result::unwrap()` on an `Err` value:
// NotFound" when there are no items in the store, whereas the former
// returns an iterator that yields no items.
//
// And since we create the Cursor and don't change its position, we can
// be sure that a call to Cursor.iter() will start at the beginning.
//
let iter = cursor.iter();
Ok(Iter {
iter,
cursor,
})
}
pub fn iter_from<T: Readable, K: AsRef<[u8]>>(self, reader: &T, k: K) -> Result<Iter, StoreError> {
let mut cursor = reader.open_ro_cursor(self.db)?;
let iter = cursor.iter_from(k);
Ok(Iter {
iter,
cursor,
})
}
pub fn clear(self, writer: &mut Writer) -> Result<(), StoreError> {
writer.clear(self.db)
}
}
impl<'env> Iterator for Iter<'env> {
type Item = Result<(&'env [u8], Option<Value<'env>>), StoreError>;
fn next(&mut self) -> Option<Self::Item> {
match self.iter.next() {
None => None,
Some(Ok((key, bytes))) => match read_transform(Ok(bytes)) {
Ok(val) => Some(Ok((key, val))),
Err(err) => Some(Err(err)),
},
Some(Err(err)) => Some(Err(StoreError::LmdbError(err))),
}
}
}

265
third_party/rust/rkv-0.10.4/src/value.rs поставляемый
Просмотреть файл

@ -1,265 +0,0 @@
// Copyright 2018-2019 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use arrayref::array_ref;
use bincode::{
deserialize,
serialize,
serialized_size,
};
use ordered_float::OrderedFloat;
use uuid::{
Bytes,
Uuid,
};
use crate::error::DataError;
/// We define a set of types, associated with simple integers, to annotate values
/// stored in LMDB. This is to avoid an accidental 'cast' from a value of one type
/// to another. For this reason we don't simply use `deserialize` from the `bincode`
/// crate.
#[repr(u8)]
#[derive(Debug, PartialEq, Eq)]
pub enum Type {
Bool = 1,
U64 = 2,
I64 = 3,
F64 = 4,
Instant = 5, // Millisecond-precision timestamp.
Uuid = 6,
Str = 7,
Json = 8,
Blob = 9,
}
/// We use manual tagging, because <https://github.com/serde-rs/serde/issues/610>.
impl Type {
pub fn from_tag(tag: u8) -> Result<Type, DataError> {
Type::from_primitive(tag).ok_or_else(|| DataError::UnknownType(tag))
}
#[allow(clippy::wrong_self_convention)]
pub fn to_tag(self) -> u8 {
self as u8
}
fn from_primitive(p: u8) -> Option<Type> {
match p {
1 => Some(Type::Bool),
2 => Some(Type::U64),
3 => Some(Type::I64),
4 => Some(Type::F64),
5 => Some(Type::Instant),
6 => Some(Type::Uuid),
7 => Some(Type::Str),
8 => Some(Type::Json),
9 => Some(Type::Blob),
_ => None,
}
}
}
impl ::std::fmt::Display for Type {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
f.write_str(match *self {
Type::Bool => "bool",
Type::U64 => "u64",
Type::I64 => "i64",
Type::F64 => "f64",
Type::Instant => "instant",
Type::Uuid => "uuid",
Type::Str => "str",
Type::Json => "json",
Type::Blob => "blob",
})
}
}
#[derive(Debug, Eq, PartialEq)]
pub enum Value<'s> {
Bool(bool),
U64(u64),
I64(i64),
F64(OrderedFloat<f64>),
Instant(i64), // Millisecond-precision timestamp.
Uuid(&'s Bytes),
Str(&'s str),
Json(&'s str),
Blob(&'s [u8]),
}
#[derive(Clone, Debug, PartialEq)]
pub enum OwnedValue {
Bool(bool),
U64(u64),
I64(i64),
F64(f64),
Instant(i64), // Millisecond-precision timestamp.
Uuid(Uuid),
Str(String),
Json(String), // TODO
Blob(Vec<u8>),
}
fn uuid(bytes: &[u8]) -> Result<Value, DataError> {
if bytes.len() == 16 {
Ok(Value::Uuid(array_ref![bytes, 0, 16]))
} else {
Err(DataError::InvalidUuid)
}
}
impl<'s> Value<'s> {
fn expected_from_tagged_slice(expected: Type, slice: &'s [u8]) -> Result<Value<'s>, DataError> {
let (tag, data) = slice.split_first().ok_or(DataError::Empty)?;
let t = Type::from_tag(*tag)?;
if t == expected {
return Err(DataError::UnexpectedType {
expected,
actual: t,
});
}
Value::from_type_and_data(t, data)
}
pub fn from_tagged_slice(slice: &'s [u8]) -> Result<Value<'s>, DataError> {
let (tag, data) = slice.split_first().ok_or(DataError::Empty)?;
let t = Type::from_tag(*tag)?;
Value::from_type_and_data(t, data)
}
fn from_type_and_data(t: Type, data: &'s [u8]) -> Result<Value<'s>, DataError> {
if t == Type::Uuid {
return deserialize(data)
.map_err(|e| DataError::DecodingError {
value_type: t,
err: e,
})
.map(uuid)?;
}
match t {
Type::Bool => deserialize(data).map(Value::Bool),
Type::U64 => deserialize(data).map(Value::U64),
Type::I64 => deserialize(data).map(Value::I64),
Type::F64 => deserialize(data).map(OrderedFloat).map(Value::F64),
Type::Instant => deserialize(data).map(Value::Instant),
Type::Str => deserialize(data).map(Value::Str),
Type::Json => deserialize(data).map(Value::Json),
Type::Blob => deserialize(data).map(Value::Blob),
Type::Uuid => {
// Processed above to avoid verbose duplication of error transforms.
unreachable!()
},
}
.map_err(|e| DataError::DecodingError {
value_type: t,
err: e,
})
}
pub fn to_bytes(&self) -> Result<Vec<u8>, DataError> {
match self {
Value::Bool(v) => serialize(&(Type::Bool.to_tag(), *v)),
Value::U64(v) => serialize(&(Type::U64.to_tag(), *v)),
Value::I64(v) => serialize(&(Type::I64.to_tag(), *v)),
Value::F64(v) => serialize(&(Type::F64.to_tag(), v.0)),
Value::Instant(v) => serialize(&(Type::Instant.to_tag(), *v)),
Value::Str(v) => serialize(&(Type::Str.to_tag(), v)),
Value::Json(v) => serialize(&(Type::Json.to_tag(), v)),
Value::Blob(v) => serialize(&(Type::Blob.to_tag(), v)),
Value::Uuid(v) => serialize(&(Type::Uuid.to_tag(), v)),
}
.map_err(DataError::EncodingError)
}
pub fn serialized_size(&self) -> Result<u64, DataError> {
match self {
Value::Bool(v) => serialized_size(&(Type::Bool.to_tag(), *v)),
Value::U64(v) => serialized_size(&(Type::U64.to_tag(), *v)),
Value::I64(v) => serialized_size(&(Type::I64.to_tag(), *v)),
Value::F64(v) => serialized_size(&(Type::F64.to_tag(), v.0)),
Value::Instant(v) => serialized_size(&(Type::Instant.to_tag(), *v)),
Value::Str(v) => serialized_size(&(Type::Str.to_tag(), v)),
Value::Json(v) => serialized_size(&(Type::Json.to_tag(), v)),
Value::Blob(v) => serialized_size(&(Type::Blob.to_tag(), v)),
Value::Uuid(v) => serialized_size(&(Type::Uuid.to_tag(), v)),
}
.map_err(DataError::EncodingError)
}
}
impl<'s> From<&'s Value<'s>> for OwnedValue {
fn from(value: &Value) -> OwnedValue {
match value {
Value::Bool(v) => OwnedValue::Bool(*v),
Value::U64(v) => OwnedValue::U64(*v),
Value::I64(v) => OwnedValue::I64(*v),
Value::F64(v) => OwnedValue::F64(**v),
Value::Instant(v) => OwnedValue::Instant(*v),
Value::Uuid(v) => OwnedValue::Uuid(Uuid::from_bytes(**v)),
Value::Str(v) => OwnedValue::Str(v.to_string()),
Value::Json(v) => OwnedValue::Json(v.to_string()),
Value::Blob(v) => OwnedValue::Blob(v.to_vec()),
}
}
}
impl<'s> From<&'s OwnedValue> for Value<'s> {
fn from(value: &OwnedValue) -> Value {
match value {
OwnedValue::Bool(v) => Value::Bool(*v),
OwnedValue::U64(v) => Value::U64(*v),
OwnedValue::I64(v) => Value::I64(*v),
OwnedValue::F64(v) => Value::F64(OrderedFloat::from(*v)),
OwnedValue::Instant(v) => Value::Instant(*v),
OwnedValue::Uuid(v) => Value::Uuid(v.as_bytes()),
OwnedValue::Str(v) => Value::Str(v),
OwnedValue::Json(v) => Value::Json(v),
OwnedValue::Blob(v) => Value::Blob(v),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use ordered_float::OrderedFloat;
#[test]
fn test_value_serialized_size() {
// | Value enum | tag: 1 byte | value_payload |
// |----------------------------------------------------------|
// | I64 | 1 | 8 |
// | U64 | 1 | 8 |
// | Bool | 1 | 1 |
// | Instant | 1 | 8 |
// | F64 | 1 | 8 |
// | Uuid | 1 | 16 |
// | Str/Blob/Json | 1 |(8: len + sizeof(payload))|
assert_eq!(Value::I64(-1000).serialized_size().unwrap(), 9);
assert_eq!(Value::U64(1000u64).serialized_size().unwrap(), 9);
assert_eq!(Value::Bool(true).serialized_size().unwrap(), 2);
assert_eq!(Value::Instant(1_558_020_865_224).serialized_size().unwrap(), 9);
assert_eq!(Value::F64(OrderedFloat(10000.1)).serialized_size().unwrap(), 9);
assert_eq!(Value::Str("hello!").serialized_size().unwrap(), 15);
assert_eq!(Value::Str("¡Hola").serialized_size().unwrap(), 15);
assert_eq!(Value::Blob(b"hello!").serialized_size().unwrap(), 15);
assert_eq!(
uuid(b"\x9f\xe2\xc4\xe9\x3f\x65\x4f\xdb\xb2\x4c\x02\xb1\x52\x59\x71\x6c")
.unwrap()
.serialized_size()
.unwrap(),
17
);
}
}

Просмотреть файл

@ -1,77 +0,0 @@
// Copyright 2018-2019 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use rkv::{
PrimitiveInt,
Rkv,
StoreOptions,
Value,
};
use serde_derive::Serialize;
use std::fs;
use tempfile::Builder;
#[test]
fn test_integer_keys() {
let root = Builder::new().prefix("test_integer_keys").tempdir().expect("tempdir");
fs::create_dir_all(root.path()).expect("dir created");
let k = Rkv::new(root.path()).expect("new succeeded");
let s = k.open_integer("s", StoreOptions::create()).expect("open");
macro_rules! test_integer_keys {
($store:expr, $key:expr) => {{
let mut writer = k.write().expect("writer");
$store.put(&mut writer, $key, &Value::Str("hello!")).expect("write");
assert_eq!($store.get(&writer, $key).expect("read"), Some(Value::Str("hello!")));
writer.commit().expect("committed");
let reader = k.read().expect("reader");
assert_eq!($store.get(&reader, $key).expect("read"), Some(Value::Str("hello!")));
}};
}
// The integer module provides only the u32 integer key variant
// of IntegerStore, so we can use it without further ado.
test_integer_keys!(s, std::u32::MIN);
test_integer_keys!(s, std::u32::MAX);
// If you want to use another integer key variant, you need to implement
// a newtype, implement PrimitiveInt, and implement or derive Serialize
// for it. Here we do so for the i32 type.
// DANGER! Doing this enables you to open a store with multiple,
// different integer key types, which may result in unexpected behavior.
// Make sure you know what you're doing!
let t = k.open_integer("s", StoreOptions::create()).expect("open");
#[derive(Serialize)]
struct I32(i32);
impl PrimitiveInt for I32 {}
test_integer_keys!(t, I32(std::i32::MIN));
test_integer_keys!(t, I32(std::i32::MAX));
let u = k.open_integer("s", StoreOptions::create()).expect("open");
#[derive(Serialize)]
struct U16(u16);
impl PrimitiveInt for U16 {}
test_integer_keys!(u, U16(std::u16::MIN));
test_integer_keys!(u, U16(std::u16::MAX));
let v = k.open_integer("s", StoreOptions::create()).expect("open");
#[derive(Serialize)]
struct U64(u64);
impl PrimitiveInt for U64 {}
test_integer_keys!(v, U64(std::u64::MIN));
test_integer_keys!(v, U64(std::u64::MAX));
}

34
third_party/rust/rkv-0.10.4/tests/manager.rs поставляемый
Просмотреть файл

@ -1,34 +0,0 @@
// Copyright 2018-2019 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use rkv::{
Manager,
Rkv,
};
use std::{
fs,
sync::Arc,
};
use tempfile::Builder;
#[test]
// Identical to the same-named unit test, but this one confirms that it works
// via the public MANAGER singleton.
fn test_same() {
let root = Builder::new().prefix("test_same_singleton").tempdir().expect("tempdir");
fs::create_dir_all(root.path()).expect("dir created");
let p = root.path();
assert!(Manager::singleton().read().unwrap().get(p).expect("success").is_none());
let created_arc = Manager::singleton().write().unwrap().get_or_create(p, Rkv::new).expect("created");
let fetched_arc = Manager::singleton().read().unwrap().get(p).expect("success").expect("existed");
assert!(Arc::ptr_eq(&created_arc, &fetched_arc));
}

Просмотреть файл

@ -1,91 +0,0 @@
// Copyright 2018 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use rkv::{
PrimitiveInt,
Rkv,
StoreOptions,
Value,
};
use serde_derive::Serialize;
use std::fs;
use tempfile::Builder;
#[test]
fn test_multi_integer_keys() {
let root = Builder::new().prefix("test_integer_keys").tempdir().expect("tempdir");
fs::create_dir_all(root.path()).expect("dir created");
let k = Rkv::new(root.path()).expect("new succeeded");
let s = k.open_multi_integer("s", StoreOptions::create()).expect("open");
macro_rules! test_integer_keys {
($store:expr, $key:expr) => {{
let mut writer = k.write().expect("writer");
$store.put(&mut writer, $key, &Value::Str("hello1")).expect("write");
$store.put(&mut writer, $key, &Value::Str("hello2")).expect("write");
$store.put(&mut writer, $key, &Value::Str("hello3")).expect("write");
let vals = $store
.get(&writer, $key)
.expect("read")
.map(|result| result.expect("ok"))
.map(|(_, v)| v.expect("multi read"))
.collect::<Vec<Value>>();
assert_eq!(vals, vec![Value::Str("hello1"), Value::Str("hello2"), Value::Str("hello3")]);
writer.commit().expect("committed");
let reader = k.read().expect("reader");
let vals = $store
.get(&reader, $key)
.expect("read")
.map(|result| result.expect("ok"))
.map(|(_, v)| v.expect("multi read"))
.collect::<Vec<Value>>();
assert_eq!(vals, vec![Value::Str("hello1"), Value::Str("hello2"), Value::Str("hello3")]);
}};
}
// The integer module provides only the u32 integer key variant
// of IntegerStore, so we can use it without further ado.
test_integer_keys!(s, std::u32::MIN);
test_integer_keys!(s, std::u32::MAX);
// If you want to use another integer key variant, you need to implement
// a newtype, implement PrimitiveInt, and implement or derive Serialize
// for it. Here we do so for the i32 type.
// DANGER! Doing this enables you to open a store with multiple,
// different integer key types, which may result in unexpected behavior.
// Make sure you know what you're doing!
let t = k.open_multi_integer("s", StoreOptions::create()).expect("open");
#[derive(Serialize)]
struct I32(i32);
impl PrimitiveInt for I32 {}
test_integer_keys!(t, I32(std::i32::MIN));
test_integer_keys!(t, I32(std::i32::MAX));
let u = k.open_multi_integer("s", StoreOptions::create()).expect("open");
#[derive(Serialize)]
struct U16(u16);
impl PrimitiveInt for U16 {}
test_integer_keys!(u, U16(std::u16::MIN));
test_integer_keys!(u, U16(std::u16::MAX));
let v = k.open_multi_integer("s", StoreOptions::create()).expect("open");
#[derive(Serialize)]
struct U64(u64);
impl PrimitiveInt for U64 {}
test_integer_keys!(v, U64(std::u64::MIN));
test_integer_keys!(v, U64(std::u64::MAX));
}

105
third_party/rust/rkv-0.10.4/tests/test_txn.rs поставляемый
Просмотреть файл

@ -1,105 +0,0 @@
/// consider a struct like this
/// struct Sample {
/// id: u64,
/// value: String,
/// date: String,
/// }
/// We would like to index all of the fields so that we can search for the struct not only by ID
/// but also by value and date. When we index the fields individually in their own tables, it
/// is important that we run all operations within a single transaction to ensure coherence of
/// the indices
/// This test features helper functions for reading and writing the parts of the struct.
/// Note that the reader functions take `Readable` because they might run within a Read
/// Transaction or a Write Transaction. The test demonstrates fetching values via both.
use rkv::{
MultiStore,
Readable,
Rkv,
SingleStore,
StoreOptions,
Value,
Writer,
};
use tempfile::Builder;
use std::fs;
#[test]
fn read_many() {
let root = Builder::new().prefix("test_txns").tempdir().expect("tempdir");
fs::create_dir_all(root.path()).expect("dir created");
let k = Rkv::new(root.path()).expect("new succeeded");
let samplestore = k.open_single("s", StoreOptions::create()).expect("open");
let datestore = k.open_multi("m", StoreOptions::create()).expect("open");
let valuestore = k.open_multi("m", StoreOptions::create()).expect("open");
{
let mut writer = k.write().expect("env write lock");
for id in 0..30_u64 {
let value = format!("value{}", id);
let date = format!("2019-06-{}", id);
put_id_field(&mut writer, datestore, &date, id);
put_id_field(&mut writer, valuestore, &value, id);
put_sample(&mut writer, samplestore, id, &value);
}
// now we read in the same transaction
for id in 0..30_u64 {
let value = format!("value{}", id);
let date = format!("2019-06-{}", id);
let ids = get_ids_by_field(&writer, datestore, &date);
let ids2 = get_ids_by_field(&writer, valuestore, &value);
let samples = get_samples(&writer, samplestore, &ids);
let samples2 = get_samples(&writer, samplestore, &ids2);
println!("{:?}, {:?}", samples, samples2);
}
}
{
let reader = k.read().expect("env read lock");
for id in 0..30_u64 {
let value = format!("value{}", id);
let date = format!("2019-06-{}", id);
let ids = get_ids_by_field(&reader, datestore, &date);
let ids2 = get_ids_by_field(&reader, valuestore, &value);
let samples = get_samples(&reader, samplestore, &ids);
let samples2 = get_samples(&reader, samplestore, &ids2);
println!("{:?}, {:?}", samples, samples2);
}
}
}
fn get_ids_by_field<Txn: Readable>(txn: &Txn, store: MultiStore, field: &str) -> Vec<u64> {
store
.get(txn, field)
.expect("get iterator")
.map(|id| match id.expect("field") {
(_, Some(Value::U64(id))) => id,
_ => panic!("getting value in iter"),
})
.collect::<Vec<u64>>()
}
fn get_samples<Txn: Readable>(txn: &Txn, samplestore: SingleStore, ids: &[u64]) -> Vec<String> {
ids.iter()
.map(|id| {
let bytes = id.to_be_bytes();
match samplestore.get(txn, &bytes).expect("fetch sample") {
Some(Value::Str(sample)) => String::from(sample),
Some(_) => panic!("wrong type"),
None => panic!("no sample for this id!"),
}
})
.collect::<Vec<String>>()
}
fn put_sample(txn: &mut Writer, samplestore: SingleStore, id: u64, value: &str) {
let idbytes = id.to_be_bytes();
samplestore.put(txn, &idbytes, &Value::Str(value)).expect("put id");
}
fn put_id_field(txn: &mut Writer, store: MultiStore, field: &str, id: u64) {
store.put(txn, field, &Value::U64(id)).expect("put id");
}

Просмотреть файл

@ -7,5 +7,5 @@ authors = ["fuzzing@mozilla.com"]
libc = "0.2"
tempfile = "3"
lazy_static = "1.4.0"
rkv = { version = "0.10", features = ["with-fuzzer-no-link"] }
rkv = { version = "0.16", features = ["with-fuzzer-no-link"] }
lmdb-rkv = { version = "0.14", features = ["with-fuzzer-no-link"] }

Просмотреть файл

@ -9,6 +9,14 @@ extern crate lmdb;
extern crate rkv;
extern crate tempfile;
use rkv::backend::{
BackendEnvironmentBuilder,
SafeMode,
SafeModeDatabase,
SafeModeEnvironment,
SafeModeRoTransaction,
SafeModeRwTransaction,
};
use std::fs;
use std::fs::File;
use std::io::Write;
@ -18,6 +26,9 @@ use std::sync::Arc;
use std::thread;
use tempfile::Builder;
type Rkv = rkv::Rkv<SafeModeEnvironment>;
type SingleStore = rkv::SingleStore<SafeModeDatabase>;
fn eat_lmdb_err<T>(value: Result<T, rkv::StoreError>) -> Result<Option<T>, rkv::StoreError> {
match value {
Ok(value) => Ok(Some(value)),
@ -49,8 +60,7 @@ pub extern "C" fn fuzz_rkv_db_file(raw_data: *const u8, size: libc::size_t) -> l
let mut db_file = File::create("data.mdb").unwrap();
db_file.write_all(db).unwrap();
let &mut builder = rkv::Rkv::environment_builder().set_max_dbs(2);
let env = rkv::Rkv::from_env(Path::new("."), builder).unwrap();
let env = Rkv::with_capacity::<SafeMode>(Path::new("."), 2).unwrap();
let store = env
.open_single("test", rkv::StoreOptions::create())
.unwrap();
@ -68,7 +78,7 @@ pub extern "C" fn fuzz_rkv_db_name(raw_data: *const u8, size: libc::size_t) -> l
let root = Builder::new().prefix("fuzz_rkv_db_name").tempdir().unwrap();
fs::create_dir_all(root.path()).unwrap();
let env = rkv::Rkv::new(root.path()).unwrap();
let env = Rkv::new::<SafeMode>(root.path()).unwrap();
let name = String::from_utf8_lossy(data);
println!("Checking string: '{:?}'", name);
// Some strings are invalid database names, and are handled as store errors.
@ -93,7 +103,7 @@ pub extern "C" fn fuzz_rkv_key_write(raw_data: *const u8, size: libc::size_t) ->
.unwrap();
fs::create_dir_all(root.path()).unwrap();
let env = rkv::Rkv::new(root.path()).unwrap();
let env = Rkv::new::<SafeMode>(root.path()).unwrap();
let store = env
.open_single("test", rkv::StoreOptions::create())
.unwrap();
@ -116,7 +126,7 @@ pub extern "C" fn fuzz_rkv_val_write(raw_data: *const u8, size: libc::size_t) ->
.unwrap();
fs::create_dir_all(root.path()).unwrap();
let env = rkv::Rkv::new(root.path()).unwrap();
let env = Rkv::new::<SafeMode>(root.path()).unwrap();
let store = env
.open_single("test", rkv::StoreOptions::create())
.unwrap();
@ -157,7 +167,7 @@ pub extern "C" fn fuzz_rkv_calls(raw_data: *const u8, size: libc::size_t) -> lib
fn maybe_abort<I: Iterator<Item = u8>>(
fuzz: &mut I,
read: rkv::Reader,
read: rkv::Reader<SafeModeRoTransaction>,
) -> Result<(), rkv::StoreError> {
match fuzz.next().map(|byte| byte % 2) {
Some(0) => Ok(read.abort()),
@ -167,7 +177,7 @@ pub extern "C" fn fuzz_rkv_calls(raw_data: *const u8, size: libc::size_t) -> lib
fn maybe_commit<I: Iterator<Item = u8>>(
fuzz: &mut I,
write: rkv::Writer,
write: rkv::Writer<SafeModeRwTransaction>,
) -> Result<(), rkv::StoreError> {
match fuzz.next().map(|byte| byte % 3) {
Some(0) => write.commit(),
@ -207,8 +217,8 @@ pub extern "C" fn fuzz_rkv_calls(raw_data: *const u8, size: libc::size_t) -> lib
fn store_put<I: Iterator<Item = u8> + Clone>(
fuzz: &mut I,
env: &rkv::Rkv,
store: &rkv::SingleStore,
env: &Rkv,
store: &SingleStore,
) {
let key = match get_any_data(fuzz, 1024) {
Some(key) => key,
@ -239,8 +249,8 @@ pub extern "C" fn fuzz_rkv_calls(raw_data: *const u8, size: libc::size_t) -> lib
fn store_get<I: Iterator<Item = u8> + Clone>(
fuzz: &mut I,
env: &rkv::Rkv,
store: &rkv::SingleStore,
env: &Rkv,
store: &SingleStore,
) {
let key = match get_any_data(fuzz, 1024) {
Some(key) => key,
@ -264,8 +274,8 @@ pub extern "C" fn fuzz_rkv_calls(raw_data: *const u8, size: libc::size_t) -> lib
fn store_delete<I: Iterator<Item = u8> + Clone>(
fuzz: &mut I,
env: &rkv::Rkv,
store: &rkv::SingleStore,
env: &Rkv,
store: &SingleStore,
) {
let key = match get_any_data(fuzz, 1024) {
Some(key) => key,
@ -284,7 +294,7 @@ pub extern "C" fn fuzz_rkv_calls(raw_data: *const u8, size: libc::size_t) -> lib
maybe_commit(fuzz, writer).unwrap();
}
fn store_resize<I: Iterator<Item = u8>>(fuzz: &mut I, env: &rkv::Rkv) {
fn store_resize<I: Iterator<Item = u8>>(fuzz: &mut I, env: &Rkv) {
let n = fuzz.next().unwrap_or(1) as usize;
env.set_map_size(1_048_576 * (n % 100)).unwrap() // 1,048,576 bytes, i.e. 1MiB.
};
@ -292,7 +302,7 @@ pub extern "C" fn fuzz_rkv_calls(raw_data: *const u8, size: libc::size_t) -> lib
let root = Builder::new().prefix("fuzz_rkv_calls").tempdir().unwrap();
fs::create_dir_all(root.path()).unwrap();
let mut builder = rkv::Rkv::environment_builder();
let mut builder: SafeMode = Rkv::environment_builder();
builder.set_max_dbs(1); // need at least one db
maybe_do(&mut fuzz, |fuzz| {
@ -308,7 +318,7 @@ pub extern "C" fn fuzz_rkv_calls(raw_data: *const u8, size: libc::size_t) -> lib
builder.set_map_size(1_048_576 * (n % 100)); // 1,048,576 bytes, i.e. 1MiB.
});
let env = rkv::Rkv::from_env(root.path(), builder).unwrap();
let env = Rkv::from_builder(root.path(), builder).unwrap();
let store = env
.open_single("test", rkv::StoreOptions::create())
.unwrap();