|
32 | 32 |
|
33 | 33 | #include "mongo/db/storage/sorted_data_interface_test_harness.h" |
34 | 34 |
|
| 35 | +#include <algorithm> |
35 | 36 | #include <memory> |
36 | 37 |
|
37 | 38 | #include "mongo/db/storage/sorted_data_interface.h" |
@@ -168,5 +169,82 @@ TEST(SortedDataInterface, ExhaustCursorReversed) { |
168 | 169 | } |
169 | 170 | } |
170 | 171 |
|
| 172 | +void testBoundaries(bool unique, bool forward, bool inclusive) { |
| 173 | + const auto harnessHelper(newSortedDataInterfaceHarnessHelper()); |
| 174 | + const std::unique_ptr<SortedDataInterface> sorted( |
| 175 | + harnessHelper->newSortedDataInterface(unique)); |
| 176 | + |
| 177 | + const ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext()); |
| 178 | + ASSERT(sorted->isEmpty(opCtx.get())); |
| 179 | + |
| 180 | + int nToInsert = 10; |
| 181 | + for (int i = 0; i < nToInsert; i++) { |
| 182 | + WriteUnitOfWork uow(opCtx.get()); |
| 183 | + BSONObj key = BSON("" << i); |
| 184 | + RecordId loc(42 + i * 2); |
| 185 | + ASSERT_OK(sorted->insert(opCtx.get(), key, loc, true)); |
| 186 | + uow.commit(); |
| 187 | + } |
| 188 | + |
| 189 | + { |
| 190 | + const std::unique_ptr<SortedDataInterface::Cursor> cursor( |
| 191 | + sorted->newCursor(opCtx.get(), forward)); |
| 192 | + int startVal = 2; |
| 193 | + int endVal = 6; |
| 194 | + if (!forward) |
| 195 | + std::swap(startVal, endVal); |
| 196 | + |
| 197 | + auto startKey = BSON("" << startVal); |
| 198 | + auto endKey = BSON("" << endVal); |
| 199 | + cursor->setEndPosition(endKey, inclusive); |
| 200 | + |
| 201 | + auto entry = cursor->seek(startKey, inclusive); |
| 202 | + |
| 203 | + // Check that the cursor returns the expected values in range. |
| 204 | + int step = forward ? 1 : -1; |
| 205 | + for (int i = startVal + (inclusive ? 0 : step); i != endVal + (inclusive ? step : 0); |
| 206 | + i += step) { |
| 207 | + ASSERT_EQ(entry, IndexKeyEntry(BSON("" << i), RecordId(42 + i * 2))); |
| 208 | + entry = cursor->next(); |
| 209 | + } |
| 210 | + ASSERT(!entry); |
| 211 | + |
| 212 | + // Cursor at EOF should remain at EOF when advanced |
| 213 | + ASSERT(!cursor->next()); |
| 214 | + } |
| 215 | +} |
| 216 | + |
| 217 | +TEST(SortedDataInterfaceBoundaryTest, UniqueForwardWithNonInclusiveBoundaries) { |
| 218 | + testBoundaries(/*unique*/ true, /*forward*/ true, /*inclusive*/ false); |
| 219 | +} |
| 220 | + |
| 221 | +TEST(SortedDataInterfaceBoundaryTest, NonUniqueForwardWithNonInclusiveBoundaries) { |
| 222 | + testBoundaries(/*unique*/ false, /*forward*/ true, /*inclusive*/ false); |
| 223 | +} |
| 224 | + |
| 225 | +TEST(SortedDataInterfaceBoundaryTest, UniqueForwardWithInclusiveBoundaries) { |
| 226 | + testBoundaries(/*unique*/ true, /*forward*/ true, /*inclusive*/ true); |
| 227 | +} |
| 228 | + |
| 229 | +TEST(SortedDataInterfaceBoundaryTest, NonUniqueForwardWithInclusiveBoundaries) { |
| 230 | + testBoundaries(/*unique*/ false, /*forward*/ true, /*inclusive*/ true); |
| 231 | +} |
| 232 | + |
| 233 | +TEST(SortedDataInterfaceBoundaryTest, UniqueBackwardWithNonInclusiveBoundaries) { |
| 234 | + testBoundaries(/*unique*/ true, /*forward*/ false, /*inclusive*/ false); |
| 235 | +} |
| 236 | + |
| 237 | +TEST(SortedDataInterfaceBoundaryTest, NonUniqueBackwardWithNonInclusiveBoundaries) { |
| 238 | + testBoundaries(/*unique*/ false, /*forward*/ false, /*inclusive*/ false); |
| 239 | +} |
| 240 | + |
| 241 | +TEST(SortedDataInterfaceBoundaryTest, UniqueBackwardWithInclusiveBoundaries) { |
| 242 | + testBoundaries(/*unique*/ true, /*forward*/ false, /*inclusive*/ true); |
| 243 | +} |
| 244 | + |
| 245 | +TEST(SortedDataInterfaceBoundaryTest, NonUniqueBackwardWithInclusiveBoundaries) { |
| 246 | + testBoundaries(/*unique*/ false, /*forward*/ false, /*inclusive*/ true); |
| 247 | +} |
| 248 | + |
171 | 249 | } // namespace |
172 | 250 | } // namespace mongo |
0 commit comments