Repository: tikv/tikv
File: src/storage/mvcc/reader/reader.rs (Rust)

Code before:
            shared_locks.to_bytes(),
        )]);

        // Scan with limit=1
        let snap = RegionSnapshot::<RocksSnapshot>::from_raw(db.clone(), region.clone());
        let mut reader = MvccReader::new(snap, None, false);
        let (locks, _has_remain) = reader
            .scan_locks_from_storage(None, None, |_, _| true, 1)
            .unwrap();

        // Count total individual locks returned
        let total_locks: usize = locks
            .iter()
            .map(|(_, lor)| match lor {
                Either::Left(_) => 1,
                Either::Right(shared) => shared.len(),
            })
            .sum();

        // REGRESSION TEST: This assertion will FAIL with current implementation
        // because limit=1 returns 1 KEY which contains 5 individual locks
        assert!(
            total_locks <= 1,
            "Expected at most 1 lock when limit=1, but got {} locks. \
             The limit parameter counts KEYS, not individual locks in SharedLocks.",
            total_locks
        );
    }

    #[test]
    fn test_scan_latest_user_keys() {
        let path = tempfile::Builder::new()
            .prefix("_test_storage_mvcc_reader_scan_latest_user_keys")
            .tempdir()
            .unwrap();
        let path = path.path().to_str().unwrap();
        let region = make_region(1, vec![], vec![]);
        let db = open_db(path, true);
        let mut engine = RegionEngine::new(&db, &region);

        // Prewrite and rollback k0.
        engine.prewrite(
            Mutation::make_put(Key::from_raw(b"k0"), b"v0@1".to_vec()),
            b"k0",
            1,
        );
        engine.rollback(b"k0", 1);
        // Prewrite and commit k0 with a large ts.
        engine.prewrite(
            Mutation::make_put(Key::from_raw(b"k0"), b"v0@999".to_vec()),
            b"k0",

Review comment (bug):
The test comment is misleading. It states "REGRESSION TEST: This assertion will FAIL with current implementation" and describes the old buggy behavior. Since this PR fixes the issue, the comment should state that this test verifies the fix works correctly: that the limit parameter now counts individual locks, not keys.

Code after:
        )]);

        // Scan with limit=1
        let snap = RegionSnapshot::<RocksSnapshot>::from_raw(db.clone(), region.clone());
        let mut reader = MvccReader::new(snap, None, false);
        let (locks, _has_remain) = reader
            .scan_locks_from_storage(None, None, |_, _| true, 1)
            .unwrap();

        // Count total individual locks returned
        let total_locks: usize = locks
            .iter()
            .map(|(_, lor)| match lor {
                Either::Left(_) => 1,
                Either::Right(shared) => shared.len(),
            })
            .sum();

        assert!(
            total_locks <= 1,
            "Expected at most 1 lock when limit=1, but got {} locks.",
            total_locks
        );
    }

    #[test]
    fn test_scan_latest_user_keys() {
        let path = tempfile::Builder::new()
            .prefix("_test_storage_mvcc_reader_scan_latest_user_keys")
            .tempdir()
            .unwrap();
        let path = path.path().to_str().unwrap();
        let region = make_region(1, vec![], vec![]);
        let db = open_db(path, true);
        let mut engine = RegionEngine::new(&db, &region);

        // Prewrite and rollback k0.
        engine.prewrite(
            Mutation::make_put(Key::from_raw(b"k0"), b"v0@1".to_vec()),
            b"k0",
            1,
        );
        engine.rollback(b"k0", 1);
        // Prewrite and commit k0 with a large ts.
        engine.prewrite(
            Mutation::make_put(Key::from_raw(b"k0"), b"v0@999".to_vec()),
            b"k0",
            999,
        );
        engine.commit(b"k0", 999, 1000);
        // Prewrite and commit k1.