PcapFileEx.Merge.Heap (pcap_file_ex v0.5.5)
View SourceMin-heap priority queue for streaming packet merge.
This module implements a priority queue optimized for merging multiple packet streams in chronological order. Each heap entry contains:
- A packet
- The file index (for deterministic tie-breaking)
- The packet index within that file (for deterministic tie-breaking)
Performance
new/0: O(1)push/2: O(N) where N is the number of files (insert and sort)pop/1: O(1) (remove first element)- Memory: O(N files) - only one packet buffered per file
Ordering
Packets are ordered by:
timestamp_precise(primary key, nanosecond precision)file_index(secondary key, deterministic)packet_index(tertiary key, deterministic)
This ensures a stable, reproducible sort even when packets have identical timestamps.
Implementation Note
This uses a sorted list rather than a true binary heap. For typical use cases with <10 files, this is simpler and performs well.
Summary
Functions
Checks if the heap is empty.
Creates a new empty heap.
Returns the minimum packet without removing it.
Removes and returns the minimum packet from the heap.
Pushes a new packet onto the heap with its file and packet indices.
Returns the number of elements in the heap.
Types
@type heap_entry() :: {PcapFileEx.Timestamp.t(), file_index :: non_neg_integer(), packet_index :: non_neg_integer(), PcapFileEx.Packet.t(), original_interface_id :: non_neg_integer() | nil}
@type t() :: [heap_entry()]
Functions
Checks if the heap is empty.
Examples
iex> PcapFileEx.Merge.Heap.new() |> PcapFileEx.Merge.Heap.empty?()
true
@spec new() :: t()
Creates a new empty heap.
Examples
iex> PcapFileEx.Merge.Heap.new()
[]
@spec peek(t()) :: {PcapFileEx.Packet.t(), non_neg_integer(), non_neg_integer(), non_neg_integer() | nil} | :empty
Returns the minimum packet without removing it.
Returns {packet, file_index, packet_index, original_interface_id} or :empty if the heap is empty.
Examples
{packet, file_idx, pkt_idx, orig_iface_id} = PcapFileEx.Merge.Heap.peek(heap)
@spec pop(t()) :: {PcapFileEx.Packet.t(), non_neg_integer(), non_neg_integer(), non_neg_integer() | nil, t()} | :empty
Removes and returns the minimum packet from the heap.
Returns {packet, file_index, packet_index, original_interface_id, new_heap} or :empty if the heap is empty.
Examples
{packet, file_idx, pkt_idx, orig_iface_id, new_heap} = PcapFileEx.Merge.Heap.pop(heap)
@spec push( t(), PcapFileEx.Packet.t(), non_neg_integer(), non_neg_integer(), non_neg_integer() | nil ) :: t()
Pushes a new packet onto the heap with its file and packet indices.
Parameters
heap- The heap to push ontopacket- The packet to addfile_index- Index of the file this packet came from (for tie-breaking)packet_index- Index of this packet within its file (for tie-breaking)original_interface_id- Original interface ID before remapping (optional, for PCAPNG)
Examples
heap = PcapFileEx.Merge.Heap.new()
heap = PcapFileEx.Merge.Heap.push(heap, packet, 0, 42, 0)
@spec size(t()) :: non_neg_integer()
Returns the number of elements in the heap.
Examples
iex> heap = PcapFileEx.Merge.Heap.new()
iex> PcapFileEx.Merge.Heap.size(heap)
0