зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1671170 - Downgrade smallvec to 1.3. r=markh
See https://github.com/servo/rust-smallvec/issues/243 and the PRs in the comments. Differential Revision: https://phabricator.services.mozilla.com/D98802
This commit is contained in:
Родитель
62dc874ef0
Коммит
80b8ba4acd
|
@ -617,15 +617,6 @@ dependencies = [
|
|||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.29"
|
||||
|
@ -3678,12 +3669,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.8.0"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b"
|
||||
checksum = "d7c6d9b8427445284a09c55be860a15855ab580a417ccad9da88f5a06787ced0"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"cloudabi",
|
||||
"cfg-if 1.0.0",
|
||||
"instant",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
|
@ -4356,9 +4346,9 @@ checksum = "5d79b4b604167921892e84afbbaad9d5ad74e091bf6c511d9dbfb0593f09fabd"
|
|||
|
||||
[[package]]
|
||||
name = "rusqlite"
|
||||
version = "0.24.1"
|
||||
version = "0.24.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e3d4791ab5517217f51216a84a688b53c1ebf7988736469c538d02f46ddba68"
|
||||
checksum = "d5f38ee71cbab2c827ec0ac24e76f82eca723cee92c509a65f67dee393c25112"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"fallible-iterator",
|
||||
|
@ -4709,9 +4699,9 @@ checksum = "797a4eaffb90d896f29698d45676f9f940a71936d7574996a7df54593ba209fa"
|
|||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.4.2"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
|
||||
checksum = "05720e22615919e4734f6a99ceae50d00226c3c5aca406e102ebc33298214e0a"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
|
|
@ -66,7 +66,8 @@ servo_arc = { path = "../servo_arc" }
|
|||
servo_atoms = {path = "../atoms", optional = true}
|
||||
servo_config = {path = "../config", optional = true}
|
||||
smallbitvec = "2.3.0"
|
||||
smallvec = "1.0"
|
||||
# See https://github.com/servo/rust-smallvec/issues/243
|
||||
smallvec = "=1.3"
|
||||
static_prefs = { path = "../../../modules/libpref/init/static_prefs" }
|
||||
string_cache = { version = "0.8", optional = true }
|
||||
style_derive = {path = "../style_derive"}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
{"files":{"Cargo.toml":"8f287443ede083f9f2816bccdd6a23f0b58e70337315c06a34a9ae06029242d1","cloudabi.rs":"5660f8ac289098a3fc9b39df2c8ec1f218bbbd8a98ec38b17f24a1dd8fbc0bdb"},"package":"4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467"}
|
|
@ -1,32 +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 = "cloudabi"
|
||||
version = "0.1.0"
|
||||
authors = ["Nuxi (https://nuxi.nl/) and contributors"]
|
||||
description = "Low level interface to CloudABI. Contains all syscalls and related types."
|
||||
homepage = "https://cloudabi.org/"
|
||||
documentation = "https://docs.rs/cloudabi/"
|
||||
keywords = ["cloudabi"]
|
||||
license = "BSD-2-Clause"
|
||||
repository = "https://github.com/nuxinl/cloudabi"
|
||||
|
||||
[lib]
|
||||
path = "cloudabi.rs"
|
||||
[dependencies.bitflags]
|
||||
version = "1.2.1"
|
||||
optional = true
|
||||
|
||||
[features]
|
||||
default = ["bitflags"]
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"f1e6b94b0b13664976a1ebeef3163f4560077e17b9254593f7c566c653fbcc93","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"c9a75f18b9ab2927829a208fc6aa2cf4e63b8420887ba29cdb265d6619ae82d5","src/lib.rs":"058dddad16d91c8d0160fa2a78bb5f7c2f801f2fd9770fc387c5843395bf0379","src/parking_lot.rs":"586fa7ff7ee77c19dcea83310135709f0beda3a3395c4b305217b67e83e6b410","src/spinwait.rs":"d568d8a81f9144ec4c4a139dc934d7d04ee1656a4a221eb548742fe7aba09ab1","src/thread_parker/cloudabi.rs":"dba5efaf7538c3d8731e9ef9aa41bb48aaa1721c61acb64eb224b38edf12b663","src/thread_parker/generic.rs":"574aecb3c325012b683eca4135441ec73f44c33cc9955aa05db24d7e4c991cd7","src/thread_parker/linux.rs":"4a2c76b3dc09301ceb73d904460f49d91bc1a2492cc123ee26ca22ece3faae79","src/thread_parker/mod.rs":"347fe878b616ec69eeffc188475920b47b3d802756565d32e004fc342eea771f","src/thread_parker/redox.rs":"91ca107c4edffa57e87294cadec3b6010b584fb272c044e2557c925dbcb90f6a","src/thread_parker/sgx.rs":"898ced116fb7b0ac077b5977b5bcac610f1d55beffb613ec73e083b1ef09cc28","src/thread_parker/unix.rs":"8ff84ab0a629e8891b663226c8867ae4bb0fc63f0b3504e85b4583e7bf73a589","src/thread_parker/wasm.rs":"903b7eec240cdbe8a23467f6b41d042d93b35755bd1763be02f9cc55756c4aec","src/thread_parker/wasm_atomic.rs":"85f2d7e9982ef64f077fc6ee2e10f81027d556b08c5618e86913c137571e377e","src/thread_parker/windows/keyed_event.rs":"fc1cf4e592d814c4c949217d91317ec2afb6048430abebb3cea2e8487b369734","src/thread_parker/windows/mod.rs":"c99a3871e69800452a56928a9e870530b7f48a563a4d3efe6184103147899f0c","src/thread_parker/windows/waitaddress.rs":"8e037df2a5692905e2bc2d4ea955295ab92bcc7e26eea0bb7a4eaac9ce657321","src/util.rs":"285e6133150645525f2ca1ece41f6d35bad4e7c5e08b42b20c99d2a97e04a974","src/word_lock.rs":"2c030aedb340ae8ca564365206452c298fe29986d005d6a40e808c9760f91c95"},"package":"c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b"}
|
||||
{"files":{"Cargo.toml":"5c6baed932139022eb9544cb9b2ea8434bd1dc4add567257bbc0245f52efaa85","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"c9a75f18b9ab2927829a208fc6aa2cf4e63b8420887ba29cdb265d6619ae82d5","src/lib.rs":"7baf09034aafc28f7dbb1550cdde89221e4eb5dfda51b55aeb652ee8710c715d","src/parking_lot.rs":"58125667bd78399e8753b6bd8acef84f180f369f0bc174c573887176bab9f9d3","src/spinwait.rs":"d568d8a81f9144ec4c4a139dc934d7d04ee1656a4a221eb548742fe7aba09ab1","src/thread_parker/generic.rs":"574aecb3c325012b683eca4135441ec73f44c33cc9955aa05db24d7e4c991cd7","src/thread_parker/linux.rs":"4a2c76b3dc09301ceb73d904460f49d91bc1a2492cc123ee26ca22ece3faae79","src/thread_parker/mod.rs":"9c675b7690bbde62e88d946fad218623d423edccff4e01e8e52b116d815c695c","src/thread_parker/redox.rs":"91ca107c4edffa57e87294cadec3b6010b584fb272c044e2557c925dbcb90f6a","src/thread_parker/sgx.rs":"898ced116fb7b0ac077b5977b5bcac610f1d55beffb613ec73e083b1ef09cc28","src/thread_parker/unix.rs":"8ff84ab0a629e8891b663226c8867ae4bb0fc63f0b3504e85b4583e7bf73a589","src/thread_parker/wasm.rs":"903b7eec240cdbe8a23467f6b41d042d93b35755bd1763be02f9cc55756c4aec","src/thread_parker/wasm_atomic.rs":"cf761157803256b18205e747bc99e30b18d5410c27121fa9595e12cb51bb6bef","src/thread_parker/windows/keyed_event.rs":"fc1cf4e592d814c4c949217d91317ec2afb6048430abebb3cea2e8487b369734","src/thread_parker/windows/mod.rs":"c99a3871e69800452a56928a9e870530b7f48a563a4d3efe6184103147899f0c","src/thread_parker/windows/waitaddress.rs":"8e037df2a5692905e2bc2d4ea955295ab92bcc7e26eea0bb7a4eaac9ce657321","src/util.rs":"285e6133150645525f2ca1ece41f6d35bad4e7c5e08b42b20c99d2a97e04a974","src/word_lock.rs":"2c030aedb340ae8ca564365206452c298fe29986d005d6a40e808c9760f91c95"},"package":"d7c6d9b8427445284a09c55be860a15855ab580a417ccad9da88f5a06787ced0"}
|
|
@ -13,7 +13,7 @@
|
|||
[package]
|
||||
edition = "2018"
|
||||
name = "parking_lot_core"
|
||||
version = "0.8.0"
|
||||
version = "0.8.1"
|
||||
authors = ["Amanieu d'Antras <amanieu@gmail.com>"]
|
||||
description = "An advanced API for creating custom synchronization primitives."
|
||||
keywords = ["mutex", "condvar", "rwlock", "once", "thread"]
|
||||
|
@ -25,7 +25,7 @@ version = "0.3.49"
|
|||
optional = true
|
||||
|
||||
[dependencies.cfg-if]
|
||||
version = "0.1.10"
|
||||
version = "1.0.0"
|
||||
|
||||
[dependencies.instant]
|
||||
version = "0.1.4"
|
||||
|
@ -35,7 +35,7 @@ version = "0.5.1"
|
|||
optional = true
|
||||
|
||||
[dependencies.smallvec]
|
||||
version = "1.4.0"
|
||||
version = "1.0"
|
||||
|
||||
[dependencies.thread-id]
|
||||
version = "3.3.0"
|
||||
|
@ -44,8 +44,6 @@ optional = true
|
|||
[features]
|
||||
deadlock_detection = ["petgraph", "thread-id", "backtrace"]
|
||||
nightly = []
|
||||
[target."cfg(target_os = \"cloudabi\")".dependencies.cloudabi]
|
||||
version = "0.1.0"
|
||||
[target."cfg(target_os = \"redox\")".dependencies.redox_syscall]
|
||||
version = "0.1.56"
|
||||
[target."cfg(unix)".dependencies.libc]
|
||||
|
|
|
@ -51,10 +51,6 @@
|
|||
),
|
||||
feature(stdsimd)
|
||||
)]
|
||||
#![cfg_attr(
|
||||
all(feature = "nightly", target_os = "cloudabi",),
|
||||
feature(thread_local)
|
||||
)]
|
||||
|
||||
mod parking_lot;
|
||||
mod spinwait;
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
use crate::thread_parker::{ThreadParker, ThreadParkerT, UnparkHandleT};
|
||||
use crate::util::UncheckedOptionExt;
|
||||
use crate::word_lock::WordLock;
|
||||
use cfg_if::cfg_if;
|
||||
use core::{
|
||||
cell::{Cell, UnsafeCell},
|
||||
ptr,
|
||||
|
@ -17,46 +16,6 @@ use instant::Instant;
|
|||
use smallvec::SmallVec;
|
||||
use std::time::Duration;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(all(
|
||||
target_arch = "wasm32",
|
||||
target_os = "unknown",
|
||||
target_vendor = "unknown"
|
||||
))] {
|
||||
use core::ops::Add;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
|
||||
struct DummyInstant(Duration);
|
||||
|
||||
impl DummyInstant {
|
||||
pub fn now() -> DummyInstant {
|
||||
DummyInstant::zero()
|
||||
}
|
||||
|
||||
const fn zero() -> DummyInstant {
|
||||
DummyInstant(Duration::from_secs(0))
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<Duration> for DummyInstant {
|
||||
type Output = DummyInstant;
|
||||
|
||||
fn add(self, _rhs: Duration) -> DummyInstant {
|
||||
DummyInstant::zero()
|
||||
}
|
||||
}
|
||||
|
||||
// Use dummy implementation for `Instant` on `wasm32`. The reason for this is
|
||||
// that `Instant::now()` will always panic because time is currently not implemented
|
||||
// on wasm32-unknown-unknown.
|
||||
// See https://github.com/rust-lang/rust/blob/master/src/libstd/sys/wasm/time.rs
|
||||
type InstantType = DummyInstant;
|
||||
} else {
|
||||
// Otherwise use `instant::Instant`
|
||||
type InstantType = Instant;
|
||||
}
|
||||
}
|
||||
|
||||
static NUM_THREADS: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
/// Holds the pointer to the currently active `HashTable`.
|
||||
|
@ -88,7 +47,7 @@ impl HashTable {
|
|||
let new_size = (num_threads * LOAD_FACTOR).next_power_of_two();
|
||||
let hash_bits = 0usize.leading_zeros() - new_size.leading_zeros() - 1;
|
||||
|
||||
let now = InstantType::now();
|
||||
let now = Instant::now();
|
||||
let mut entries = Vec::with_capacity(new_size);
|
||||
for i in 0..new_size {
|
||||
// We must ensure the seed is not zero
|
||||
|
@ -118,7 +77,7 @@ struct Bucket {
|
|||
|
||||
impl Bucket {
|
||||
#[inline]
|
||||
pub fn new(timeout: InstantType, seed: u32) -> Self {
|
||||
pub fn new(timeout: Instant, seed: u32) -> Self {
|
||||
Self {
|
||||
mutex: WordLock::new(),
|
||||
queue_head: Cell::new(ptr::null()),
|
||||
|
@ -130,7 +89,7 @@ impl Bucket {
|
|||
|
||||
struct FairTimeout {
|
||||
// Next time at which point be_fair should be set
|
||||
timeout: InstantType,
|
||||
timeout: Instant,
|
||||
|
||||
// the PRNG state for calculating the next timeout
|
||||
seed: u32,
|
||||
|
@ -138,14 +97,14 @@ struct FairTimeout {
|
|||
|
||||
impl FairTimeout {
|
||||
#[inline]
|
||||
fn new(timeout: InstantType, seed: u32) -> FairTimeout {
|
||||
fn new(timeout: Instant, seed: u32) -> FairTimeout {
|
||||
FairTimeout { timeout, seed }
|
||||
}
|
||||
|
||||
// Determine whether we should force a fair unlock, and update the timeout
|
||||
#[inline]
|
||||
fn should_timeout(&mut self) -> bool {
|
||||
let now = InstantType::now();
|
||||
let now = Instant::now();
|
||||
if now > self.timeout {
|
||||
// Time between 0 and 1ms.
|
||||
let nanos = self.gen_u32() % 1_000_000;
|
||||
|
|
|
@ -1,305 +0,0 @@
|
|||
// Copyright 2016 Amanieu d'Antras
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
|
||||
use cloudabi as abi;
|
||||
use core::{
|
||||
cell::Cell,
|
||||
mem::{self, MaybeUninit},
|
||||
sync::atomic::{AtomicU32, Ordering},
|
||||
};
|
||||
use instant::Instant;
|
||||
use std::{convert::TryFrom, thread};
|
||||
|
||||
extern "C" {
|
||||
#[thread_local]
|
||||
static __pthread_thread_id: abi::tid;
|
||||
}
|
||||
|
||||
struct Lock {
|
||||
lock: AtomicU32,
|
||||
}
|
||||
|
||||
impl Lock {
|
||||
pub fn new() -> Self {
|
||||
Lock {
|
||||
lock: AtomicU32::new(abi::LOCK_UNLOCKED.0),
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// See `Lock::lock`.
|
||||
unsafe fn try_lock(&self) -> Option<LockGuard> {
|
||||
// Attempt to acquire the lock.
|
||||
if let Err(old) = self.lock.compare_exchange(
|
||||
abi::LOCK_UNLOCKED.0,
|
||||
__pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
|
||||
Ordering::Acquire,
|
||||
Ordering::Relaxed,
|
||||
) {
|
||||
// Failure. Crash upon recursive acquisition.
|
||||
debug_assert_ne!(
|
||||
old & !abi::LOCK_KERNEL_MANAGED.0,
|
||||
__pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
|
||||
"Attempted to recursive write-lock a lock",
|
||||
);
|
||||
None
|
||||
} else {
|
||||
Some(LockGuard { lock: &self.lock })
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// This method is unsafe because the `LockGuard` has a raw pointer into this `Lock`
|
||||
/// that it will access on drop to unlock the lock. So make sure the `LockGuard` goes
|
||||
/// out of scope before the `Lock` it came from moves or goes out of scope.
|
||||
pub unsafe fn lock(&self) -> LockGuard {
|
||||
self.try_lock().unwrap_or_else(|| {
|
||||
// Call into the kernel to acquire a write lock.
|
||||
let subscription = abi::subscription {
|
||||
r#type: abi::eventtype::LOCK_WRLOCK,
|
||||
union: abi::subscription_union {
|
||||
lock: abi::subscription_lock {
|
||||
lock: self.ptr(),
|
||||
lock_scope: abi::scope::PRIVATE,
|
||||
},
|
||||
},
|
||||
..mem::zeroed()
|
||||
};
|
||||
let mut event = MaybeUninit::<abi::event>::uninit();
|
||||
let mut nevents: usize = 0;
|
||||
let ret = abi::poll(&subscription, event.as_mut_ptr(), 1, &mut nevents);
|
||||
debug_assert_eq!(ret, abi::errno::SUCCESS);
|
||||
debug_assert_eq!(event.assume_init().error, abi::errno::SUCCESS);
|
||||
|
||||
LockGuard { lock: &self.lock }
|
||||
})
|
||||
}
|
||||
|
||||
fn ptr(&self) -> *mut abi::lock {
|
||||
&self.lock as *const AtomicU32 as *mut abi::lock
|
||||
}
|
||||
}
|
||||
|
||||
struct LockGuard {
|
||||
lock: *const AtomicU32,
|
||||
}
|
||||
|
||||
impl LockGuard {
|
||||
fn ptr(&self) -> *mut abi::lock {
|
||||
self.lock as *mut abi::lock
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for LockGuard {
|
||||
fn drop(&mut self) {
|
||||
let lock = unsafe { &*self.lock };
|
||||
debug_assert_eq!(
|
||||
lock.load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0,
|
||||
unsafe { __pthread_thread_id.0 } | abi::LOCK_WRLOCKED.0,
|
||||
"This lock is not write-locked by this thread"
|
||||
);
|
||||
|
||||
if !lock
|
||||
.compare_exchange(
|
||||
unsafe { __pthread_thread_id.0 } | abi::LOCK_WRLOCKED.0,
|
||||
abi::LOCK_UNLOCKED.0,
|
||||
Ordering::Release,
|
||||
Ordering::Relaxed,
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
// Lock is managed by kernelspace. Call into the kernel
|
||||
// to unblock waiting threads.
|
||||
let ret = unsafe { abi::lock_unlock(self.lock as *mut abi::lock, abi::scope::PRIVATE) };
|
||||
debug_assert_eq!(ret, abi::errno::SUCCESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Condvar {
|
||||
condvar: AtomicU32,
|
||||
}
|
||||
|
||||
impl Condvar {
|
||||
pub fn new() -> Self {
|
||||
Condvar {
|
||||
condvar: AtomicU32::new(abi::CONDVAR_HAS_NO_WAITERS.0),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wait(&self, lock: &LockGuard) {
|
||||
unsafe {
|
||||
let subscription = abi::subscription {
|
||||
r#type: abi::eventtype::CONDVAR,
|
||||
union: abi::subscription_union {
|
||||
condvar: abi::subscription_condvar {
|
||||
condvar: self.ptr(),
|
||||
condvar_scope: abi::scope::PRIVATE,
|
||||
lock: lock.ptr(),
|
||||
lock_scope: abi::scope::PRIVATE,
|
||||
},
|
||||
},
|
||||
..mem::zeroed()
|
||||
};
|
||||
let mut event = MaybeUninit::<abi::event>::uninit();
|
||||
let mut nevents: usize = 0;
|
||||
|
||||
let ret = abi::poll(&subscription, event.as_mut_ptr(), 1, &mut nevents);
|
||||
debug_assert_eq!(ret, abi::errno::SUCCESS);
|
||||
debug_assert_eq!(event.assume_init().error, abi::errno::SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
/// Waits for a signal on the condvar.
|
||||
/// Returns false if it times out before anyone notified us.
|
||||
pub fn wait_timeout(&self, lock: &LockGuard, timeout: abi::timestamp) -> bool {
|
||||
unsafe {
|
||||
let subscriptions = [
|
||||
abi::subscription {
|
||||
r#type: abi::eventtype::CONDVAR,
|
||||
union: abi::subscription_union {
|
||||
condvar: abi::subscription_condvar {
|
||||
condvar: self.ptr(),
|
||||
condvar_scope: abi::scope::PRIVATE,
|
||||
lock: lock.ptr(),
|
||||
lock_scope: abi::scope::PRIVATE,
|
||||
},
|
||||
},
|
||||
..mem::zeroed()
|
||||
},
|
||||
abi::subscription {
|
||||
r#type: abi::eventtype::CLOCK,
|
||||
union: abi::subscription_union {
|
||||
clock: abi::subscription_clock {
|
||||
clock_id: abi::clockid::MONOTONIC,
|
||||
timeout,
|
||||
..mem::zeroed()
|
||||
},
|
||||
},
|
||||
..mem::zeroed()
|
||||
},
|
||||
];
|
||||
let mut events = MaybeUninit::<[abi::event; 2]>::uninit();
|
||||
let mut nevents: usize = 0;
|
||||
|
||||
let ret = abi::poll(
|
||||
subscriptions.as_ptr(),
|
||||
events.as_mut_ptr() as *mut _,
|
||||
2,
|
||||
&mut nevents,
|
||||
);
|
||||
debug_assert_eq!(ret, abi::errno::SUCCESS);
|
||||
let events = events.assume_init();
|
||||
for i in 0..nevents {
|
||||
debug_assert_eq!(events[i].error, abi::errno::SUCCESS);
|
||||
if events[i].r#type == abi::eventtype::CONDVAR {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn notify(&self) {
|
||||
let ret = unsafe { abi::condvar_signal(self.ptr(), abi::scope::PRIVATE, 1) };
|
||||
debug_assert_eq!(ret, abi::errno::SUCCESS);
|
||||
}
|
||||
|
||||
fn ptr(&self) -> *mut abi::condvar {
|
||||
&self.condvar as *const AtomicU32 as *mut abi::condvar
|
||||
}
|
||||
}
|
||||
|
||||
// Helper type for putting a thread to sleep until some other thread wakes it up
|
||||
pub struct ThreadParker {
|
||||
should_park: Cell<bool>,
|
||||
lock: Lock,
|
||||
condvar: Condvar,
|
||||
}
|
||||
|
||||
impl super::ThreadParkerT for ThreadParker {
|
||||
type UnparkHandle = UnparkHandle;
|
||||
|
||||
const IS_CHEAP_TO_CONSTRUCT: bool = true;
|
||||
|
||||
fn new() -> ThreadParker {
|
||||
ThreadParker {
|
||||
should_park: Cell::new(false),
|
||||
lock: Lock::new(),
|
||||
condvar: Condvar::new(),
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn prepare_park(&self) {
|
||||
self.should_park.set(true);
|
||||
}
|
||||
|
||||
unsafe fn timed_out(&self) -> bool {
|
||||
// We need to grab the lock here because another thread may be
|
||||
// concurrently executing UnparkHandle::unpark, which is done without
|
||||
// holding the queue lock.
|
||||
let _guard = self.lock.lock();
|
||||
self.should_park.get()
|
||||
}
|
||||
|
||||
unsafe fn park(&self) {
|
||||
let guard = self.lock.lock();
|
||||
while self.should_park.get() {
|
||||
self.condvar.wait(&guard);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn park_until(&self, timeout: Instant) -> bool {
|
||||
let guard = self.lock.lock();
|
||||
while self.should_park.get() {
|
||||
if let Some(duration_left) = timeout.checked_duration_since(Instant::now()) {
|
||||
if let Ok(nanos_left) = abi::timestamp::try_from(duration_left.as_nanos()) {
|
||||
self.condvar.wait_timeout(&guard, nanos_left);
|
||||
} else {
|
||||
// remaining timeout overflows an abi::timestamp. Sleep indefinitely
|
||||
self.condvar.wait(&guard);
|
||||
}
|
||||
} else {
|
||||
// We timed out
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
unsafe fn unpark_lock(&self) -> UnparkHandle {
|
||||
let _lock_guard = self.lock.lock();
|
||||
|
||||
UnparkHandle {
|
||||
thread_parker: self,
|
||||
_lock_guard,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UnparkHandle {
|
||||
thread_parker: *const ThreadParker,
|
||||
_lock_guard: LockGuard,
|
||||
}
|
||||
|
||||
impl super::UnparkHandleT for UnparkHandle {
|
||||
unsafe fn unpark(self) {
|
||||
(*self.thread_parker).should_park.set(false);
|
||||
|
||||
// We notify while holding the lock here to avoid races with the target
|
||||
// thread. In particular, the thread could exit after we unlock the
|
||||
// mutex, which would make the condvar access invalid memory.
|
||||
(*self.thread_parker).condvar.notify();
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn thread_yield() {
|
||||
thread::yield_now();
|
||||
}
|
|
@ -76,9 +76,6 @@ cfg_if! {
|
|||
} else if #[cfg(target_arch = "wasm32")] {
|
||||
#[path = "wasm.rs"]
|
||||
mod imp;
|
||||
} else if #[cfg(all(feature = "nightly", target_os = "cloudabi"))] {
|
||||
#[path = "cloudabi.rs"]
|
||||
mod imp;
|
||||
} else {
|
||||
#[path = "generic.rs"]
|
||||
mod imp;
|
||||
|
|
|
@ -5,13 +5,41 @@
|
|||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
use core::{
|
||||
arch::wasm32,
|
||||
sync::atomic::{AtomicI32, Ordering},
|
||||
};
|
||||
use instant::Instant;
|
||||
use std::time::Duration;
|
||||
use std::{convert::TryFrom, thread};
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(all(
|
||||
target_arch = "wasm32",
|
||||
target_os = "unknown",
|
||||
target_vendor = "unknown"
|
||||
))] {
|
||||
// This function serves as a polyfill for `Instant::checked_duration_since`, which is
|
||||
// currently not implemented for wasm32-unknown-unknown.
|
||||
// TODO: Remove this shim once it
|
||||
fn checked_duration_since_now(other: Instant) -> Option<Duration> {
|
||||
let now = Instant::now();
|
||||
|
||||
if other < now {
|
||||
None
|
||||
} else {
|
||||
Some(other.duration_since(now))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If we are not targeting wasm32, we can use the native `checked_duration_since`.
|
||||
fn checked_duration_since_now(timeout: Instant) -> Option<Duration> {
|
||||
timeout.checked_duration_since(Instant::now())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper type for putting a thread to sleep until some other thread wakes it up
|
||||
pub struct ThreadParker {
|
||||
parked: AtomicI32,
|
||||
|
@ -45,7 +73,7 @@ impl super::ThreadParkerT for ThreadParker {
|
|||
#[inline]
|
||||
unsafe fn park(&self) {
|
||||
while self.parked.load(Ordering::Acquire) == PARKED {
|
||||
let r = unsafe { wasm32::i32_atomic_wait(self.ptr(), PARKED, -1) };
|
||||
let r = wasm32::memory_atomic_wait32(self.ptr(), PARKED, -1);
|
||||
// we should have either woken up (0) or got a not-equal due to a
|
||||
// race (1). We should never time out (2)
|
||||
debug_assert!(r == 0 || r == 1);
|
||||
|
@ -55,9 +83,9 @@ impl super::ThreadParkerT for ThreadParker {
|
|||
#[inline]
|
||||
unsafe fn park_until(&self, timeout: Instant) -> bool {
|
||||
while self.parked.load(Ordering::Acquire) == PARKED {
|
||||
if let Some(left) = timeout.checked_duration_since(Instant::now()) {
|
||||
if let Some(left) = checked_duration_since_now(timeout) {
|
||||
let nanos_left = i64::try_from(left.as_nanos()).unwrap_or(i64::max_value());
|
||||
let r = unsafe { wasm32::i32_atomic_wait(self.ptr(), PARKED, nanos_left) };
|
||||
let r = wasm32::memory_atomic_wait32(self.ptr(), PARKED, nanos_left);
|
||||
debug_assert!(r == 0 || r == 1 || r == 2);
|
||||
} else {
|
||||
return false;
|
||||
|
@ -86,7 +114,7 @@ pub struct UnparkHandle(*mut i32);
|
|||
impl super::UnparkHandleT for UnparkHandle {
|
||||
#[inline]
|
||||
unsafe fn unpark(self) {
|
||||
let num_notified = unsafe { wasm32::atomic_notify(self.0 as *mut i32, 1) };
|
||||
let num_notified = wasm32::memory_atomic_notify(self.0 as *mut i32, 1);
|
||||
debug_assert!(num_notified == 0 || num_notified == 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"56285617b69a9e2ea1d922620fb2ba960cb487fcececd016ef41dcb9c850f53a","Changelog.md":"34c6aa9cde3eb6b2803ec1072368ae412eac2da7c8a770ab2bd643a3fa1f9c5d","LICENSE":"6e93da4b8f1e937ae6addcac29c06bac66358611488c17fd1f46c6fa485f519c","README.md":"1730524868f2391f2501f3e8f1516e4cc63dc5e93b4d7dfb211ad8f3de460dac","appveyor.yml":"0bcc97462ce19ea2d7018b5a0f322d4d0ffc085a31cd18abe540ede05c770ff2","benches/cache.rs":"30459d8d7f65dd684909a53590f9be32e2e545a0775cd93ee0ce85dd08410955","benches/exec.rs":"cb7feb1738d4565c8265538a95a869a99ca360ed20c68bb69e84bd31ecbce094","clippy.toml":"98f90bbe52849b3078daeccfbe87aec1c08d02b94a453a15149a1fcccb7cafd0","codecov.yml":"17e6a8fa616f9a9f46ce420761ad15ddf0d8b5fb64c75c04365e5f269ab60ee5","publish-ghp-docs.sh":"3e2c59e09ce377c46a62511aa17389e6bf824c17d2fc5a818409ede40ba64c23","src/backup.rs":"00ee47c6b3d96393e68a3c9467e61f4082613bdd7e06607ef8b9238b62122de2","src/blob/mod.rs":"a8ea454a6bb31becd8b83e10c32c2e19a5a2fbb91cdfbd9fb0ec8525a162b2a7","src/blob/pos_io.rs":"6a41d298789ba7b2efa339f7cfcefef4162d39daf0400ca4fd3849f2f9534c45","src/busy.rs":"1308fbb2a09940207e59e6730d84165e262d95409ee11d434e4e846bb327caac","src/cache.rs":"024aac5c2a955fe60e54871a5ffd0d4fe56410398d2f2202c53f13c425533820","src/collation.rs":"1871a5d1973aedeaf8db52ab635702d77cc7a958d604f307cb498b5060db0d8e","src/column.rs":"7e7c7d5532202eaed6d453cb4cc3f46e3901f0528c5f1c83bfa08a0fd3d87264","src/config.rs":"70620f037d79bbb59ce4fff406b4aff4333cc14901dab8a6deeb4715d30ebc63","src/context.rs":"7550b77ccc1362ebbefa85e51ad70bf3d4e7d4f7817fcaac8cf34300962b7c33","src/error.rs":"dd7ab850c864aabd7bed4988955e652bff00546c20c16e3fe9ed471a655fb684","src/functions.rs":"ed50aacc01f1087ba7af347c0d46ee443360932dbdc539583cbf8b59a221bfdb","src/hooks.rs":"3ca1bcc9ba80f41c003331d779f1116c5c83daaf2bc5740fd0feb56710babce1","src/inner_connection.rs":"844a609bde6131ca13dd1a496181b405ae4f6a79766721adec01c3cf75e82c2a","src/lib.rs":"cd4c916eb8e1fbcc8eff2435b136e7f3723e7d62a691758018ee6e2bbf4678c5","src/limits.rs":"75d339cf1f21c744f42f339dcfccf44e149bd2d1294ad0fe412b0792d9c809ab","src/load_extension_guard.rs":"cd349613067410fa4be811d7522fc50004fbc48feb050c19f80a097ab919f9fb","src/pragma.rs":"f6820bcccd50ef804be09f348069208a2bc227de6959c0e3d9ac42b9c4c3e454","src/raw_statement.rs":"40864c284d9b29842831e92ca92eecf6ac77e5f166b43fc55043e62405e9e190","src/row.rs":"5f0e20ec6bbe9e6c5bce80e34bb76ba06b3abf54ef42755394f144ed1ad2e0c9","src/session.rs":"a4730dd21a0dd880d6cff46236fd3c7ad5ad5de4f607203c13062011162f3029","src/statement.rs":"32e3df655ff71ae0415539c6d79197f8e21315a583bfcad39906e0f8da4abc38","src/trace.rs":"686f46f9b27c9d446aaeff2eae0e8346177cedc48859c1fdac7453386797fe6e","src/transaction.rs":"41c5b8b0355401cace43996d311065a8e05846cb40a15d043f51bdd9e0606ffb","src/types/chrono.rs":"1d6aebb7b8efc6038ec30c95d91cee7a16c826bf5a78aca1bc75c86349e17c83","src/types/from_sql.rs":"3508835cf9a7eba0628dbd0bbbe06783f6fe57e5e8469ca51b288f139cd73436","src/types/mod.rs":"77ef2a40101d7864a651fa601e84ecda0ad441723e6c16dedd5329f4cbe8de84","src/types/serde_json.rs":"a3f11fd63cf5f3ffc9e89134dd3d139ac275aff1948d315b1eb1673d81e8fe95","src/types/time.rs":"f4ce83e8368274cf67677a5b67133adfaf0adef5c600574dd34e2e68da102754","src/types/to_sql.rs":"8544f6c9c6a0676bd75375ddba234d051d9dcf28829f49e3dbb39534142b7981","src/types/url.rs":"b476ca2386a4cc4e8ac500f870993c0445abe91754d4e004bfd19a1b95b53816","src/types/value.rs":"1bc28c99b215bf74821feef60544d5bfbedfcde99590f229d8336e0fc75354f8","src/types/value_ref.rs":"6fb2f5bfb268a90794bfc4aeda41182c7cead0292c84ff56d5141a4825ff1bae","src/unlock_notify.rs":"cf2a91e6484454fc3174be546a7f80934fd40f5be51d174db6a5674e93c9ec4a","src/util/mod.rs":"330b1822393003003e4c890df183eb88e3cfe9d566c8325fb421426811a54193","src/util/param_cache.rs":"efb480749cd74c09aeca28be074050e3a9aed7c8ed1371ca562342cba9c408dd","src/util/small_cstr.rs":"5ec10de6708837c09a67d12a7c503fc2856e933b318f8776ee2b4a6b2ce6cd83","src/util/sqlite_string.rs":"b35a4fac5962d47e0efa1b488d3447997de138aca8e99be8f5073fcbf2081664","src/version.rs":"6df3d88ff62b1f4c46692b515a16d1f02ff27732a3e371788566e6a75d5c1d4d","src/vtab/array.rs":"485d2b441b01d26a8f6a59130c85970afd627e1b953b52434964835f8b6a2aef","src/vtab/csvtab.rs":"1a4b70bdb3cb1eaeee80caded133278280f760bda2eac7ca9185448e121f32ca","src/vtab/mod.rs":"24119ac8328b8aaaf8d75c59e60820055af87dc56db153dabcb3b14113a5e50a","src/vtab/series.rs":"6b6f1c13c3d453ae726721fd09bb51c90a4252d4e662c503d7b0398812e772b7","test.csv":"3f5649d7b9f80468999b80d4d0e747c6f4f1bba80ade792689eeb4359dc1834a","tests/config_log.rs":"e786bb1a0ca1b560788b24a2091e7d294753a7bee8a39f0e6037b435809267df","tests/deny_single_threaded_sqlite_config.rs":"586ee163d42d886d88ae319cb2184c021bdf9f6da9a8325d799ba10ddeadcbe0","tests/vtab.rs":"0bb466e5ad5f96443ed5ef7f7252656dc5d3c6c3cc44d179195f654190065c04"},"package":"7e3d4791ab5517217f51216a84a688b53c1ebf7988736469c538d02f46ddba68"}
|
||||
{"files":{"Cargo.toml":"a68dc0863956a747f6526f566355c2f176dc1f0e522742ee1b4fe83f56dce905","Changelog.md":"34c6aa9cde3eb6b2803ec1072368ae412eac2da7c8a770ab2bd643a3fa1f9c5d","LICENSE":"6e93da4b8f1e937ae6addcac29c06bac66358611488c17fd1f46c6fa485f519c","README.md":"2265be99f12cc6805897266a26fb27227e4bb226293f3952de6edc4e2e47b8ef","appveyor.yml":"0bcc97462ce19ea2d7018b5a0f322d4d0ffc085a31cd18abe540ede05c770ff2","benches/cache.rs":"30459d8d7f65dd684909a53590f9be32e2e545a0775cd93ee0ce85dd08410955","benches/exec.rs":"cb7feb1738d4565c8265538a95a869a99ca360ed20c68bb69e84bd31ecbce094","clippy.toml":"98f90bbe52849b3078daeccfbe87aec1c08d02b94a453a15149a1fcccb7cafd0","codecov.yml":"17e6a8fa616f9a9f46ce420761ad15ddf0d8b5fb64c75c04365e5f269ab60ee5","publish-ghp-docs.sh":"3e2c59e09ce377c46a62511aa17389e6bf824c17d2fc5a818409ede40ba64c23","src/backup.rs":"00ee47c6b3d96393e68a3c9467e61f4082613bdd7e06607ef8b9238b62122de2","src/blob/mod.rs":"a8ea454a6bb31becd8b83e10c32c2e19a5a2fbb91cdfbd9fb0ec8525a162b2a7","src/blob/pos_io.rs":"6a41d298789ba7b2efa339f7cfcefef4162d39daf0400ca4fd3849f2f9534c45","src/busy.rs":"1308fbb2a09940207e59e6730d84165e262d95409ee11d434e4e846bb327caac","src/cache.rs":"024aac5c2a955fe60e54871a5ffd0d4fe56410398d2f2202c53f13c425533820","src/collation.rs":"1871a5d1973aedeaf8db52ab635702d77cc7a958d604f307cb498b5060db0d8e","src/column.rs":"7e7c7d5532202eaed6d453cb4cc3f46e3901f0528c5f1c83bfa08a0fd3d87264","src/config.rs":"70620f037d79bbb59ce4fff406b4aff4333cc14901dab8a6deeb4715d30ebc63","src/context.rs":"7550b77ccc1362ebbefa85e51ad70bf3d4e7d4f7817fcaac8cf34300962b7c33","src/error.rs":"dd7ab850c864aabd7bed4988955e652bff00546c20c16e3fe9ed471a655fb684","src/functions.rs":"ed50aacc01f1087ba7af347c0d46ee443360932dbdc539583cbf8b59a221bfdb","src/hooks.rs":"3ca1bcc9ba80f41c003331d779f1116c5c83daaf2bc5740fd0feb56710babce1","src/inner_connection.rs":"844a609bde6131ca13dd1a496181b405ae4f6a79766721adec01c3cf75e82c2a","src/lib.rs":"cd4c916eb8e1fbcc8eff2435b136e7f3723e7d62a691758018ee6e2bbf4678c5","src/limits.rs":"75d339cf1f21c744f42f339dcfccf44e149bd2d1294ad0fe412b0792d9c809ab","src/load_extension_guard.rs":"cd349613067410fa4be811d7522fc50004fbc48feb050c19f80a097ab919f9fb","src/pragma.rs":"f6820bcccd50ef804be09f348069208a2bc227de6959c0e3d9ac42b9c4c3e454","src/raw_statement.rs":"40864c284d9b29842831e92ca92eecf6ac77e5f166b43fc55043e62405e9e190","src/row.rs":"5f0e20ec6bbe9e6c5bce80e34bb76ba06b3abf54ef42755394f144ed1ad2e0c9","src/session.rs":"a4730dd21a0dd880d6cff46236fd3c7ad5ad5de4f607203c13062011162f3029","src/statement.rs":"32e3df655ff71ae0415539c6d79197f8e21315a583bfcad39906e0f8da4abc38","src/trace.rs":"686f46f9b27c9d446aaeff2eae0e8346177cedc48859c1fdac7453386797fe6e","src/transaction.rs":"41c5b8b0355401cace43996d311065a8e05846cb40a15d043f51bdd9e0606ffb","src/types/chrono.rs":"1d6aebb7b8efc6038ec30c95d91cee7a16c826bf5a78aca1bc75c86349e17c83","src/types/from_sql.rs":"3508835cf9a7eba0628dbd0bbbe06783f6fe57e5e8469ca51b288f139cd73436","src/types/mod.rs":"77ef2a40101d7864a651fa601e84ecda0ad441723e6c16dedd5329f4cbe8de84","src/types/serde_json.rs":"a3f11fd63cf5f3ffc9e89134dd3d139ac275aff1948d315b1eb1673d81e8fe95","src/types/time.rs":"f4ce83e8368274cf67677a5b67133adfaf0adef5c600574dd34e2e68da102754","src/types/to_sql.rs":"8544f6c9c6a0676bd75375ddba234d051d9dcf28829f49e3dbb39534142b7981","src/types/url.rs":"b476ca2386a4cc4e8ac500f870993c0445abe91754d4e004bfd19a1b95b53816","src/types/value.rs":"1bc28c99b215bf74821feef60544d5bfbedfcde99590f229d8336e0fc75354f8","src/types/value_ref.rs":"6fb2f5bfb268a90794bfc4aeda41182c7cead0292c84ff56d5141a4825ff1bae","src/unlock_notify.rs":"cf2a91e6484454fc3174be546a7f80934fd40f5be51d174db6a5674e93c9ec4a","src/util/mod.rs":"330b1822393003003e4c890df183eb88e3cfe9d566c8325fb421426811a54193","src/util/param_cache.rs":"efb480749cd74c09aeca28be074050e3a9aed7c8ed1371ca562342cba9c408dd","src/util/small_cstr.rs":"5ec10de6708837c09a67d12a7c503fc2856e933b318f8776ee2b4a6b2ce6cd83","src/util/sqlite_string.rs":"b35a4fac5962d47e0efa1b488d3447997de138aca8e99be8f5073fcbf2081664","src/version.rs":"6df3d88ff62b1f4c46692b515a16d1f02ff27732a3e371788566e6a75d5c1d4d","src/vtab/array.rs":"485d2b441b01d26a8f6a59130c85970afd627e1b953b52434964835f8b6a2aef","src/vtab/csvtab.rs":"1a4b70bdb3cb1eaeee80caded133278280f760bda2eac7ca9185448e121f32ca","src/vtab/mod.rs":"24119ac8328b8aaaf8d75c59e60820055af87dc56db153dabcb3b14113a5e50a","src/vtab/series.rs":"6b6f1c13c3d453ae726721fd09bb51c90a4252d4e662c503d7b0398812e772b7","test.csv":"3f5649d7b9f80468999b80d4d0e747c6f4f1bba80ade792689eeb4359dc1834a","tests/config_log.rs":"e786bb1a0ca1b560788b24a2091e7d294753a7bee8a39f0e6037b435809267df","tests/deny_single_threaded_sqlite_config.rs":"586ee163d42d886d88ae319cb2184c021bdf9f6da9a8325d799ba10ddeadcbe0","tests/vtab.rs":"0bb466e5ad5f96443ed5ef7f7252656dc5d3c6c3cc44d179195f654190065c04"},"package":"d5f38ee71cbab2c827ec0ac24e76f82eca723cee92c509a65f67dee393c25112"}
|
|
@ -13,7 +13,7 @@
|
|||
[package]
|
||||
edition = "2018"
|
||||
name = "rusqlite"
|
||||
version = "0.24.1"
|
||||
version = "0.24.2"
|
||||
authors = ["The rusqlite developers"]
|
||||
description = "Ergonomic wrapper for SQLite"
|
||||
documentation = "http://docs.rs/rusqlite/"
|
||||
|
@ -92,7 +92,7 @@ version = "1.0"
|
|||
optional = true
|
||||
|
||||
[dependencies.smallvec]
|
||||
version = "1.4"
|
||||
version = "1.0"
|
||||
|
||||
[dependencies.time]
|
||||
version = "0.2"
|
||||
|
|
|
@ -123,7 +123,7 @@ You can adjust this behavior in a number of ways:
|
|||
0.20.0). This is probably the simplest solution to any build problems. You can enable this by adding the following in your `Cargo.toml` file:
|
||||
```toml
|
||||
[dependencies.rusqlite]
|
||||
version = "0.24.1"
|
||||
version = "0.24.2"
|
||||
features = ["bundled"]
|
||||
```
|
||||
* You can set the `SQLITE3_LIB_DIR` to point to directory containing the SQLite
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"13560b491e0ed99fe7d16ecef0f728bc57058c007563170d7d644f3bb2433fff","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0b28172679e0009b655da42797c03fd163a3379d5cfa67ba1f1655e974a2a1a9","README.md":"a01127c37308457e8d396b176fb790846be0978c173be3f13260b62efcef011b","benches/bench.rs":"7425b60d83d01a0bcedb5855ec8652fb1089194da5b5d8f7d7d9072c8ea9d133","scripts/run_miri.sh":"0d0b8c54c73fa9da1217d29ed0984f8328dd9fb61bb5a02db44458c360cdc3c4","src/lib.rs":"bb8aef09a9c7a43d225dfd99063261b89ebd6835ced4e2dfe696f1c3eaf9b9d2","src/specialization.rs":"46433586203399251cba496d67b88d34e1be3c2b591986b77463513da1c66471","src/tests.rs":"1c4763444139813d335d33f9eda8b8b719da60a2b13ddcb44e1a6cc278c319cc","tests/macro.rs":"22ad4f6f104a599fdcba19cad8834105b8656b212fb6c7573a427d447f5db14f"},"package":"fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"}
|
||||
{"files":{"Cargo.toml":"45e745963490153700d8392f914b159019420aa81d8ae80241771769199cf65b","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0b28172679e0009b655da42797c03fd163a3379d5cfa67ba1f1655e974a2a1a9","README.md":"a01127c37308457e8d396b176fb790846be0978c173be3f13260b62efcef011b","benches/bench.rs":"9dca7122a3dcb2c099e49807e4d3b8f01d9220e2b3db0a54e9901ee74392866f","lib.rs":"45aa4cd721dd8e649b79c443b9d12b8ff0f9e4dd4188e604b2d6b36b8ceb1c71","scripts/run_miri.sh":"2e83d153efc16cbc3c41589e306faa0624c8b9a0feecea3baae6e34f4563ac42","specialization.rs":"46433586203399251cba496d67b88d34e1be3c2b591986b77463513da1c66471"},"package":"05720e22615919e4734f6a99ceae50d00226c3c5aca406e102ebc33298214e0a"}
|
|
@ -13,8 +13,8 @@
|
|||
[package]
|
||||
edition = "2018"
|
||||
name = "smallvec"
|
||||
version = "1.4.2"
|
||||
authors = ["The Servo Project Developers"]
|
||||
version = "1.3.0"
|
||||
authors = ["Simon Sapin <simon.sapin@exyr.org>"]
|
||||
description = "'Small vector' optimization: store up to a small number of items on the stack"
|
||||
documentation = "https://docs.rs/smallvec/"
|
||||
readme = "README.md"
|
||||
|
@ -22,10 +22,13 @@ keywords = ["small", "vec", "vector", "stack", "no_std"]
|
|||
categories = ["data-structures"]
|
||||
license = "MIT/Apache-2.0"
|
||||
repository = "https://github.com/servo/rust-smallvec"
|
||||
|
||||
[lib]
|
||||
name = "smallvec"
|
||||
path = "lib.rs"
|
||||
[dependencies.serde]
|
||||
version = "1"
|
||||
optional = true
|
||||
default-features = false
|
||||
[dev-dependencies.bincode]
|
||||
version = "1.0.1"
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#![feature(test)]
|
||||
#![allow(deprecated)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate smallvec;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -16,6 +16,6 @@ rustup default "$MIRI_NIGHTLY"
|
|||
rustup component add miri
|
||||
cargo miri setup
|
||||
|
||||
cargo miri test --verbose
|
||||
cargo miri test --verbose --features union
|
||||
cargo miri test --verbose --all-features
|
||||
cargo miri test --verbose -- -Zmiri-ignore-leaks
|
||||
cargo miri test --verbose --features union -- -Zmiri-ignore-leaks
|
||||
cargo miri test --verbose --all-features -- -Zmiri-ignore-leaks
|
||||
|
|
|
@ -1,907 +0,0 @@
|
|||
use crate::{smallvec, SmallVec};
|
||||
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use alloc::borrow::ToOwned;
|
||||
use alloc::boxed::Box;
|
||||
use alloc::rc::Rc;
|
||||
use alloc::{vec, vec::Vec};
|
||||
|
||||
#[test]
|
||||
pub fn test_zero() {
|
||||
let mut v = SmallVec::<[_; 0]>::new();
|
||||
assert!(!v.spilled());
|
||||
v.push(0usize);
|
||||
assert!(v.spilled());
|
||||
assert_eq!(&*v, &[0]);
|
||||
}
|
||||
|
||||
// We heap allocate all these strings so that double frees will show up under valgrind.
|
||||
|
||||
#[test]
|
||||
pub fn test_inline() {
|
||||
let mut v = SmallVec::<[_; 16]>::new();
|
||||
v.push("hello".to_owned());
|
||||
v.push("there".to_owned());
|
||||
assert_eq!(&*v, &["hello".to_owned(), "there".to_owned(),][..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_spill() {
|
||||
let mut v = SmallVec::<[_; 2]>::new();
|
||||
v.push("hello".to_owned());
|
||||
assert_eq!(v[0], "hello");
|
||||
v.push("there".to_owned());
|
||||
v.push("burma".to_owned());
|
||||
assert_eq!(v[0], "hello");
|
||||
v.push("shave".to_owned());
|
||||
assert_eq!(
|
||||
&*v,
|
||||
&[
|
||||
"hello".to_owned(),
|
||||
"there".to_owned(),
|
||||
"burma".to_owned(),
|
||||
"shave".to_owned(),
|
||||
][..]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_double_spill() {
|
||||
let mut v = SmallVec::<[_; 2]>::new();
|
||||
v.push("hello".to_owned());
|
||||
v.push("there".to_owned());
|
||||
v.push("burma".to_owned());
|
||||
v.push("shave".to_owned());
|
||||
v.push("hello".to_owned());
|
||||
v.push("there".to_owned());
|
||||
v.push("burma".to_owned());
|
||||
v.push("shave".to_owned());
|
||||
assert_eq!(
|
||||
&*v,
|
||||
&[
|
||||
"hello".to_owned(),
|
||||
"there".to_owned(),
|
||||
"burma".to_owned(),
|
||||
"shave".to_owned(),
|
||||
"hello".to_owned(),
|
||||
"there".to_owned(),
|
||||
"burma".to_owned(),
|
||||
"shave".to_owned(),
|
||||
][..]
|
||||
);
|
||||
}
|
||||
|
||||
/// https://github.com/servo/rust-smallvec/issues/4
|
||||
#[test]
|
||||
fn issue_4() {
|
||||
SmallVec::<[Box<u32>; 2]>::new();
|
||||
}
|
||||
|
||||
/// https://github.com/servo/rust-smallvec/issues/5
|
||||
#[test]
|
||||
fn issue_5() {
|
||||
assert!(Some(SmallVec::<[&u32; 2]>::new()).is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_with_capacity() {
|
||||
let v: SmallVec<[u8; 3]> = SmallVec::with_capacity(1);
|
||||
assert!(v.is_empty());
|
||||
assert!(!v.spilled());
|
||||
assert_eq!(v.capacity(), 3);
|
||||
|
||||
let v: SmallVec<[u8; 3]> = SmallVec::with_capacity(10);
|
||||
assert!(v.is_empty());
|
||||
assert!(v.spilled());
|
||||
assert_eq!(v.capacity(), 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drain() {
|
||||
let mut v: SmallVec<[u8; 2]> = SmallVec::new();
|
||||
v.push(3);
|
||||
assert_eq!(v.drain(..).collect::<Vec<_>>(), &[3]);
|
||||
|
||||
// spilling the vec
|
||||
v.push(3);
|
||||
v.push(4);
|
||||
v.push(5);
|
||||
let old_capacity = v.capacity();
|
||||
assert_eq!(v.drain(1..).collect::<Vec<_>>(), &[4, 5]);
|
||||
// drain should not change the capacity
|
||||
assert_eq!(v.capacity(), old_capacity);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drain_rev() {
|
||||
let mut v: SmallVec<[u8; 2]> = SmallVec::new();
|
||||
v.push(3);
|
||||
assert_eq!(v.drain(..).rev().collect::<Vec<_>>(), &[3]);
|
||||
|
||||
// spilling the vec
|
||||
v.push(3);
|
||||
v.push(4);
|
||||
v.push(5);
|
||||
assert_eq!(v.drain(..).rev().collect::<Vec<_>>(), &[5, 4, 3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drain_forget() {
|
||||
let mut v: SmallVec<[u8; 1]> = smallvec![0, 1, 2, 3, 4, 5, 6, 7];
|
||||
std::mem::forget(v.drain(2..5));
|
||||
assert_eq!(v.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn into_iter() {
|
||||
let mut v: SmallVec<[u8; 2]> = SmallVec::new();
|
||||
v.push(3);
|
||||
assert_eq!(v.into_iter().collect::<Vec<_>>(), &[3]);
|
||||
|
||||
// spilling the vec
|
||||
let mut v: SmallVec<[u8; 2]> = SmallVec::new();
|
||||
v.push(3);
|
||||
v.push(4);
|
||||
v.push(5);
|
||||
assert_eq!(v.into_iter().collect::<Vec<_>>(), &[3, 4, 5]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn into_iter_rev() {
|
||||
let mut v: SmallVec<[u8; 2]> = SmallVec::new();
|
||||
v.push(3);
|
||||
assert_eq!(v.into_iter().rev().collect::<Vec<_>>(), &[3]);
|
||||
|
||||
// spilling the vec
|
||||
let mut v: SmallVec<[u8; 2]> = SmallVec::new();
|
||||
v.push(3);
|
||||
v.push(4);
|
||||
v.push(5);
|
||||
assert_eq!(v.into_iter().rev().collect::<Vec<_>>(), &[5, 4, 3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn into_iter_drop() {
|
||||
use std::cell::Cell;
|
||||
|
||||
struct DropCounter<'a>(&'a Cell<i32>);
|
||||
|
||||
impl<'a> Drop for DropCounter<'a> {
|
||||
fn drop(&mut self) {
|
||||
self.0.set(self.0.get() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let cell = Cell::new(0);
|
||||
let mut v: SmallVec<[DropCounter<'_>; 2]> = SmallVec::new();
|
||||
v.push(DropCounter(&cell));
|
||||
v.into_iter();
|
||||
assert_eq!(cell.get(), 1);
|
||||
}
|
||||
|
||||
{
|
||||
let cell = Cell::new(0);
|
||||
let mut v: SmallVec<[DropCounter<'_>; 2]> = SmallVec::new();
|
||||
v.push(DropCounter(&cell));
|
||||
v.push(DropCounter(&cell));
|
||||
assert!(v.into_iter().next().is_some());
|
||||
assert_eq!(cell.get(), 2);
|
||||
}
|
||||
|
||||
{
|
||||
let cell = Cell::new(0);
|
||||
let mut v: SmallVec<[DropCounter<'_>; 2]> = SmallVec::new();
|
||||
v.push(DropCounter(&cell));
|
||||
v.push(DropCounter(&cell));
|
||||
v.push(DropCounter(&cell));
|
||||
assert!(v.into_iter().next().is_some());
|
||||
assert_eq!(cell.get(), 3);
|
||||
}
|
||||
{
|
||||
let cell = Cell::new(0);
|
||||
let mut v: SmallVec<[DropCounter<'_>; 2]> = SmallVec::new();
|
||||
v.push(DropCounter(&cell));
|
||||
v.push(DropCounter(&cell));
|
||||
v.push(DropCounter(&cell));
|
||||
{
|
||||
let mut it = v.into_iter();
|
||||
assert!(it.next().is_some());
|
||||
assert!(it.next_back().is_some());
|
||||
}
|
||||
assert_eq!(cell.get(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_capacity() {
|
||||
let mut v: SmallVec<[u8; 2]> = SmallVec::new();
|
||||
v.reserve(1);
|
||||
assert_eq!(v.capacity(), 2);
|
||||
assert!(!v.spilled());
|
||||
|
||||
v.reserve_exact(0x100);
|
||||
assert!(v.capacity() >= 0x100);
|
||||
|
||||
v.push(0);
|
||||
v.push(1);
|
||||
v.push(2);
|
||||
v.push(3);
|
||||
|
||||
v.shrink_to_fit();
|
||||
assert!(v.capacity() < 0x100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate() {
|
||||
let mut v: SmallVec<[Box<u8>; 8]> = SmallVec::new();
|
||||
|
||||
for x in 0..8 {
|
||||
v.push(Box::new(x));
|
||||
}
|
||||
v.truncate(4);
|
||||
|
||||
assert_eq!(v.len(), 4);
|
||||
assert!(!v.spilled());
|
||||
|
||||
assert_eq!(*v.swap_remove(1), 1);
|
||||
assert_eq!(*v.remove(1), 3);
|
||||
v.insert(1, Box::new(3));
|
||||
|
||||
assert_eq!(&v.iter().map(|v| **v).collect::<Vec<_>>(), &[0, 3, 2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_insert_many() {
|
||||
let mut v: SmallVec<[u8; 8]> = SmallVec::new();
|
||||
for x in 0..4 {
|
||||
v.push(x);
|
||||
}
|
||||
assert_eq!(v.len(), 4);
|
||||
v.insert_many(1, [5, 6].iter().cloned());
|
||||
assert_eq!(
|
||||
&v.iter().map(|v| *v).collect::<Vec<_>>(),
|
||||
&[0, 5, 6, 1, 2, 3]
|
||||
);
|
||||
}
|
||||
|
||||
struct MockHintIter<T: Iterator> {
|
||||
x: T,
|
||||
hint: usize,
|
||||
}
|
||||
impl<T: Iterator> Iterator for MockHintIter<T> {
|
||||
type Item = T::Item;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.x.next()
|
||||
}
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
(self.hint, None)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_insert_many_short_hint() {
|
||||
let mut v: SmallVec<[u8; 8]> = SmallVec::new();
|
||||
for x in 0..4 {
|
||||
v.push(x);
|
||||
}
|
||||
assert_eq!(v.len(), 4);
|
||||
v.insert_many(
|
||||
1,
|
||||
MockHintIter {
|
||||
x: [5, 6].iter().cloned(),
|
||||
hint: 5,
|
||||
},
|
||||
);
|
||||
assert_eq!(
|
||||
&v.iter().map(|v| *v).collect::<Vec<_>>(),
|
||||
&[0, 5, 6, 1, 2, 3]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_insert_many_long_hint() {
|
||||
let mut v: SmallVec<[u8; 8]> = SmallVec::new();
|
||||
for x in 0..4 {
|
||||
v.push(x);
|
||||
}
|
||||
assert_eq!(v.len(), 4);
|
||||
v.insert_many(
|
||||
1,
|
||||
MockHintIter {
|
||||
x: [5, 6].iter().cloned(),
|
||||
hint: 1,
|
||||
},
|
||||
);
|
||||
assert_eq!(
|
||||
&v.iter().map(|v| *v).collect::<Vec<_>>(),
|
||||
&[0, 5, 6, 1, 2, 3]
|
||||
);
|
||||
}
|
||||
|
||||
// https://github.com/servo/rust-smallvec/issues/96
|
||||
mod insert_many_panic {
|
||||
use crate::{smallvec, SmallVec};
|
||||
use alloc::boxed::Box;
|
||||
|
||||
struct PanicOnDoubleDrop {
|
||||
dropped: Box<bool>,
|
||||
}
|
||||
|
||||
impl PanicOnDoubleDrop {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
dropped: Box::new(false),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for PanicOnDoubleDrop {
|
||||
fn drop(&mut self) {
|
||||
assert!(!*self.dropped, "already dropped");
|
||||
*self.dropped = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// Claims to yield `hint` items, but actually yields `count`, then panics.
|
||||
struct BadIter {
|
||||
hint: usize,
|
||||
count: usize,
|
||||
}
|
||||
|
||||
impl Iterator for BadIter {
|
||||
type Item = PanicOnDoubleDrop;
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
(self.hint, None)
|
||||
}
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.count == 0 {
|
||||
panic!()
|
||||
}
|
||||
self.count -= 1;
|
||||
Some(PanicOnDoubleDrop::new())
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn panic_early_at_start() {
|
||||
let mut vec: SmallVec<[PanicOnDoubleDrop; 0]> =
|
||||
smallvec![PanicOnDoubleDrop::new(), PanicOnDoubleDrop::new(),];
|
||||
let result = ::std::panic::catch_unwind(move || {
|
||||
vec.insert_many(0, BadIter { hint: 1, count: 0 });
|
||||
});
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn panic_early_in_middle() {
|
||||
let mut vec: SmallVec<[PanicOnDoubleDrop; 0]> =
|
||||
smallvec![PanicOnDoubleDrop::new(), PanicOnDoubleDrop::new(),];
|
||||
let result = ::std::panic::catch_unwind(move || {
|
||||
vec.insert_many(1, BadIter { hint: 4, count: 2 });
|
||||
});
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn panic_early_at_end() {
|
||||
let mut vec: SmallVec<[PanicOnDoubleDrop; 0]> =
|
||||
smallvec![PanicOnDoubleDrop::new(), PanicOnDoubleDrop::new(),];
|
||||
let result = ::std::panic::catch_unwind(move || {
|
||||
vec.insert_many(2, BadIter { hint: 3, count: 1 });
|
||||
});
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn panic_late_at_start() {
|
||||
let mut vec: SmallVec<[PanicOnDoubleDrop; 0]> =
|
||||
smallvec![PanicOnDoubleDrop::new(), PanicOnDoubleDrop::new(),];
|
||||
let result = ::std::panic::catch_unwind(move || {
|
||||
vec.insert_many(0, BadIter { hint: 3, count: 5 });
|
||||
});
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn panic_late_at_end() {
|
||||
let mut vec: SmallVec<[PanicOnDoubleDrop; 0]> =
|
||||
smallvec![PanicOnDoubleDrop::new(), PanicOnDoubleDrop::new(),];
|
||||
let result = ::std::panic::catch_unwind(move || {
|
||||
vec.insert_many(2, BadIter { hint: 3, count: 5 });
|
||||
});
|
||||
assert!(result.is_err());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_invalid_grow() {
|
||||
let mut v: SmallVec<[u8; 8]> = SmallVec::new();
|
||||
v.extend(0..8);
|
||||
v.grow(5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_insert_from_slice() {
|
||||
let mut v: SmallVec<[u8; 8]> = SmallVec::new();
|
||||
for x in 0..4 {
|
||||
v.push(x);
|
||||
}
|
||||
assert_eq!(v.len(), 4);
|
||||
v.insert_from_slice(1, &[5, 6]);
|
||||
assert_eq!(
|
||||
&v.iter().map(|v| *v).collect::<Vec<_>>(),
|
||||
&[0, 5, 6, 1, 2, 3]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extend_from_slice() {
|
||||
let mut v: SmallVec<[u8; 8]> = SmallVec::new();
|
||||
for x in 0..4 {
|
||||
v.push(x);
|
||||
}
|
||||
assert_eq!(v.len(), 4);
|
||||
v.extend_from_slice(&[5, 6]);
|
||||
assert_eq!(
|
||||
&v.iter().map(|v| *v).collect::<Vec<_>>(),
|
||||
&[0, 1, 2, 3, 5, 6]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_drop_panic_smallvec() {
|
||||
// This test should only panic once, and not double panic,
|
||||
// which would mean a double drop
|
||||
struct DropPanic;
|
||||
|
||||
impl Drop for DropPanic {
|
||||
fn drop(&mut self) {
|
||||
panic!("drop");
|
||||
}
|
||||
}
|
||||
|
||||
let mut v = SmallVec::<[_; 1]>::new();
|
||||
v.push(DropPanic);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eq() {
|
||||
let mut a: SmallVec<[u32; 2]> = SmallVec::new();
|
||||
let mut b: SmallVec<[u32; 2]> = SmallVec::new();
|
||||
let mut c: SmallVec<[u32; 2]> = SmallVec::new();
|
||||
// a = [1, 2]
|
||||
a.push(1);
|
||||
a.push(2);
|
||||
// b = [1, 2]
|
||||
b.push(1);
|
||||
b.push(2);
|
||||
// c = [3, 4]
|
||||
c.push(3);
|
||||
c.push(4);
|
||||
|
||||
assert!(a == b);
|
||||
assert!(a != c);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ord() {
|
||||
let mut a: SmallVec<[u32; 2]> = SmallVec::new();
|
||||
let mut b: SmallVec<[u32; 2]> = SmallVec::new();
|
||||
let mut c: SmallVec<[u32; 2]> = SmallVec::new();
|
||||
// a = [1]
|
||||
a.push(1);
|
||||
// b = [1, 1]
|
||||
b.push(1);
|
||||
b.push(1);
|
||||
// c = [1, 2]
|
||||
c.push(1);
|
||||
c.push(2);
|
||||
|
||||
assert!(a < b);
|
||||
assert!(b > a);
|
||||
assert!(b < c);
|
||||
assert!(c > b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hash() {
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::hash::Hash;
|
||||
|
||||
{
|
||||
let mut a: SmallVec<[u32; 2]> = SmallVec::new();
|
||||
let b = [1, 2];
|
||||
a.extend(b.iter().cloned());
|
||||
let mut hasher = DefaultHasher::new();
|
||||
assert_eq!(a.hash(&mut hasher), b.hash(&mut hasher));
|
||||
}
|
||||
{
|
||||
let mut a: SmallVec<[u32; 2]> = SmallVec::new();
|
||||
let b = [1, 2, 11, 12];
|
||||
a.extend(b.iter().cloned());
|
||||
let mut hasher = DefaultHasher::new();
|
||||
assert_eq!(a.hash(&mut hasher), b.hash(&mut hasher));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_as_ref() {
|
||||
let mut a: SmallVec<[u32; 2]> = SmallVec::new();
|
||||
a.push(1);
|
||||
assert_eq!(a.as_ref(), [1]);
|
||||
a.push(2);
|
||||
assert_eq!(a.as_ref(), [1, 2]);
|
||||
a.push(3);
|
||||
assert_eq!(a.as_ref(), [1, 2, 3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_as_mut() {
|
||||
let mut a: SmallVec<[u32; 2]> = SmallVec::new();
|
||||
a.push(1);
|
||||
assert_eq!(a.as_mut(), [1]);
|
||||
a.push(2);
|
||||
assert_eq!(a.as_mut(), [1, 2]);
|
||||
a.push(3);
|
||||
assert_eq!(a.as_mut(), [1, 2, 3]);
|
||||
a.as_mut()[1] = 4;
|
||||
assert_eq!(a.as_mut(), [1, 4, 3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_borrow() {
|
||||
use std::borrow::Borrow;
|
||||
|
||||
let mut a: SmallVec<[u32; 2]> = SmallVec::new();
|
||||
a.push(1);
|
||||
assert_eq!(a.borrow(), [1]);
|
||||
a.push(2);
|
||||
assert_eq!(a.borrow(), [1, 2]);
|
||||
a.push(3);
|
||||
assert_eq!(a.borrow(), [1, 2, 3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_borrow_mut() {
|
||||
use std::borrow::BorrowMut;
|
||||
|
||||
let mut a: SmallVec<[u32; 2]> = SmallVec::new();
|
||||
a.push(1);
|
||||
assert_eq!(a.borrow_mut(), [1]);
|
||||
a.push(2);
|
||||
assert_eq!(a.borrow_mut(), [1, 2]);
|
||||
a.push(3);
|
||||
assert_eq!(a.borrow_mut(), [1, 2, 3]);
|
||||
BorrowMut::<[u32]>::borrow_mut(&mut a)[1] = 4;
|
||||
assert_eq!(a.borrow_mut(), [1, 4, 3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from() {
|
||||
assert_eq!(&SmallVec::<[u32; 2]>::from(&[1][..])[..], [1]);
|
||||
assert_eq!(&SmallVec::<[u32; 2]>::from(&[1, 2, 3][..])[..], [1, 2, 3]);
|
||||
|
||||
let vec = vec![];
|
||||
let small_vec: SmallVec<[u8; 3]> = SmallVec::from(vec);
|
||||
assert_eq!(&*small_vec, &[]);
|
||||
drop(small_vec);
|
||||
|
||||
let vec = vec![1, 2, 3, 4, 5];
|
||||
let small_vec: SmallVec<[u8; 3]> = SmallVec::from(vec);
|
||||
assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
|
||||
drop(small_vec);
|
||||
|
||||
let vec = vec![1, 2, 3, 4, 5];
|
||||
let small_vec: SmallVec<[u8; 1]> = SmallVec::from(vec);
|
||||
assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
|
||||
drop(small_vec);
|
||||
|
||||
let array = [1];
|
||||
let small_vec: SmallVec<[u8; 1]> = SmallVec::from(array);
|
||||
assert_eq!(&*small_vec, &[1]);
|
||||
drop(small_vec);
|
||||
|
||||
let array = [99; 128];
|
||||
let small_vec: SmallVec<[u8; 128]> = SmallVec::from(array);
|
||||
assert_eq!(&*small_vec, vec![99u8; 128].as_slice());
|
||||
drop(small_vec);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_slice() {
|
||||
assert_eq!(&SmallVec::<[u32; 2]>::from_slice(&[1][..])[..], [1]);
|
||||
assert_eq!(
|
||||
&SmallVec::<[u32; 2]>::from_slice(&[1, 2, 3][..])[..],
|
||||
[1, 2, 3]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_exact_size_iterator() {
|
||||
let mut vec = SmallVec::<[u32; 2]>::from(&[1, 2, 3][..]);
|
||||
assert_eq!(vec.clone().into_iter().len(), 3);
|
||||
assert_eq!(vec.drain(..2).len(), 2);
|
||||
assert_eq!(vec.into_iter().len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_into_iter_as_slice() {
|
||||
let vec = SmallVec::<[u32; 2]>::from(&[1, 2, 3][..]);
|
||||
let mut iter = vec.clone().into_iter();
|
||||
assert_eq!(iter.as_slice(), &[1, 2, 3]);
|
||||
assert_eq!(iter.as_mut_slice(), &[1, 2, 3]);
|
||||
iter.next();
|
||||
assert_eq!(iter.as_slice(), &[2, 3]);
|
||||
assert_eq!(iter.as_mut_slice(), &[2, 3]);
|
||||
iter.next_back();
|
||||
assert_eq!(iter.as_slice(), &[2]);
|
||||
assert_eq!(iter.as_mut_slice(), &[2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_into_iter_clone() {
|
||||
// Test that the cloned iterator yields identical elements and that it owns its own copy
|
||||
// (i.e. no use after move errors).
|
||||
let mut iter = SmallVec::<[u8; 2]>::from_iter(0..3).into_iter();
|
||||
let mut clone_iter = iter.clone();
|
||||
while let Some(x) = iter.next() {
|
||||
assert_eq!(x, clone_iter.next().unwrap());
|
||||
}
|
||||
assert_eq!(clone_iter.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_into_iter_clone_partially_consumed_iterator() {
|
||||
// Test that the cloned iterator only contains the remaining elements of the original iterator.
|
||||
let mut iter = SmallVec::<[u8; 2]>::from_iter(0..3).into_iter().skip(1);
|
||||
let mut clone_iter = iter.clone();
|
||||
while let Some(x) = iter.next() {
|
||||
assert_eq!(x, clone_iter.next().unwrap());
|
||||
}
|
||||
assert_eq!(clone_iter.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_into_iter_clone_empty_smallvec() {
|
||||
let mut iter = SmallVec::<[u8; 2]>::new().into_iter();
|
||||
let mut clone_iter = iter.clone();
|
||||
assert_eq!(iter.next(), None);
|
||||
assert_eq!(clone_iter.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shrink_to_fit_unspill() {
|
||||
let mut vec = SmallVec::<[u8; 2]>::from_iter(0..3);
|
||||
vec.pop();
|
||||
assert!(vec.spilled());
|
||||
vec.shrink_to_fit();
|
||||
assert!(!vec.spilled(), "shrink_to_fit will un-spill if possible");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_into_vec() {
|
||||
let vec = SmallVec::<[u8; 2]>::from_iter(0..2);
|
||||
assert_eq!(vec.into_vec(), vec![0, 1]);
|
||||
|
||||
let vec = SmallVec::<[u8; 2]>::from_iter(0..3);
|
||||
assert_eq!(vec.into_vec(), vec![0, 1, 2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_into_inner() {
|
||||
let vec = SmallVec::<[u8; 2]>::from_iter(0..2);
|
||||
assert_eq!(vec.into_inner(), Ok([0, 1]));
|
||||
|
||||
let vec = SmallVec::<[u8; 2]>::from_iter(0..1);
|
||||
assert_eq!(vec.clone().into_inner(), Err(vec));
|
||||
|
||||
let vec = SmallVec::<[u8; 2]>::from_iter(0..3);
|
||||
assert_eq!(vec.clone().into_inner(), Err(vec));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_vec() {
|
||||
let vec = vec![];
|
||||
let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec);
|
||||
assert_eq!(&*small_vec, &[]);
|
||||
drop(small_vec);
|
||||
|
||||
let vec = vec![];
|
||||
let small_vec: SmallVec<[u8; 1]> = SmallVec::from_vec(vec);
|
||||
assert_eq!(&*small_vec, &[]);
|
||||
drop(small_vec);
|
||||
|
||||
let vec = vec![1];
|
||||
let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec);
|
||||
assert_eq!(&*small_vec, &[1]);
|
||||
drop(small_vec);
|
||||
|
||||
let vec = vec![1, 2, 3];
|
||||
let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec);
|
||||
assert_eq!(&*small_vec, &[1, 2, 3]);
|
||||
drop(small_vec);
|
||||
|
||||
let vec = vec![1, 2, 3, 4, 5];
|
||||
let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec);
|
||||
assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
|
||||
drop(small_vec);
|
||||
|
||||
let vec = vec![1, 2, 3, 4, 5];
|
||||
let small_vec: SmallVec<[u8; 1]> = SmallVec::from_vec(vec);
|
||||
assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
|
||||
drop(small_vec);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_retain() {
|
||||
// Test inline data storate
|
||||
let mut sv: SmallVec<[i32; 5]> = SmallVec::from_slice(&[1, 2, 3, 3, 4]);
|
||||
sv.retain(|&mut i| i != 3);
|
||||
assert_eq!(sv.pop(), Some(4));
|
||||
assert_eq!(sv.pop(), Some(2));
|
||||
assert_eq!(sv.pop(), Some(1));
|
||||
assert_eq!(sv.pop(), None);
|
||||
|
||||
// Test spilled data storage
|
||||
let mut sv: SmallVec<[i32; 3]> = SmallVec::from_slice(&[1, 2, 3, 3, 4]);
|
||||
sv.retain(|&mut i| i != 3);
|
||||
assert_eq!(sv.pop(), Some(4));
|
||||
assert_eq!(sv.pop(), Some(2));
|
||||
assert_eq!(sv.pop(), Some(1));
|
||||
assert_eq!(sv.pop(), None);
|
||||
|
||||
// Test that drop implementations are called for inline.
|
||||
let one = Rc::new(1);
|
||||
let mut sv: SmallVec<[Rc<i32>; 3]> = SmallVec::new();
|
||||
sv.push(Rc::clone(&one));
|
||||
assert_eq!(Rc::strong_count(&one), 2);
|
||||
sv.retain(|_| false);
|
||||
assert_eq!(Rc::strong_count(&one), 1);
|
||||
|
||||
// Test that drop implementations are called for spilled data.
|
||||
let mut sv: SmallVec<[Rc<i32>; 1]> = SmallVec::new();
|
||||
sv.push(Rc::clone(&one));
|
||||
sv.push(Rc::new(2));
|
||||
assert_eq!(Rc::strong_count(&one), 2);
|
||||
sv.retain(|_| false);
|
||||
assert_eq!(Rc::strong_count(&one), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dedup() {
|
||||
let mut dupes: SmallVec<[i32; 5]> = SmallVec::from_slice(&[1, 1, 2, 3, 3]);
|
||||
dupes.dedup();
|
||||
assert_eq!(&*dupes, &[1, 2, 3]);
|
||||
|
||||
let mut empty: SmallVec<[i32; 5]> = SmallVec::new();
|
||||
empty.dedup();
|
||||
assert!(empty.is_empty());
|
||||
|
||||
let mut all_ones: SmallVec<[i32; 5]> = SmallVec::from_slice(&[1, 1, 1, 1, 1]);
|
||||
all_ones.dedup();
|
||||
assert_eq!(all_ones.len(), 1);
|
||||
|
||||
let mut no_dupes: SmallVec<[i32; 5]> = SmallVec::from_slice(&[1, 2, 3, 4, 5]);
|
||||
no_dupes.dedup();
|
||||
assert_eq!(no_dupes.len(), 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_resize() {
|
||||
let mut v: SmallVec<[i32; 8]> = SmallVec::new();
|
||||
v.push(1);
|
||||
v.resize(5, 0);
|
||||
assert_eq!(v[..], [1, 0, 0, 0, 0][..]);
|
||||
|
||||
v.resize(2, -1);
|
||||
assert_eq!(v[..], [1, 0][..]);
|
||||
}
|
||||
|
||||
#[cfg(feature = "write")]
|
||||
#[test]
|
||||
fn test_write() {
|
||||
use std::io::Write;
|
||||
|
||||
let data = [1, 2, 3, 4, 5];
|
||||
|
||||
let mut small_vec: SmallVec<[u8; 2]> = SmallVec::new();
|
||||
let len = small_vec.write(&data[..]).unwrap();
|
||||
assert_eq!(len, 5);
|
||||
assert_eq!(small_vec.as_ref(), data.as_ref());
|
||||
|
||||
let mut small_vec: SmallVec<[u8; 2]> = SmallVec::new();
|
||||
small_vec.write_all(&data[..]).unwrap();
|
||||
assert_eq!(small_vec.as_ref(), data.as_ref());
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
extern crate bincode;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn test_serde() {
|
||||
use self::bincode::{config, deserialize};
|
||||
let mut small_vec: SmallVec<[i32; 2]> = SmallVec::new();
|
||||
small_vec.push(1);
|
||||
let encoded = config().limit(100).serialize(&small_vec).unwrap();
|
||||
let decoded: SmallVec<[i32; 2]> = deserialize(&encoded).unwrap();
|
||||
assert_eq!(small_vec, decoded);
|
||||
small_vec.push(2);
|
||||
// Spill the vec
|
||||
small_vec.push(3);
|
||||
small_vec.push(4);
|
||||
// Check again after spilling.
|
||||
let encoded = config().limit(100).serialize(&small_vec).unwrap();
|
||||
let decoded: SmallVec<[i32; 2]> = deserialize(&encoded).unwrap();
|
||||
assert_eq!(small_vec, decoded);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grow_to_shrink() {
|
||||
let mut v: SmallVec<[u8; 2]> = SmallVec::new();
|
||||
v.push(1);
|
||||
v.push(2);
|
||||
v.push(3);
|
||||
assert!(v.spilled());
|
||||
v.clear();
|
||||
// Shrink to inline.
|
||||
v.grow(2);
|
||||
assert!(!v.spilled());
|
||||
assert_eq!(v.capacity(), 2);
|
||||
assert_eq!(v.len(), 0);
|
||||
v.push(4);
|
||||
assert_eq!(v[..], [4]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resumable_extend() {
|
||||
let s = "a b c";
|
||||
// This iterator yields: (Some('a'), None, Some('b'), None, Some('c')), None
|
||||
let it = s
|
||||
.chars()
|
||||
.scan(0, |_, ch| if ch.is_whitespace() { None } else { Some(ch) });
|
||||
let mut v: SmallVec<[char; 4]> = SmallVec::new();
|
||||
v.extend(it);
|
||||
assert_eq!(v[..], ['a']);
|
||||
}
|
||||
|
||||
// #139
|
||||
#[test]
|
||||
fn uninhabited() {
|
||||
enum Void {}
|
||||
let _sv = SmallVec::<[Void; 8]>::new();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grow_spilled_same_size() {
|
||||
let mut v: SmallVec<[u8; 2]> = SmallVec::new();
|
||||
v.push(0);
|
||||
v.push(1);
|
||||
v.push(2);
|
||||
assert!(v.spilled());
|
||||
assert_eq!(v.capacity(), 4);
|
||||
// grow with the same capacity
|
||||
v.grow(4);
|
||||
assert_eq!(v.capacity(), 4);
|
||||
assert_eq!(v[..], [0, 1, 2]);
|
||||
}
|
||||
|
||||
#[cfg(feature = "const_generics")]
|
||||
#[test]
|
||||
fn const_generics() {
|
||||
let _v = SmallVec::<[i32; 987]>::default();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_macro() {
|
||||
let _v: SmallVec<[u8; 1]> = smallvec![];
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zero_size_items() {
|
||||
SmallVec::<[(); 0]>::new().push(());
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/// This file tests `smallvec!` without actually having the macro in scope.
|
||||
/// This forces any recursion to use a `$crate` prefix to reliably find itself.
|
||||
|
||||
#[test]
|
||||
fn smallvec() {
|
||||
let mut vec: smallvec::SmallVec<[i32; 2]>;
|
||||
|
||||
macro_rules! check {
|
||||
($init:tt) => {
|
||||
vec = smallvec::smallvec! $init;
|
||||
assert_eq!(*vec, *vec! $init);
|
||||
}
|
||||
}
|
||||
|
||||
check!([0; 0]);
|
||||
check!([1; 1]);
|
||||
check!([2; 2]);
|
||||
check!([3; 3]);
|
||||
|
||||
check!([]);
|
||||
check!([1]);
|
||||
check!([1, 2]);
|
||||
check!([1, 2, 3]);
|
||||
}
|
Загрузка…
Ссылка в новой задаче