Skip to content

Commit 7d62fc7

Browse files
committed
Replace KeyValuePairs' internal BTreeSet with BTreeMap
Fixes #887
1 parent daf9908 commit 7d62fc7

File tree

3 files changed

+41
-26
lines changed

3 files changed

+41
-26
lines changed

crates/stackable-operator/src/kvp/annotation/mod.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -293,15 +293,14 @@ impl Annotations {
293293
pub fn contains_key(&self, key: impl TryInto<Key>) -> bool;
294294

295295
/// Returns an [`Iterator`] over [`Annotations`] yielding a reference to every [`Annotation`] contained within.
296-
pub fn iter(&self) -> impl Iterator<Item = &KeyValuePair<AnnotationValue>>;
297-
296+
pub fn iter(&self) -> impl Iterator<Item = KeyValuePair<AnnotationValue>> + '_;
298297
}
299298
}
300299
}
301300

302301
impl IntoIterator for Annotations {
303302
type Item = KeyValuePair<AnnotationValue>;
304-
type IntoIter = std::collections::btree_set::IntoIter<Self::Item>;
303+
type IntoIter = <KeyValuePairs<AnnotationValue> as IntoIterator>::IntoIter;
305304

306305
/// Returns a consuming [`Iterator`] over [`Annotations`] moving every [`Annotation`] out.
307306
/// The [`Annotations`] cannot be used again after calling this.

crates/stackable-operator/src/kvp/label/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -385,15 +385,15 @@ impl Labels {
385385
pub fn contains_key(&self, key: impl TryInto<Key>) -> bool;
386386

387387
/// Returns an [`Iterator`] over [`Labels`] yielding a reference to every [`Label`] contained within.
388-
pub fn iter(&self) -> impl Iterator<Item = &KeyValuePair<LabelValue>>;
388+
pub fn iter(&self) -> impl Iterator<Item = KeyValuePair<LabelValue>> + '_;
389389

390390
}
391391
}
392392
}
393393

394394
impl IntoIterator for Labels {
395395
type Item = KeyValuePair<LabelValue>;
396-
type IntoIter = std::collections::btree_set::IntoIter<Self::Item>;
396+
type IntoIter = <KeyValuePairs<LabelValue> as IntoIterator>::IntoIter;
397397

398398
/// Returns a consuming [`Iterator`] over [`Labels`] moving every [`Label`] out.
399399
/// The [`Labels`] cannot be used again after calling this.

crates/stackable-operator/src/kvp/mod.rs

+37-21
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ pub enum KeyValuePairsError {
178178
/// which ultimately prevent unncessary reconciliations due to changes
179179
/// in item order.
180180
#[derive(Clone, Debug, Default)]
181-
pub struct KeyValuePairs<T: Value>(BTreeSet<KeyValuePair<T>>);
181+
pub struct KeyValuePairs<T: Value>(BTreeMap<Key, T>);
182182

183183
impl<K, V, T> TryFrom<BTreeMap<K, V>> for KeyValuePairs<T>
184184
where
@@ -224,7 +224,7 @@ where
224224
T: Value,
225225
{
226226
fn from_iter<I: IntoIterator<Item = KeyValuePair<T>>>(iter: I) -> Self {
227-
Self(iter.into_iter().collect())
227+
Self(iter.into_iter().map(|kvp| (kvp.key, kvp.value)).collect())
228228
}
229229
}
230230

@@ -242,7 +242,7 @@ where
242242
.map(KeyValuePair::try_from)
243243
.collect::<Result<BTreeSet<_>, KeyValuePairError<T::Error>>>()?;
244244

245-
Ok(Self(pairs))
245+
Ok(Self::from_iter(pairs))
246246
}
247247
}
248248

