Skip to content

Conversation

@Fusl
Copy link

@Fusl Fusl commented Jul 6, 2024

Inspired by the Redis SCAN command, this pull request introduces an incremental and iterative key scanning method for our map data structure. The goal is to allow for efficient iteration over the entire map without the need to maintain an open communication channel, enabling better handling of large datasets.

Changes Introduced

  • New Method: Scan(cursor uint32, yield func(key K, value V) bool) (nextCursor uint32)

    • Parameters:
      • cursor: A previously returned cursor from a call to Scan or 0 to start from the beginning.
      • yield: A function that processes each key-value pair. If it returns false, the iteration stops.
    • Returns:
      • nextCursor: The cursor to use in the next call to Scan. 0 indicates the iteration is complete.
  • Implementation Details:

    • Bucket Handling: The method calculates the appropriate bucket, group, and slot based on the cursor.
    • Iteration Logic:
      • Iterates through the buckets, groups, and slots in the map.
      • Uses a snapshot of the groups and groupMask to ensure iteration remains valid even if the map is resized during iteration.
      • The iteration can be stopped prematurely if the yield function returns false, allowing the implementation of a count limit similar to the Redis SCAN command.

Example Usage

Here's an example demonstrating how to use the Scan method to process keys in batches of 10:

var cursor uint32
for {
	keys := make([]int, 0, 10)
	cursor = m.Scan(cursor, func(key K, value V) bool {
		keys = append(keys, key)
		return len(keys) < 10
	})
	processKeys(keys)
	if cursor == 0 {
		break
	}
}

Motivation

The primary motivation behind this change is to provide a more flexible and scalable way to iterate over large maps. By implementing a SCAN-like method, we can handle partial iterations and avoid the overhead of maintaining a persistent connection. The iteration can be paused and resumed, making it easier to integrate with other processing workflows.

@cockroach-teamcity
Copy link
Member

This change is Reviewable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants