Module rcu

Read-Copy-Update (RCU) synchronized hash table.

This library provides a Lua-accessible hash table that uses RCU (Read-Copy-Update) for synchronization within the Linux kernel. RCU allows for very fast, lockless read operations, while write operations (updates and deletions) are synchronized to ensure data consistency. This makes it highly suitable for scenarios where read operations significantly outnumber write operations and high concurrency is required.

Keys in the RCU table must be strings. Values must be Lunatik objects (i.e., userdata created by other Lunatik C modules like data.new(), lunatik.runtime(), etc.) or nil to delete an entry.

A practical example of its usage can be found in examples/shared.lua, which implements an in-memory key-value store.

Class rcu_table

rcu_table:__index (self, key) Retrieves a value (a Lunatik object) from the RCU table.
rcu_table:__newindex (self, key, value) Sets or removes a value in the RCU table.
rcu_table:map (self, callback) Iterates over the RCU table and calls a callback for each key-value pair.

rcu

table ([size=1024]) Creates a new RCU-synchronized hash table.


Class rcu_table

Represents an RCU-synchronized hash table. This is a userdata object returned by rcu.table(). It behaves like a standard Lua table for get (__index) and set (__newindex) operations but uses RCU internally for synchronization.

Keys must be strings. Values stored must be Lunatik objects (e.g., created via data.new(), lunatik.runtime()) or nil (to remove an entry). When a Lunatik object is retrieved, it's a new reference to that object.

Usage:

-- Assuming 'data' module is available for creating Lunatik objects
-- and 'rcu' module is required.
local rcu_store = rcu.table()
local my_data = data.new(10) -- Create a Lunatik object
my_data:setstring(0, "hello")

-- Set a value
rcu_store["my_key"] = my_data

-- Get a value
local retrieved_data = rcu_store["my_key"]
if retrieved_data then
  print(retrieved_data:getstring(0)) -- Output: hello
end

-- Remove a value
rcu_store["my_key"] = nil

-- Iterate
rcu_store:map(function(k, v_obj)
  print("Found key:", k, "Value object:", v_obj)
end)
rcu_table:__index (self, key)
Retrieves a value (a Lunatik object) from the RCU table. This is the Lua __index metamethod, allowing table-like access rcu_table[key]. Read operations are RCU-protected and lockless.

Parameters:

  • self rcu_table The RCU table instance.
  • key string The key to look up in the table.

Returns:

    lunatik_object The Lunatik object associated with the key, or nil if the key is not found. A new reference to the object is returned.

Usage:

    local my_object = my_rcu_table["some_key"]
    if my_object then
      -- Use my_object
    end
rcu_table:__newindex (self, key, value)
Sets or removes a value in the RCU table. This is the Lua __newindex metamethod, allowing table-like assignment rcu_table[key] = value. Write operations are synchronized.

Parameters:

  • self rcu_table The RCU table instance.
  • key string The key to set or update.
  • value lunatik_object or nil The Lunatik object to associate with the key. If nil, the key-value pair is removed from the table.

Raises:

Error if memory allocation fails during new entry creation.

Usage:

    local data_obj = data.new(5) -- Assuming 'data' module
    my_rcu_table["new_key"] = some_lunatik_object
    my_rcu_table["another_key"] = nil -- Removes 'another_key'
rcu_table:map (self, callback)
Iterates over the RCU table and calls a callback for each key-value pair. The iteration is RCU-protected. The order of iteration is not guaranteed. For each entry, a new reference to the value (Lunatik object) is obtained before calling the callback and released after the callback returns.

Parameters:

  • self rcu_table The RCU table instance.
  • callback function

    A Lua function that will be called for each entry in the table. The callback receives two arguments:

    1. key (string): The key of the current entry.
    2. value (lunatik_object): The Lunatik object associated with the key.

Returns:

    nil

Raises:

Error if the callback function raises an error during its execution.

Usage:

    -- Example: Iterating and printing content if values are 'data' objects
    my_rcu_table:map(function(k, v_obj)
      -- v_obj is the Lunatik object stored for the key.
      -- If it's a 'data' object (a common use case, see examples/shared.lua):
      print("Key:", k, "Content from data object:", v_obj:getstring(0))
    end)

rcu

table ([size=1024])
Creates a new RCU-synchronized hash table.

Parameters:

  • size integer Specifies the initial number of hash buckets (internal slots) for the table. This is not a hard limit on the number of entries the table can store. The provided size will be rounded up to the nearest power of two. Choosing an appropriate size involves a trade-off between memory usage and performance:

    • more buckets (larger size): Consumes more memory for the table structure itself, even if many buckets remain empty. However, it reduces the probability of hash collisions, which can significantly speed up operations (lookups, insertions, deletions), especially when storing a large number of entries.
    • fewer buckets (smaller size): Uses less memory for the table's internal array. However, if the number of entries is high relative to the number of buckets, it increases the chance of hash collisions. This means more entries might end up in the same bucket, forming longer linked lists that need to be traversed, thereby slowing down operations.

    Guidance: For optimal performance, aim for a size that is roughly in the order of, or somewhat larger than, the maximum number of entries you anticipate storing. This helps maintain a low average number of entries per bucket (a low "load factor," ideally close to 1). The table can hold more entries than its size (number of buckets), but performance will degrade as the load factor increases. The default is a general-purpose starting point suitable for many common use cases. (default 1024)

Returns:

    rcu_table A new RCU table object, or raises an error if memory allocation fails.

Usage:

    local my_rcu_table = rcu.table() -- Default: 1024 buckets, good for moderate entries.
    local small_table = rcu.table(128) -- 128 buckets, for fewer expected entries.
    local large_table = rcu.table(8192) -- 8192 buckets, for many expected entries.
generated by LDoc 1.5.0 Last updated 2025-06-27 17:53:55