Skip to content

Commit f0d1c23

Browse files
stepanchegfacebook-github-bot
authored andcommitted
Dummy Vec2
Summary: `Vec` of pairs. This is refactoring to make the top diff smaller, see D40557486. Reviewed By: ndmitchell Differential Revision: D40647761 fbshipit-source-id: a9ded969e96c61d2b5b94e27c6b586b0e6dc126a
1 parent 968e247 commit f0d1c23

File tree

3 files changed

+252
-0
lines changed

3 files changed

+252
-0
lines changed

starlark_map/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pub mod small_map;
3131
pub mod small_set;
3232
// TODO(nga): make private.
3333
mod iter;
34+
pub(crate) mod vec2;
3435
pub(crate) mod vec_map;
3536

3637
pub use equivalent::Equivalent;

starlark_map/src/vec2/iter.rs

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* Copyright 2019 The Starlark in Rust Authors.
3+
* Copyright (c) Facebook, Inc. and its affiliates.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* https://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
use std::slice;
19+
20+
use gazebo::prelude::*;
21+
22+
#[derive(Clone_)]
23+
pub(crate) struct Iter<'a, K, V> {
24+
pub(crate) keys: slice::Iter<'a, K>,
25+
pub(crate) values: slice::Iter<'a, V>,
26+
}
27+
28+
impl<'a, K, V> Iterator for Iter<'a, K, V> {
29+
type Item = (&'a K, &'a V);
30+
31+
fn next(&mut self) -> Option<Self::Item> {
32+
match (self.keys.next(), self.values.next()) {
33+
(Some(k), Some(v)) => Some((k, v)),
34+
_ => None,
35+
}
36+
}
37+
38+
fn size_hint(&self) -> (usize, Option<usize>) {
39+
self.keys.size_hint()
40+
}
41+
}
42+
43+
impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
44+
fn len(&self) -> usize {
45+
self.keys.len()
46+
}
47+
}
48+
49+
impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V> {
50+
fn next_back(&mut self) -> Option<Self::Item> {
51+
match (self.keys.next_back(), self.values.next_back()) {
52+
(Some(k), Some(v)) => Some((k, v)),
53+
_ => None,
54+
}
55+
}
56+
}
57+
58+
pub(crate) struct IntoIter<K, V> {
59+
pub(crate) keys: std::vec::IntoIter<K>,
60+
pub(crate) values: std::vec::IntoIter<V>,
61+
}
62+
63+
impl<K, V> Iterator for IntoIter<K, V> {
64+
type Item = (K, V);
65+
66+
fn next(&mut self) -> Option<Self::Item> {
67+
match (self.keys.next(), self.values.next()) {
68+
(Some(k), Some(v)) => Some((k, v)),
69+
_ => None,
70+
}
71+
}
72+
73+
fn size_hint(&self) -> (usize, Option<usize>) {
74+
self.keys.size_hint()
75+
}
76+
}
77+
78+
impl<K, V> ExactSizeIterator for IntoIter<K, V> {
79+
fn len(&self) -> usize {
80+
self.keys.len()
81+
}
82+
}
83+
84+
impl<K, V> DoubleEndedIterator for IntoIter<K, V> {
85+
fn next_back(&mut self) -> Option<Self::Item> {
86+
match (self.keys.next_back(), self.values.next_back()) {
87+
(Some(k), Some(v)) => Some((k, v)),
88+
_ => None,
89+
}
90+
}
91+
}

