cache-rs 0.4.0

A high-performance, memory-efficient cache implementation supporting multiple eviction policies including LRU, LFU, LFUDA, SLRU and GDSF
Documentation
# Safety Considerations for the Cache Crate

This document outlines the safety considerations for users of the Cache crate, particularly when working with the `List` implementation.

## Raw Pointers and Unsafe Code

The `List` implementation uses raw pointers extensively to create an efficient doubly-linked list. This approach allows for O(1) operations but requires careful attention to safety.

### General Safety Guidelines

1. **Never free a node pointer manually** that has been returned by `add()` - the `List` owns the memory and will handle deallocation.

2. **Never use a pointer after the `List` is dropped** - all node pointers become invalid when the owning `List` is dropped.

3. **Never use a pointer after calling `remove_first()` or `remove_last()`** if that pointer might have been to the removed node.

4. **Node pointers are not thread-safe** - do not share node pointers across threads without proper synchronization.

### Unsafe Function Requirements

Functions marked `unsafe` in the API have specific requirements that must be met:

- `update(node, value, capture)`: The `node` must be a valid pointer to an `Entry` within the list.
- `get_value(node)` and `get_value_mut(node)`: The `node` must be a valid pointer to a non-sigil `Entry` within the list.
- `move_to_front(node)`: The `node` must be a valid pointer to an `Entry` within the list.
- `attach_last(node)`: The `node` must be a valid pointer to an `Entry` that is not already in the list.

### Common Pitfalls

1. **Using a node after it's been removed**: Always check if a node has been removed before using its pointer.

2. **Double insertion**: Never add a node that's already in the list. This will create cycles in the linked list.

3. **Null pointers**: While the API tries to handle null pointers gracefully, passing null pointers to unsafe functions is undefined behavior.

4. **Invalid memory**: Using pointers to freed memory will cause undefined behavior. The `List` implementation takes care of freeing memory when nodes are removed or when the list is dropped.

## Internal Safety Mechanisms

The `List` implementation uses several techniques to ensure memory safety:

1. **Sentinel nodes**: The list uses head and tail sentinel nodes to simplify operations and handle edge cases.

2. **Capacity limits**: The list enforces capacity limits to prevent unbounded growth.

3. **Null checks**: Functions check for null pointers where appropriate.

4. **Proper cleanup on drop**: The `Drop` implementation ensures all nodes are properly freed.

## Best Practices

1. **Use wrapper types**: Consider creating safe wrapper types around the raw pointer API if you need to use the `List` directly.

2. **Use higher-level cache implementations**: Where possible, use the higher-level cache implementations provided by this crate instead of working with the `List` directly.

3. **Document unsafe code**: When writing unsafe code that uses this `List` implementation, document the safety invariants you're maintaining.

4. **Test thoroughly**: Test unsafe code extensively, including edge cases like empty lists and full lists.