@@ -253,7 +253,7 @@ where
253253
fn from(value: KeyValuePairs<T>) -> Self {
254254
value
255255
.iter()
256-
.map(|pair| (pair.key().to_string(), pair.value().to_string()))
256+
.map(|(k, v)| (k.to_string(), v.to_string()))
257257
.collect()
258258
}
259259
}
@@ -262,7 +262,7 @@ impl<T> Deref for KeyValuePairs<T>
262262
where
263263
T: Value,
264264
{
265-
type Target = BTreeSet<KeyValuePair<T>>;
265+
type Target = BTreeMap<Key, T>;
266266

267267
fn deref(&self) -> &Self::Target {
268268
&self.0
@@ -280,7 +280,7 @@ where
280280

281281
/// Creates a new list of [`KeyValuePair`]s from `pairs`.
282282
pub fn new_with(pairs: BTreeSet<KeyValuePair<T>>) -> Self {
283-
Self(pairs)
283+
Self::from_iter(pairs)
284284
}
285285

286286
/// Extends `self` with `other`.
@@ -295,16 +295,16 @@ where
295295
/// [`KeyValuePairs::contains_key`] before inserting or try to insert
296296
/// fallible via [`KeyValuePairs::try_insert`].
297297
pub fn insert(&mut self, kvp: KeyValuePair<T>) -> &mut Self {
298-
self.0.insert(kvp);
298+
self.0.insert(kvp.key, kvp.value);
299299
self
300300
}
301301

302302
/// Tries to insert a new [`KeyValuePair`] into the list of pairs.
303303
///
304-
/// If the list already had this pair present, nothing is updated, and an
304+
/// If the list already had this key present, nothing is updated, and an
305305
/// error is returned.
306306
pub fn try_insert(&mut self, kvp: KeyValuePair<T>) -> Result<(), KeyValuePairsError> {
307-
ensure!(!self.0.contains(&kvp), PairAlreadyExistsSnafu);
307+
ensure!(!self.0.contains_key(&kvp.key), PairAlreadyExistsSnafu);
308308
self.insert(kvp);
309309
Ok(())
310310
}
@@ -314,7 +314,10 @@ where
314314
let Ok(kvp) = kvp.try_into() else {
315315
return false;
316316
};
317-
self.0.contains(&kvp)
317+
let Some(value) = self.get(&kvp.key) else {
318+
return false;
319+
};
320+
value == &kvp.value
318321
}
319322

320323
/// Returns if the list contains a key/value pair with a specific [`Key`].
@@ -323,18 +326,15 @@ where
323326
return false;
324327
};
325328

326-
for kvp in &self.0 {
327-
if kvp.key == key {
328-
return true;
329-
}
330-
}
331-
332-
false
329+
self.0.contains_key(&key)
333330
}
334331

335332
/// Returns an [`Iterator`] over [`KeyValuePairs`] yielding a reference to every [`KeyValuePair`] contained within.
336-
pub fn iter(&self) -> impl Iterator<Item = &KeyValuePair<T>> {
337-
self.0.iter()
333+
pub fn iter(&self) -> impl Iterator<Item = KeyValuePair<T>> + '_ {
334+
self.0.iter().map(|(k, v)| KeyValuePair {
335+
key: k.clone(),
336+
value: v.clone(),
337+
})
338338
}
339339
}
340340

@@ -343,12 +343,15 @@ where
343343
T: Value,
344344
{
345345
type Item = KeyValuePair<T>;
346-
type IntoIter = std::collections::btree_set::IntoIter<Self::Item>;
346+
type IntoIter =
347+
std::iter::Map<std::collections::btree_map::IntoIter<Key, T>, fn((Key, T)) -> Self::Item>;
347348

348349
/// Returns a consuming [`Iterator`] over [`KeyValuePairs`] moving every [`KeyValuePair`] out.
349350
/// The [`KeyValuePairs`] cannot be used again after calling this.
350351
fn into_iter(self) -> Self::IntoIter {
351-
self.0.into_iter()
352+
self.0
353+
.into_iter()
354+
.map(|(key, value)| KeyValuePair { key, value })
352355
}
353356
}
354357

@@ -488,4 +491,17 @@ mod test {
488491
let report = Report::from_error(err);
489492
println!("{report}")
490493
}
494+
495+
#[test]
496+
fn merge() {
497+
let mut merged_labels =
498+
Labels::try_from_iter([("a", "b"), ("b", "a"), ("c", "c")]).unwrap();
499+
merged_labels.extend(Labels::try_from_iter([("a", "a"), ("b", "b"), ("d", "d")]).unwrap());
500+
assert_eq!(
501+
BTreeMap::from(merged_labels),
502+
BTreeMap::from(
503+
Labels::try_from_iter([("a", "a"), ("b", "b"), ("c", "c"), ("d", "d")]).unwrap()
504+
)
505+
)
506+
}
491507
}

0 commit comments

Comments
 (0)