starlark_map/src/vec2/mod.rs

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
/*
2+
* Copyright 2019 The Starlark in Rust Authors.
3+
* Copyright (c) Facebook, Inc. and its affiliates.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* https://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#![allow(dead_code)] // TODO(nga): used in the following diff.
19+
20+
use std::cmp::Ordering;
21+
use std::mem;
22+
23+
use allocative::Allocative;
24+
use gazebo::prelude::*;
25+
26+
pub(crate) mod iter;
27+
28+
/// Array of pairs (K, V), where K and V are stored separately.
29+
/// This reduces memory consumption when K and V have different alignments.
30+
#[derive(Debug, Clone, PartialEq, Eq, Default_, Hash, Allocative)]
31+
pub(crate) struct Vec2<K, V> {
32+
// `keys` and `values` are always the same length.
33+
keys: Vec<K>,
34+
values: Vec<V>,
35+
}
36+
37+
impl<K, V> Vec2<K, V> {
38+
pub(crate) const fn new() -> Vec2<K, V> {
39+
Vec2 {
40+
keys: Vec::new(),
41+
values: Vec::new(),
42+
}
43+
}
44+
45+
pub(crate) fn with_capacity(capacity: usize) -> Vec2<K, V> {
46+
Vec2 {
47+
keys: Vec::with_capacity(capacity),
48+
values: Vec::with_capacity(capacity),
49+
}
50+
}
51+
52+
pub(crate) fn len(&self) -> usize {
53+
self.keys.len()
54+
}
55+
56+
pub(crate) fn is_empty(&self) -> bool {
57+
self.keys.is_empty()
58+
}
59+
60+
pub(crate) fn capacity(&self) -> usize {
61+
self.keys.capacity()
62+
}
63+
64+
pub(crate) fn reserve(&mut self, additional: usize) {
65+
self.keys.reserve(additional);
66+
self.values.reserve(additional);
67+
}
68+
69+
pub(crate) fn get(&self, index: usize) -> Option<(&K, &V)> {
70+
Some((self.keys.get(index)?, self.values.get(index)?))
71+
}
72+
73+
pub(crate) unsafe fn get_unchecked(&self, index: usize) -> (&K, &V) {
74+
(
75+
self.keys.get_unchecked(index),
76+
self.values.get_unchecked(index),
77+
)
78+
}
79+
80+
pub(crate) unsafe fn get_unchecked_mut(&mut self, index: usize) -> (&mut K, &mut V) {
81+
(
82+
self.keys.get_unchecked_mut(index),
83+
self.values.get_unchecked_mut(index),
84+
)
85+
}
86+
87+
pub(crate) fn push(&mut self, key: K, value: V) {
88+
self.keys.push(key);
89+
self.values.push(value);
90+
}
91+
92+
pub(crate) fn remove(&mut self, index: usize) -> (K, V) {
93+
(self.keys.remove(index), self.values.remove(index))
94+
}
95+
96+
pub(crate) fn clear(&mut self) {
97+
self.keys.clear();
98+
self.values.clear();
99+
}
100+
101+
pub(crate) fn pop(&mut self) -> Option<(K, V)> {
102+
let key = self.keys.pop()?;
103+
let value = self.values.pop()?;
104+
Some((key, value))
105+
}
106+
107+
pub(crate) fn iter(&self) -> iter::Iter<'_, K, V> {
108+
iter::Iter {
109+
keys: self.keys.iter(),
110+
values: self.values.iter(),
111+
}
112+
}
113+
114+
pub(crate) fn into_iter(self) -> iter::IntoIter<K, V> {
115+
iter::IntoIter {
116+
keys: self.keys.into_iter(),
117+
values: self.values.into_iter(),
118+
}
119+
}
120+
121+
pub(crate) fn keys(&self) -> &[K] {
122+
&self.keys
123+
}
124+
125+
pub(crate) fn keys_mut(&mut self) -> &mut [K] {
126+
&mut self.keys
127+
}
128+
129+
pub(crate) fn values(&self) -> &[V] {
130+
&self.values
131+
}
132+
133+
pub(crate) fn sort_by<F>(&mut self, mut compare: F)
134+
where
135+
F: FnMut((&K, &V), (&K, &V)) -> Ordering,
136+
{
137+
// TODO: sort without allocation.
138+
// TODO: drain.
139+
let mut entries: Vec<(K, V)> = mem::take(self).into_iter().collect();
140+
entries.sort_by(|(ak, av), (bk, bv)| compare((ak, av), (bk, bv)));
141+
for (k, v) in entries {
142+
self.push(k, v);
143+
}
144+
}
145+
}
146+
147+
impl<'a, K, V> IntoIterator for &'a Vec2<K, V> {
148+
type Item = (&'a K, &'a V);
149+
type IntoIter = iter::Iter<'a, K, V>;
150+
151+
fn into_iter(self) -> Self::IntoIter {
152+
self.iter()
153+
}
154+
}
155+
156+
#[cfg(test)]
157+
mod tests {
158+
#[test]
159+
fn test() {}
160+
}

0 commit comments

Comments
 (0)