Skip to content

Commit 920015e

Browse files
stepanchegfacebook-github-bot
authored andcommitted
Avoid copying set when arguments of operations like intersection are already a set
Reviewed By: perehonchuk Differential Revision: D63739933 fbshipit-source-id: eba5481f5a23d9136d90992225e776788def1fa2
1 parent 8990347 commit 920015e

File tree

1 file changed

+12
-9
lines changed

1 file changed

+12
-9
lines changed

starlark/src/values/types/set/methods.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,34 +32,42 @@ use crate::values::set::refs::SetRef;
3232
use crate::values::set::value::SetData;
3333
use crate::values::typing::StarlarkIter;
3434
use crate::values::Heap;
35+
use crate::values::UnpackValue;
3536
use crate::values::Value;
3637
use crate::values::ValueOfUnchecked;
3738

3839
enum SetFromValue<'v> {
3940
Set(SmallSet<Value<'v>>),
41+
Ref(SetRef<'v>),
4042
}
4143

4244
impl<'v> SetFromValue<'v> {
4345
fn from_value(
4446
value: ValueOfUnchecked<'v, StarlarkIter<Value<'v>>>,
4547
heap: &'v Heap,
4648
) -> crate::Result<Self> {
47-
let mut set = SmallSet::default();
48-
for elem in value.get().iterate(heap)? {
49-
set.insert_hashed(elem.get_hashed()?);
49+
if let Some(v) = SetRef::unpack_value_opt(value.get()) {
50+
Ok(SetFromValue::Ref(v))
51+
} else {
52+
let mut set = SmallSet::default();
53+
for elem in value.get().iterate(heap)? {
54+
set.insert_hashed(elem.get_hashed()?);
55+
}
56+
Ok(SetFromValue::Set(set))
5057
}
51-
Ok(SetFromValue::Set(set))
5258
}
5359

5460
fn get(&self) -> &SmallSet<Value<'v>> {
5561
match self {
5662
SetFromValue::Set(set) => set,
63+
SetFromValue::Ref(set) => &set.aref.content,
5764
}
5865
}
5966

6067
fn into_set(self) -> SmallSet<Value<'v>> {
6168
match self {
6269
SetFromValue::Set(set) => set,
70+
SetFromValue::Ref(set) => set.aref.content.clone(),
6371
}
6472
}
6573

@@ -118,7 +126,6 @@ pub(crate) fn set_methods(builder: &mut MethodsBuilder) {
118126
#[starlark(require=pos)] other: ValueOfUnchecked<'v, StarlarkIter<Value<'v>>>,
119127
heap: &'v Heap,
120128
) -> starlark::Result<SetData<'v>> {
121-
//TODO(romanp) check if other is set
122129
let other_set = SetFromValue::from_value(other, heap)?;
123130
let mut data = SetData::default();
124131
if other_set.is_empty() {
@@ -146,7 +153,6 @@ pub(crate) fn set_methods(builder: &mut MethodsBuilder) {
146153
#[starlark(require=pos)] other: ValueOfUnchecked<'v, StarlarkIter<Value<'v>>>,
147154
heap: &'v Heap,
148155
) -> starlark::Result<SetData<'v>> {
149-
//TODO(romanp) check if other is set
150156
let other_set = SetFromValue::from_value(other, heap)?;
151157

152158
if other_set.is_empty() {
@@ -307,8 +313,6 @@ pub(crate) fn set_methods(builder: &mut MethodsBuilder) {
307313
#[starlark(require=pos)] other: ValueOfUnchecked<'v, StarlarkIter<Value<'v>>>,
308314
heap: &'v Heap,
309315
) -> starlark::Result<SetData<'v>> {
310-
//TODO(romanp) check if other is set
311-
312316
if this.aref.content.is_empty() {
313317
other.get().iterate(heap)?;
314318
return Ok(SetData::default());
@@ -372,7 +376,6 @@ pub(crate) fn set_methods(builder: &mut MethodsBuilder) {
372376
other.get().iterate(heap)?;
373377
return Ok(true);
374378
}
375-
//TODO(romanp): check if other is already a set
376379
let rhs = SetFromValue::from_value(other, heap)?;
377380
if rhs.is_empty() {
378381
return Ok(false);

0 commit comments

Comments
 (0)