5个不稳定版本

0.2.1 2019年4月25日
0.2.0 2019年4月23日
0.1.1 2019年4月15日
0.0.2 2019年4月15日
0.0.1 2019年4月15日

#452 in 内存管理

CC0许可

25KB
369

vecshard

在O(1)时间内分割Vec。

Crates.io Build Status Coverage Status License: CC0-1.0

您可以使用VecVec::split_off方法将其分割成两个,但由于大多数分配器不能直接分割分配,这需要为第二个Vec分配空间,甚至更糟糕的是,需要复制相关元素,这需要O(n)时间。您还可以使用Vec::split_atVec::split_at_mut将其分割成切片,但这不会给您提供可以随意移动或移出数据的所有权数据。

此crate提供了一种将Vec分割成两个类似Vec的VecShard的方法,这两个方法在常数时间内运行。但要注意的是,VecShard使用引用计数来确定最后一个被丢弃。只有当最后一个被丢弃时,原始Vec的内存才会被释放。然而,碎片中的单个项目在碎片被丢弃时就会丢弃。

此功能通过为Vec提供的扩展特质ShardExt来实现。

文档

请参阅docs.rs上的API文档

基本示例

use vecshard::ShardExt;

let animals = vec!["penguin", "owl", "toucan", "turtle", "spider", "mosquitto"];

// split the vec into 2 shards
let (cool_animals, uncool_animals) = animals.split_inplace_at(4);

// shards can be indexed as usual
assert_eq!(cool_animals[3], "turtle");
assert_eq!(uncool_animals[0], "spider");

// ..including with a range as index
assert_eq!(cool_animals[1..3], ["owl", "toucan"]);

// they deref into slices, so you can use them as such:
assert_eq!(cool_animals.len(), 4);
assert!(uncool_animals.ends_with(&["mosquitto"]));

// shards can also be split up again:
let (cool_birds, cool_reptiles) = cool_animals.split_inplace_at(3);
assert_eq!(*cool_birds, ["penguin", "owl", "toucan"]);
assert_eq!(*cool_reptiles, ["turtle"]);

转换

碎片可以自由地从FromInto转换成Vec。请注意,后者可能需要分配,如果还有其他碎片也使用碎片分配。


let vec = vec![1, 2, 3];
let shard = VecShard::from(vec);
let vec2 : Vec<_> = shard.into();

迭代

要遍历一个VecShard,你有几种选择。VecShard<T>自身就是一个可以排空的Iterator,并返回拥有实例,从其存储中删除它们。如果你只需要的引用或mut引用,你可以将其解引用为一个切片,并遍历该切片。最后,如果你需要一个拥有Iterator但不想排空碎片,你可以克隆碎片并遍历它。

let mut shard = VecShard::from(vec!['y', 'e', 'e', 't']);

assert_eq!(Some('y'), shard.next());
assert_eq!(Some('e'), shard.next());

assert_eq!(*shard, ['e', 't']);

可选功能

默认情况下,此crate没有依赖,但如果你想要序列化和反序列化VecShard,你可以像这样启用serde功能

[dependencies.vecshard]
optional = true
version = "0.2.1"

依赖

~170KB