Skip to main content

Module shared

Module shared 

Source
Available on crate features alloc or std only.
Expand description

The Shared strategy: Preserves heap allocations for fast Bytes conversions.

This strategy keeps heap-allocated buffers on the heap even when they could fit inline, enabling zero-copy conversions with bytes::Bytes.

See shared::Bytes for usage examples and detailed documentation. The Shared strategy for Bytes.

This module provides the Bytes type alias configured with the Shared strategy, which prioritizes fast conversions and allocation sharing with bytes::Bytes.

§Key Characteristics

  • Zero-copy conversions: Converting to/from Bytes is O(1) for heap-allocated data
  • Preserves heap allocations: Once heap-allocated, stays on heap even when data shrinks
  • Reference-counted sharing: Heap allocations use Arc for cheap clones
  • Recommended default: Best for most use cases, especially I/O and networking

§When to Use

Choose this strategy when:

  • Frequent Bytes conversions: You often convert between Bytes and bytes::Bytes
  • Network protocols: Building HTTP servers, WebSocket handlers, or other I/O-heavy applications
  • Performance-critical paths: Speed is more important than memory overhead
  • Shared buffers: You frequently clone buffers and want cheap reference counting

§Basic Usage

use smol_bytes::shared::Bytes;

// Small data (≤62 bytes) is stored inline
let small = Bytes::from_static(b"hello world");
assert!(!small.is_heap());

// Large data is heap-allocated
let large = Bytes::from(vec![1u8; 100]);
assert!(large.is_heap());

// Cheap clone (reference counting)
let clone = large.clone();

§Behavior Details

§Memory Layout

┌─────────────────────────────────────────┐
│  Bytes (64 bytes on stack)          │
├─────────────────────────────────────────┤
│  Variant: Inline (≤62 bytes)            │
│  ┌────────────────────────────────────┐ │
│  │ [u8; 62] data                      │ │
│  │ u8 length                          │ │
│  │ u8 current_offset                  │ │
│  └────────────────────────────────────┘ │
│                                           │
│  Variant: Heap (>62 bytes or shrunk)    │
│  ┌────────────────────────────────────┐ │
│  │ bytes::Bytes (Arc<[u8]>)           │ │
│  └────────────────────────────────────┘ │
└─────────────────────────────────────────┘

§Operations and Allocation Behavior

use smol_bytes::shared::Bytes;
use bytes::Buf;

// Start with large heap allocation
let mut data = Bytes::from(vec![1u8; 100]);
assert!(data.is_heap());

// After advance, still heap-allocated (Shared strategy)
data.advance(70); // 30 bytes remain
assert!(data.is_heap()); // ✓ Still on heap!

// Zero-copy conversion to Bytes
let bytes: bytes::Bytes = data.into();
assert_eq!(bytes.len(), 30);

§Comparison: Operations That Keep vs Convert to Heap

OperationStarting StateResult StateNotes
advance()Heap (100 bytes)Heap (30 bytes)Stays heap
truncate()Heap (100 bytes)Heap (30 bytes)Stays heap
split_to()Heap (100 bytes)Heap (70 bytes)Both parts may be heap
split_off()Heap (100 bytes)Heap (30 bytes)Both parts may be heap
slice()HeapHeapNon-empty slices retain shared heap backing, even if ≤62 bytes

§Performance Characteristics

§Fast Operations (O(1))

  • clone() - Reference count increment
  • advance() - Pointer adjustment
  • truncate() - Length update
  • into::<Bytes>() - Zero-copy when heap-allocated

§Linear Operations (O(62) - copies up to 62 bytes)

  • Creating inline values from inline sources
  • Operations on inline values

§Examples

§Network Protocol Buffer

use smol_bytes::shared::Bytes;
use bytes::Buf;

// Receive data from network
let mut buffer = Bytes::from(vec![0u8; 1024]);

// Process header (advance past it)
buffer.advance(16);

// Buffer stays on heap for efficient passing to bytes::Bytes
assert!(buffer.is_heap());

// Zero-copy conversion for writing
let bytes: bytes::Bytes = buffer.into();
// ... write bytes to socket

§Parsing with Zero-Copy Slicing

use smol_bytes::shared::Bytes;

let data = Bytes::from(vec![1_u8; 128]);

// Extract different segments
let header = data.slice(0..2);
let payload = data.slice(2..8);
let checksum = data.slice(8..10);

// All share the same underlying allocation!

§Efficient Cloning

use smol_bytes::shared::Bytes;

let original = Bytes::from(vec![1u8; 100]);

// Cheap clones (just Arc reference count)
let clone1 = original.clone();
let clone2 = original.clone();
let clone3 = original.clone();

// All share the same heap allocation
assert!(original.is_heap());
assert!(clone1.is_heap());

Structs§

Shared
A strategy that preserves heap allocations for fast, zero-copy conversions with bytes::Bytes.

Type Aliases§

Bytes
A space-efficient byte buffer that shares heap allocations with bytes::Bytes.
Utf8Bytes
A shared, immutable UTF-8 string type alias using the Shared strategy.