docs: Fix user-guide/maps.md

This commit is contained in:
Pragyansh Chaturvedi
2026-01-27 12:59:22 +05:30
parent 217e760e98
commit a31ef3997a

View File

@ -33,7 +33,7 @@ def my_map() -> HashMap:
#### Parameters #### Parameters
* `key` - The type of the key (must be a ctypes type) * `key` - The type of the key (must be a ctypes type or struct)
* `value` - The type of the value (must be a ctypes type or struct) * `value` - The type of the value (must be a ctypes type or struct)
* `max_entries` - Maximum number of entries the map can hold * `max_entries` - Maximum number of entries the map can hold
@ -47,11 +47,10 @@ Look up a value by key. Returns the value if found, `None` otherwise.
@bpf @bpf
@section("tracepoint/syscalls/sys_enter_open") @section("tracepoint/syscalls/sys_enter_open")
def trace_open(ctx: c_void_p) -> c_int64: def trace_open(ctx: c_void_p) -> c_int64:
key = c_uint32(1) value = my_map.lookup(1)
value = my_map.lookup(key)
if value: if value:
print(f"Found value: {value}") print(f"Found value: {value}")
return c_int64(0) return 0
``` ```
##### update(key, value, flags=None) ##### update(key, value, flags=None)
@ -67,8 +66,8 @@ def track_opens(ctx: c_void_p) -> c_int64:
if count: if count:
my_map.update(key, count + 1) my_map.update(key, count + 1)
else: else:
my_map.update(key, c_uint64(1)) my_map.update(key, 1)
return c_int64(0) return 0
``` ```
##### delete(key) ##### delete(key)
@ -78,9 +77,8 @@ Remove an entry from the map.
```python ```python
@bpf @bpf
def cleanup(ctx: c_void_p) -> c_int64: def cleanup(ctx: c_void_p) -> c_int64:
key = c_uint32(1) my_map.delete(1)
my_map.delete(key) return 0
return c_int64(0)
``` ```
#### Use Cases #### Use Cases
@ -108,14 +106,14 @@ def process_count() -> HashMap:
def count_processes(ctx: c_void_p) -> c_int64: def count_processes(ctx: c_void_p) -> c_int64:
process_id = pid() process_id = pid()
count = process_count.lookup(process_id) count = process_count.lookup(process_id)
if count: if count:
new_count = count + 1 new_count = count + 1
process_count.update(process_id, new_count) process_count.update(process_id, new_count)
else: else:
process_count.update(process_id, c_uint64(1)) process_count.update(process_id, 1)
return c_int64(0) return 0
@bpf @bpf
@bpfglobal @bpfglobal
@ -179,7 +177,7 @@ def send_event(ctx: c_void_p) -> c_int64:
event.pid = pid() event.pid = pid()
event.timestamp = ktime() event.timestamp = ktime()
events.output(event) events.output(event)
return c_int64(0) return 0
``` ```
#### Use Cases #### Use Cases
@ -215,10 +213,9 @@ def log_exec(ctx: c_void_p) -> c_int64:
event = ProcessEvent() event = ProcessEvent()
event.timestamp = ktime() event.timestamp = ktime()
event.pid = pid() event.pid = pid()
# Note: comm() requires a buffer parameter comm(event.comm) # Fills event.comm with process name
# comm(event.comm) # Fills event.comm with process name
events.output(event) events.output(event)
return c_int64(0) return 0
@bpf @bpf
@bpfglobal @bpfglobal
@ -258,7 +255,7 @@ def log_event(ctx: c_void_p) -> c_int64:
event = Event() event = Event()
event.pid = pid() event.pid = pid()
events.output(event) events.output(event)
return c_int64(0) return 0
``` ```
##### reserve(size) ##### reserve(size)
@ -272,7 +269,7 @@ def reserve_space(ctx: c_void_p) -> c_int64:
if ptr: if ptr:
# Use the reserved space # Use the reserved space
events.submit(ptr) events.submit(ptr)
return c_int64(0) return 0
``` ```
##### submit(data, flags=0) ##### submit(data, flags=0)
@ -343,18 +340,18 @@ def process_stats() -> HashMap:
def track_stats(ctx: c_void_p) -> c_int64: def track_stats(ctx: c_void_p) -> c_int64:
process_id = pid() process_id = pid()
stats = process_stats.lookup(process_id) stats = process_stats.lookup(process_id)
if stats: if stats:
stats.count = stats.count + 1 stats.count = stats.count + 1
process_stats.update(process_id, stats) process_stats.update(process_id, stats)
else: else:
new_stats = Stats() new_stats = Stats()
new_stats.count = c_uint64(1) new_stats.count = 1
new_stats.total_time = c_uint64(0) new_stats.total_time = 0
new_stats.max_time = c_uint64(0) new_stats.max_time = 0
process_stats.update(process_id, new_stats) process_stats.update(process_id, new_stats)
return c_int64(0) return 0
``` ```
## Accessing Maps from Userspace ## Accessing Maps from Userspace
@ -392,32 +389,6 @@ map_obj[key] = new_value
del map_obj[key] del map_obj[key]
``` ```
## Best Practices
1. **Choose the right map type**
* Use `HashMap` for key-value storage
* Use `RingBuffer` for event streaming (kernel 5.8+)
* Use `PerfEventArray` for older kernels
2. **Size maps appropriately**
* Consider maximum expected entries
* Balance memory usage vs. capacity
* Use LRU maps for automatic eviction
3. **Handle lookup failures**
* Always check if `lookup()` returns `None`
* Initialize new entries properly
4. **Minimize map operations**
* BPF has instruction limits
* Reduce unnecessary lookups
* Batch operations when possible
5. **Use structs for complex data**
* More efficient than multiple lookups
* Atomic updates of related fields
* Better cache locality
## Common Patterns ## Common Patterns
### Counter Pattern ### Counter Pattern
@ -427,7 +398,7 @@ count = my_map.lookup(key)
if count: if count:
my_map.update(key, count + 1) my_map.update(key, count + 1)
else: else:
my_map.update(key, c_uint64(1)) my_map.update(key, 1)
``` ```
### Latency Tracking ### Latency Tracking
@ -452,7 +423,7 @@ if start_time:
count = counter.lookup(key) count = counter.lookup(key)
if count and (count % 100) == 0: if count and (count % 100) == 0:
events.output(data) events.output(data)
counter.update(key, count + 1 if count else c_uint64(1)) counter.update(key, count + 1 if count else 1)
``` ```
## Troubleshooting ## Troubleshooting
@ -476,7 +447,6 @@ If updates fail due to map being full:
If you get type-related errors: If you get type-related errors:
* Verify key and value types match the definition * Verify key and value types match the definition
* Check that structs are properly defined * Check that structs are properly defined
* Ensure ctypes are used correctly
## Next Steps ## Next Steps