KV
KV Module
The KV (Key-Value) module provides a high-performance, thread-safe, in-memory key-value store for VintLang applications. It offers enterprise-grade features including TTL (Time-To-Live), atomic operations, bulk operations, and comprehensive statistics.
Import
import kv
Features
- ๐ Thread-Safe: Concurrent read/write operations with proper locking
- โฐ TTL Support: Automatic key expiration with customizable time-to-live
- ๐ Atomic Operations: Increment/decrement operations for counters
- ๐ฆ Bulk Operations: Efficient multi-key get/set operations
- ๐ Statistics: Real-time metrics and store monitoring
- ๐พ Data Dump: Export all data for debugging and backup
- ๐งน Memory Management: Automatic cleanup of expired keys
Basic Operations
set(key, value)
Sets a key-value pair in the store.
Parameters:
key(string): The key to setvalue(any): The value to store
Returns: boolean - true if successful
Example:
import kv kv.set("user:123", {"name": "John", "age": 30}) kv.set("session:456", "active") kv.set("counter", 42)
get(key)
Retrieves a value by its key.
Parameters:
key(string): The key to retrieve
Returns: The stored value, or null if not found or expired
Example:
let user = kv.get("user:123"); println("User:", user); // {name: John, age: 30} let missing = kv.get("nonexistent"); println("Missing:", missing); // null
delete(key)
Removes a key-value pair from the store.
Parameters:
key(string): The key to delete
Returns: boolean - true if key existed and was deleted
Example:
let deleted = kv.delete("session:456"); println("Deleted:", deleted); // true
exists(key)
Checks if a key exists in the store (and is not expired).
Parameters:
key(string): The key to check
Returns: boolean - true if key exists and is not expired
Example:
if (kv.exists("user:123")) { println("User exists"); }
clear()
Removes all key-value pairs from the store.
Returns: boolean - Always true
Example:
kv.clear(); println("Store cleared");
Store Information
keys()
Returns an array of all keys in the store (excluding expired keys).
Returns: array - Array of string keys
Example:
kv.set("key1", "value1"); kv.set("key2", "value2"); let allKeys = kv.keys(); println("Keys:", allKeys); // ["key1", "key2"]
values()
Returns an array of all values in the store (excluding expired values).
Returns: array - Array of stored values
Example:
let allValues = kv.values(); println("Values:", allValues); // ["value1", "value2"]
size()
Returns the number of key-value pairs in the store.
Returns: integer - Number of stored pairs
Example:
println("Store size:", kv.size()); // 2
isEmpty()
Checks if the store is empty.
Returns: boolean - true if store has no keys
Example:
if (kv.isEmpty()) { println("Store is empty"); }
TTL (Time-To-Live) Operations
setTTL(key, value, ttl_seconds)
Sets a key-value pair with automatic expiration.
Parameters:
key(string): The key to setvalue(any): The value to storettl_seconds(integer): Time-to-live in seconds
Returns: boolean - true if successful
Example:
// Set a session that expires in 5 minutes kv.setTTL("session:temp", "temporary_data", 300); // Set a cache entry that expires in 1 hour kv.setTTL("cache:user:123", userData, 3600);
getTTL(key)
Gets the remaining time-to-live for a key.
Parameters:
key(string): The key to check
Returns: integer - Remaining seconds, or -1 if no TTL set, or null if key doesn't exist
Example:
let remaining = kv.getTTL("session:temp"); if (remaining != null && remaining > 0) { println("Session expires in", remaining, "seconds"); }
expire(key, ttl_seconds)
Sets or updates the TTL for an existing key.
Parameters:
key(string): The key to set expiration forttl_seconds(integer): Time-to-live in seconds (must be positive)
Returns: boolean - true if key exists and TTL was set
Example:
kv.set("temp:data", "some data"); kv.expire("temp:data", 60); // Expire in 1 minute
Bulk Operations
mget(keys)
Gets multiple values in a single operation.
Parameters:
keys(array): Array of string keys to retrieve
Returns: array - Array of values in same order as keys (null for missing/expired keys)
Example:
kv.set("user:1", "Alice"); kv.set("user:2", "Bob"); let users = kv.mget(["user:1", "user:2", "user:3"]); println("Users:", users); // ["Alice", "Bob", null]
mset(pairs)
Sets multiple key-value pairs in a single operation.
Parameters:
pairs(dictionary): Dictionary of key-value pairs to set
Returns: boolean - true if all pairs were set successfully
Example:
let bulkData = { "config:theme": "dark", "config:language": "en", "config:notifications": true, }; kv.mset(bulkData);
Atomic Operations
increment(key, [delta])
Atomically increments a numeric value.
Parameters:
key(string): The key to incrementdelta(integer, optional): Amount to increment by (default: 1)
Returns: integer - The new value after increment
Notes:
- If key doesn't exist, creates it with the delta value
- If key exists but value is not an integer, returns an error
- Thread-safe for concurrent increments
Example:
// Simple counter let count = kv.increment("page:views"); println("Views:", count); // 1 // Increment by custom amount let score = kv.increment("user:score", 10); println("Score:", score); // 10 // Increment existing value kv.set("counter", 5); let newCount = kv.increment("counter", 3); println("New count:", newCount); // 8
decrement(key, [delta])
Atomically decrements a numeric value.
Parameters:
key(string): The key to decrementdelta(integer, optional): Amount to decrement by (default: 1)
Returns: integer - The new value after decrement
Notes:
- If key doesn't exist, creates it with the negative delta value
- If key exists but value is not an integer, returns an error
- Thread-safe for concurrent decrements
Example:
// Simple countdown let remaining = kv.decrement("lives"); println("Lives remaining:", remaining); // -1 // Decrement by custom amount kv.set("inventory", 100); let newInventory = kv.decrement("inventory", 15); println("Inventory:", newInventory); // 85
Utility Functions
dump()
Returns all key-value pairs in the store as a dictionary (excluding expired keys).
Returns: dictionary - All stored key-value pairs
Example:
kv.set("key1", "value1"); kv.set("key2", 42); let allData = kv.dump(); println("All data:", allData); // {key1: value1, key2: 42}
stats()
Returns statistics about the KV store.
Returns: dictionary - Statistics including:
total_keys: Total number of keys (including expired)active_keys: Number of active (non-expired) keysexpired_keys: Number of expired keyskeys_with_ttl: Number of keys that have TTL set
Example:
let statistics = kv.stats(); println("Store stats:", statistics); // {total_keys: 10, active_keys: 8, expired_keys: 2, keys_with_ttl: 5}
Common Use Cases
Session Management
import kv // Store user session with 30-minute expiration func createSession(userId, sessionData) { let sessionId = "session:" + userId kv.setTTL(sessionId, sessionData, 1800) // 30 minutes return sessionId } // Check if session is valid func isSessionValid(sessionId) { return kv.exists(sessionId) } // Extend session func extendSession(sessionId) { if (kv.exists(sessionId)) { kv.expire(sessionId, 1800) // Extend by 30 minutes return true } return false }
Caching
import kv // Cache expensive computation results func getCachedResult(cacheKey, computeFunc) { // Check cache first let cached = kv.get(cacheKey) if (cached != null) { return cached } // Compute and cache result let result = computeFunc() kv.setTTL(cacheKey, result, 300) // Cache for 5 minutes return result }
Rate Limiting
import kv // Simple rate limiter func isRateLimited(userId, limit, windowSeconds) { let key = "rate:" + userId let current = kv.get(key) if (current == null) { // First request in window kv.setTTL(key, 1, windowSeconds) return false } if (current >= limit) { return true // Rate limited } // Increment counter kv.increment(key) return false } // Usage: Allow 100 requests per minute if (isRateLimited("user123", 100, 60)) { println("Rate limited!") }
Counters and Metrics
import kv // Track page views func trackPageView(page) { kv.increment("views:" + page) kv.increment("total:views") } // Track user actions func trackUserAction(userId, action) { kv.increment("user:" + userId + ":actions") kv.increment("action:" + action + ":count") } // Get metrics func getMetrics() { return { "total_views": kv.get("total:views"), "stats": kv.stats(), "all_counters": kv.dump() } }
Configuration Management
import kv // Load configuration func loadConfig() { let defaultConfig = { "app:theme": "light", "app:language": "en", "app:debug": false, "cache:ttl": 3600 } kv.mset(defaultConfig) } // Update configuration func updateConfig(key, value) { kv.set("config:" + key, value) } // Get all configuration func getConfig() { let allData = kv.dump() let config = {} for (key, value in allData) { if (key.startsWith("config:")) { config[key] = value } } return config }
Performance Considerations
Thread Safety
- All operations are thread-safe using read-write mutexes
- Multiple concurrent reads are allowed
- Writes are exclusive and properly synchronized
Memory Management
- Expired keys are automatically cleaned up when accessed
- Use
clear()to free all memory when done - Monitor using
stats()to track memory usage
Bulk Operations
- Use
mget()andmset()for better performance with multiple keys - Bulk operations are more efficient than multiple single operations
TTL Best Practices
- Set appropriate TTL values to prevent memory leaks
- Use
getTTL()to check remaining time before operations - Consider using
expire()to extend TTL for active sessions
Error Handling
All KV functions return appropriate error messages for invalid usage:
// Invalid key type let result = kv.get(123); // Error: key must be a string // Invalid TTL let result = kv.expire("key", -5); // Error: TTL must be positive // Invalid increment target kv.set("text", "hello"); let result = kv.increment("text"); // Error: existing value must be an integer
Integration Examples
With HTTP Server
import kv import http // Simple API with caching let app = http.app() app.get("/api/user/:id", func(req, res) { let userId = req.params.id let cacheKey = "user:" + userId // Try cache first let user = kv.get(cacheKey) if (user != null) { return res.json({"user": user, "cached": true}) } // Fetch from database (simulated) user = fetchUserFromDB(userId) // Cache for 10 minutes kv.setTTL(cacheKey, user, 600) res.json({"user": user, "cached": false}) }) // Track API calls app.use(func(req, res, next) { kv.increment("api:calls") kv.increment("api:endpoint:" + req.path) next() })
With Async Operations
import kv // Async cache implementation async func getCachedOrFetch(key, fetchFunc) { let cached = kv.get(key) if (cached != null) { return cached } let result = await fetchFunc() kv.setTTL(key, result, 300) return result }
The KV module provides a robust foundation for in-memory data storage and caching in VintLang applications, with enterprise-grade features suitable for production use.