Skip to content

Commit d0dcd9f

Browse files
authored
Remove unused code from ImpactedBlocks (#1668)
There are a bunch of functions in `ImpactedBlocks` which are only used in unit tests for those functions. This PR removes those functions and unit tests. In addition, it updates an old comment (we haven't had a hashmap in `ImpactedBlocks` since #591).
1 parent 1a0a260 commit d0dcd9f

File tree

1 file changed

+4
-328
lines changed

1 file changed

+4
-328
lines changed

common/src/impacted_blocks.rs

+4-328
Original file line numberDiff line numberDiff line change
@@ -165,52 +165,10 @@ impl ImpactedBlocks {
165165
ImpactedBlocks::InclusiveRange(first_impacted, last_impacted)
166166
}
167167

168-
pub fn intersection(&self, other: &ImpactedBlocks) -> ImpactedBlocks {
169-
let ImpactedBlocks::InclusiveRange(fst_self, lst_self) = self else {
170-
return ImpactedBlocks::Empty;
171-
};
172-
173-
let ImpactedBlocks::InclusiveRange(fst_other, lst_other) = other else {
174-
return ImpactedBlocks::Empty;
175-
};
176-
177-
let fst = fst_self.max(fst_other);
178-
let lst = lst_self.min(lst_other);
179-
if lst >= fst {
180-
ImpactedBlocks::InclusiveRange(*fst, *lst)
181-
} else {
182-
ImpactedBlocks::Empty
183-
}
184-
}
185-
186-
pub fn union(&self, other: &ImpactedBlocks) -> ImpactedBlocks {
187-
let ImpactedBlocks::InclusiveRange(fst_self, lst_self) = self else {
188-
return *other;
189-
};
190-
191-
let ImpactedBlocks::InclusiveRange(fst_other, lst_other) = other else {
192-
return *self;
193-
};
194-
let fst = fst_self.min(fst_other);
195-
let lst = lst_self.max(lst_other);
196-
ImpactedBlocks::InclusiveRange(*fst, *lst)
197-
}
198-
199168
pub fn is_empty(&self) -> bool {
200169
self == &ImpactedBlocks::Empty
201170
}
202171

203-
/// Return true if this list of impacted blocks overlaps with another.
204-
pub fn conflicts(&self, other: &ImpactedBlocks) -> bool {
205-
!self.intersection(other).is_empty()
206-
}
207-
208-
pub fn fully_contains(&self, other: &ImpactedBlocks) -> bool {
209-
!self.is_empty()
210-
&& !other.is_empty()
211-
&& self.intersection(other) == *other
212-
}
213-
214172
/// Return a range of impacted extents
215173
pub fn extents(&self) -> Option<RangeInclusive<u32>> {
216174
match self {
@@ -240,8 +198,8 @@ impl ImpactedBlocks {
240198
}
241199
}
242200

243-
/// Given a global offset and number of blocks, compute a list of individually
244-
/// impacted blocks:
201+
/// Given a global offset and number of blocks, compute a range of impacted
202+
/// blocks:
245203
///
246204
/// |eid0 |eid1
247205
/// |───────────────────────────────────────────────│
@@ -255,14 +213,8 @@ impl ImpactedBlocks {
255213
/// The example offset and length above spans 7 blocks over two extents (where
256214
/// the numbers at the bottom of the diagram are block numbers).
257215
///
258-
/// Return an ImpactedBlocks object that stores which extents are impacted,
259-
/// along with the specific blocks in those extents. For the above example, the
260-
/// hashmap inside ImpactedBlocks would be:
261-
///
262-
/// blocks = {
263-
/// eid0 -> [2, 3, 4, 5],
264-
/// eid1 -> [0, 1, 2],
265-
/// }
216+
/// Return an ImpactedBlocks object that stores the affected region as a range
217+
/// of [`ImpactedAddr`] values (which are `(ExtentId, BlockOffset)` tuples)
266218
pub fn extent_from_offset(
267219
ddef: &RegionDefinition,
268220
offset: BlockIndex,
@@ -778,37 +730,10 @@ mod test {
778730
)
779731
}
780732

781-
/// Map the ImpactedBlocks to the full range of possible values
782-
fn reify_impacted_blocks_without_region(
783-
test_iblocks: ArbitraryImpactedBlocks,
784-
) -> ImpactedBlocks {
785-
reify_impacted_blocks(test_iblocks, u32::MAX, usize::MAX)
786-
}
787-
788733
fn region_def_strategy() -> impl Strategy<Value = RegionDefinition> {
789734
any::<ArbitraryRegionDefinition>().prop_map(reify_region_definition)
790735
}
791736

792-
/// Generate a random region definition, and a pair of ImpactedBlocks ranges
793-
/// that fit within it
794-
fn region_and_impacted_pair_strategy(
795-
) -> impl Strategy<Value = (RegionDefinition, ImpactedBlocks, ImpactedBlocks)>
796-
{
797-
any::<(
798-
ArbitraryRegionDefinition,
799-
ArbitraryImpactedBlocks,
800-
ArbitraryImpactedBlocks,
801-
)>()
802-
.prop_map(|(test_ddef, test_iblocks_a, test_iblocks_b)| {
803-
let ddef = reify_region_definition(test_ddef);
804-
let iblocks_a =
805-
reify_impacted_blocks_in_region(test_iblocks_a, &ddef);
806-
let iblocks_b =
807-
reify_impacted_blocks_in_region(test_iblocks_b, &ddef);
808-
(ddef, iblocks_a, iblocks_b)
809-
})
810-
}
811-
812737
/// Generate a random region definition, and a single ImpactedBlocks range
813738
/// within it.
814739
fn region_and_impacted_blocks_strategy(
@@ -823,126 +748,6 @@ mod test {
823748
)
824749
}
825750

826-
fn any_impacted_blocks_strategy() -> impl Strategy<Value = ImpactedBlocks> {
827-
any::<ArbitraryImpactedBlocks>()
828-
.prop_map(reify_impacted_blocks_without_region)
829-
}
830-
831-
#[proptest]
832-
fn intersection_produces_less_than_or_equal_block_count(
833-
#[strategy(region_and_impacted_pair_strategy())]
834-
region_and_impacted_pair: (
835-
RegionDefinition,
836-
ImpactedBlocks,
837-
ImpactedBlocks,
838-
),
839-
) {
840-
let (ddef, iblocks_a, iblocks_b) = region_and_impacted_pair;
841-
let intersection = iblocks_a.intersection(&iblocks_b);
842-
843-
let len_a = iblocks_a.len(&ddef);
844-
let len_b = iblocks_b.len(&ddef);
845-
let len_intersection = intersection.len(&ddef);
846-
847-
prop_assert!(len_intersection <= len_a);
848-
prop_assert!(len_intersection <= len_b);
849-
}
850-
851-
#[proptest]
852-
fn union_produces_greater_than_or_equal_block_count(
853-
#[strategy(region_and_impacted_pair_strategy())]
854-
region_and_impacted_pair: (
855-
RegionDefinition,
856-
ImpactedBlocks,
857-
ImpactedBlocks,
858-
),
859-
) {
860-
let (ddef, iblocks_a, iblocks_b) = region_and_impacted_pair;
861-
let union = iblocks_a.union(&iblocks_b);
862-
863-
let len_a = iblocks_a.len(&ddef);
864-
let len_b = iblocks_b.len(&ddef);
865-
let len_union = union.len(&ddef);
866-
867-
prop_assert!(len_union >= len_a);
868-
prop_assert!(len_union >= len_b);
869-
}
870-
871-
#[proptest]
872-
fn intersection_with_empty_is_empty(
873-
#[strategy(any_impacted_blocks_strategy())] iblocks: ImpactedBlocks,
874-
) {
875-
// a . Empty == Empty
876-
prop_assert_eq!(
877-
iblocks.intersection(&ImpactedBlocks::Empty),
878-
ImpactedBlocks::Empty
879-
);
880-
}
881-
882-
#[proptest]
883-
fn union_with_empty_is_identity(
884-
#[strategy(any_impacted_blocks_strategy())] iblocks: ImpactedBlocks,
885-
) {
886-
// a . Empty == a
887-
prop_assert_eq!(iblocks.union(&ImpactedBlocks::Empty), iblocks);
888-
}
889-
890-
#[proptest]
891-
fn intersection_is_commutative(
892-
#[strategy(any_impacted_blocks_strategy())] iblocks_a: ImpactedBlocks,
893-
#[strategy(any_impacted_blocks_strategy())] iblocks_b: ImpactedBlocks,
894-
) {
895-
// a . b == b . a
896-
prop_assert_eq!(
897-
iblocks_a.intersection(&iblocks_b),
898-
iblocks_b.intersection(&iblocks_a)
899-
);
900-
}
901-
902-
#[proptest]
903-
fn union_is_commutative(
904-
#[strategy(any_impacted_blocks_strategy())] iblocks_a: ImpactedBlocks,
905-
#[strategy(any_impacted_blocks_strategy())] iblocks_b: ImpactedBlocks,
906-
) {
907-
// a . b == b . a
908-
prop_assert_eq!(
909-
iblocks_a.union(&iblocks_b),
910-
iblocks_b.union(&iblocks_a)
911-
);
912-
}
913-
914-
#[proptest]
915-
fn intersection_is_associative(
916-
#[strategy(any_impacted_blocks_strategy())] iblocks_a: ImpactedBlocks,
917-
#[strategy(any_impacted_blocks_strategy())] iblocks_b: ImpactedBlocks,
918-
#[strategy(any_impacted_blocks_strategy())] iblocks_c: ImpactedBlocks,
919-
) {
920-
// a . (b . c)
921-
let l = iblocks_a.intersection(&iblocks_b.intersection(&iblocks_c));
922-
923-
// (a . b) . c
924-
let r = iblocks_a.intersection(&iblocks_b).intersection(&iblocks_c);
925-
926-
// a . (b . c) == (a . b) . c
927-
prop_assert_eq!(l, r);
928-
}
929-
930-
#[proptest]
931-
fn union_is_associative(
932-
#[strategy(any_impacted_blocks_strategy())] iblocks_a: ImpactedBlocks,
933-
#[strategy(any_impacted_blocks_strategy())] iblocks_b: ImpactedBlocks,
934-
#[strategy(any_impacted_blocks_strategy())] iblocks_c: ImpactedBlocks,
935-
) {
936-
// a . (b . c)
937-
let l = iblocks_a.union(&iblocks_b.union(&iblocks_c));
938-
939-
// (a . b) . c
940-
let r = iblocks_a.union(&iblocks_b).union(&iblocks_c);
941-
942-
// a . (b . c) == (a . b) . c
943-
prop_assert_eq!(l, r);
944-
}
945-
946751
#[proptest]
947752
fn iblocks_from_offset_is_empty_for_zero_blocks(
948753
#[strategy(1..=u64::MAX)] extent_size: u64,
@@ -1058,135 +863,6 @@ mod test {
1058863
);
1059864
}
1060865

1061-
#[proptest]
1062-
fn iblocks_conflicts_is_commutative(
1063-
#[strategy(any_impacted_blocks_strategy())] iblocks_a: ImpactedBlocks,
1064-
#[strategy(any_impacted_blocks_strategy())] iblocks_b: ImpactedBlocks,
1065-
) {
1066-
// a . b == b . a
1067-
prop_assert_eq!(
1068-
iblocks_a.conflicts(&iblocks_b),
1069-
iblocks_b.conflicts(&iblocks_a)
1070-
);
1071-
}
1072-
1073-
#[proptest]
1074-
fn empty_impacted_blocks_never_conflict(
1075-
#[strategy(any_impacted_blocks_strategy())] iblocks: ImpactedBlocks,
1076-
) {
1077-
prop_assert!(!iblocks.conflicts(&ImpactedBlocks::Empty));
1078-
}
1079-
1080-
#[proptest]
1081-
fn overlapping_impacted_blocks_should_conflict(
1082-
// 4 random points, we'll make two overlapping ranges out of them
1083-
point_a: (u32, u64),
1084-
point_b: (u32, u64),
1085-
point_c: (u32, u64),
1086-
point_d: (u32, u64),
1087-
) {
1088-
// First we need to sort the points so we can use them correctly.
1089-
let mut sorted_points = [point_a, point_b, point_c, point_d];
1090-
sorted_points.sort();
1091-
let (eid_a, block_a) = sorted_points[0];
1092-
let (eid_b, block_b) = sorted_points[1];
1093-
let (eid_c, block_c) = sorted_points[2];
1094-
let (eid_d, block_d) = sorted_points[3];
1095-
1096-
// After sorting, if we make ranges from the pairs (a,c) and (b,d)
1097-
// then they are guaranteed to overlap.
1098-
let iblocks_a = ImpactedBlocks::new(
1099-
ImpactedAddr {
1100-
extent_id: ExtentId(eid_a),
1101-
block: BlockOffset(block_a),
1102-
},
1103-
ImpactedAddr {
1104-
extent_id: ExtentId(eid_c),
1105-
block: BlockOffset(block_c),
1106-
},
1107-
);
1108-
1109-
let iblocks_b = ImpactedBlocks::new(
1110-
ImpactedAddr {
1111-
extent_id: ExtentId(eid_b),
1112-
block: BlockOffset(block_b),
1113-
},
1114-
ImpactedAddr {
1115-
extent_id: ExtentId(eid_d),
1116-
block: BlockOffset(block_d),
1117-
},
1118-
);
1119-
1120-
// And thus they should conflict
1121-
prop_assert!(iblocks_a.conflicts(&iblocks_b),
1122-
"These overlapping ImpactedBlocks should conflict, but don't:\n {:?}\n {:?}",
1123-
iblocks_a,
1124-
iblocks_b);
1125-
}
1126-
1127-
#[proptest]
1128-
fn nothing_contains_empty(
1129-
#[strategy(any_impacted_blocks_strategy())] iblocks: ImpactedBlocks,
1130-
) {
1131-
prop_assert!(!iblocks.fully_contains(&ImpactedBlocks::Empty));
1132-
}
1133-
1134-
#[proptest]
1135-
fn empty_contains_nothing(
1136-
#[strategy(any_impacted_blocks_strategy())] iblocks: ImpactedBlocks,
1137-
) {
1138-
prop_assert!(!ImpactedBlocks::Empty.fully_contains(&iblocks));
1139-
}
1140-
1141-
const U32_U64_MAX: u128 = ((u32::MAX as u128) << 64) | (u64::MAX as u128);
1142-
#[proptest]
1143-
fn subregions_are_contained(
1144-
// proptest doesn't implement strategies for tuple-ranges for some
1145-
// reason, so I'm using a u128 in place of a (u32, u64)
1146-
#[strategy(0..=U32_U64_MAX)] outer_start: u128,
1147-
#[strategy(#outer_start..=U32_U64_MAX)] outer_end: u128,
1148-
1149-
// Inner must be within outer
1150-
#[strategy(#outer_start ..= #outer_end)] inner_start: u128,
1151-
#[strategy(#inner_start ..= #outer_end)] inner_end: u128,
1152-
) {
1153-
let (outer_eid_a, outer_block_a) =
1154-
((outer_start >> 64) as u32, outer_start as u64);
1155-
let (outer_eid_b, outer_block_b) =
1156-
((outer_end >> 64) as u32, outer_end as u64);
1157-
let (inner_eid_a, inner_block_a) =
1158-
((inner_start >> 64) as u32, inner_start as u64);
1159-
let (inner_eid_b, inner_block_b) =
1160-
((inner_end >> 64) as u32, inner_end as u64);
1161-
1162-
let outer_iblocks = ImpactedBlocks::new(
1163-
ImpactedAddr {
1164-
extent_id: ExtentId(outer_eid_a),
1165-
block: BlockOffset(outer_block_a),
1166-
},
1167-
ImpactedAddr {
1168-
extent_id: ExtentId(outer_eid_b),
1169-
block: BlockOffset(outer_block_b),
1170-
},
1171-
);
1172-
1173-
let inner_iblocks = ImpactedBlocks::new(
1174-
ImpactedAddr {
1175-
extent_id: ExtentId(inner_eid_a),
1176-
block: BlockOffset(inner_block_a),
1177-
},
1178-
ImpactedAddr {
1179-
extent_id: ExtentId(inner_eid_b),
1180-
block: BlockOffset(inner_block_b),
1181-
},
1182-
);
1183-
1184-
prop_assert!(outer_iblocks.fully_contains(&inner_iblocks),
1185-
"Outer ImpactedBlocks does not contain inner ImpactedBlocks:\n Outer: {:?}\n Inner: {:?}",
1186-
outer_iblocks,
1187-
inner_iblocks);
1188-
}
1189-
1190866
#[proptest]
1191867
/// We have a manual test of extent_from_offset above, but here's another
1192868
/// for good measure. We'll generate an ImpactedBlocks in a region, and then

0 commit comments

Comments
 (0)