mirror of
https://github.com/c-cube/tiny_httpd.git
synced 2026-01-22 09:16:50 -05:00
78 lines
15 KiB
HTML
78 lines
15 KiB
HTML
<!DOCTYPE html>
|
||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Queue (ocaml.Stdlib.Queue)</title><meta charset="utf-8"/><link rel="stylesheet" href="../../../_odoc-theme/odoc.css"/><meta name="generator" content="odoc 3.0.0"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><script src="../../../highlight.pack.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body class="odoc"><nav class="odoc-nav"><a href="../index.html">Up</a> – <a href="../../../index.html">Index</a> » <a href="../../index.html">ocaml</a> » <a href="../index.html">Stdlib</a> » Queue</nav><header class="odoc-preamble"><h1>Module <code><span>Stdlib.Queue</span></code></h1><p>First-in first-out queues.</p><p>This module implements queues (FIFOs), with in-place modification. See <a href="#examples" title="examples">the example section</a> below.</p></header><div class="odoc-tocs"><nav class="odoc-toc odoc-local-toc"><ul><li><a href="#iterators">Iterators</a></li><li><a href="#examples">Examples</a><ul><li><a href="#basic-example">Basic Example</a></li><li><a href="#search-through-a-graph">Search Through a Graph</a></li></ul></li></ul></nav></div><div class="odoc-content"><p><b>Unsynchronized accesses</b></p><p>Unsynchronized accesses to a queue may lead to an invalid queue state. Thus, concurrent accesses to queues must be synchronized (for instance with a <a href="../Mutex/index.html#type-t"><code>Mutex.t</code></a>).</p><div class="odoc-spec"><div class="spec type anchored" id="type-t"><a href="#type-t" class="anchor"></a><code><span><span class="keyword">type</span> <span>!'a t</span></span></code></div><div class="spec-doc"><p>The type of queues containing elements of type <code>'a</code>.</p></div></div><div class="odoc-spec"><div class="spec exception anchored" id="exception-Empty"><a href="#exception-Empty" class="anchor"></a><code><span><span class="keyword">exception</span> </span><span><span class="exception">Empty</span></span></code></div><div class="spec-doc"><p>Raised when <a href="#val-take"><code>Queue.take</code></a> or <a href="#val-peek"><code>Queue.peek</code></a> is applied to an empty queue.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-create"><a href="#val-create" class="anchor"></a><code><span><span class="keyword">val</span> create : <span>unit <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Return a new queue, initially empty.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-add"><a href="#val-add" class="anchor"></a><code><span><span class="keyword">val</span> add : <span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> unit</span></code></div><div class="spec-doc"><p><code>add x q</code> adds the element <code>x</code> at the end of the queue <code>q</code>.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-push"><a href="#val-push" class="anchor"></a><code><span><span class="keyword">val</span> push : <span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> unit</span></code></div><div class="spec-doc"><p><code>push</code> is a synonym for <code>add</code>.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-take"><a href="#val-take" class="anchor"></a><code><span><span class="keyword">val</span> take : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span class="type-var">'a</span></span></code></div><div class="spec-doc"><p><code>take q</code> removes and returns the first element in queue <code>q</code>, or raises <a href="#exception-Empty"><code>Empty</code></a> if the queue is empty.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-take_opt"><a href="#val-take_opt" class="anchor"></a><code><span><span class="keyword">val</span> take_opt : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> option</span></span></code></div><div class="spec-doc"><p><code>take_opt q</code> removes and returns the first element in queue <code>q</code>, or returns <code>None</code> if the queue is empty.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.08</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-pop"><a href="#val-pop" class="anchor"></a><code><span><span class="keyword">val</span> pop : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span class="type-var">'a</span></span></code></div><div class="spec-doc"><p><code>pop</code> is a synonym for <code>take</code>.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-peek"><a href="#val-peek" class="anchor"></a><code><span><span class="keyword">val</span> peek : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span class="type-var">'a</span></span></code></div><div class="spec-doc"><p><code>peek q</code> returns the first element in queue <code>q</code>, without removing it from the queue, or raises <a href="#exception-Empty"><code>Empty</code></a> if the queue is empty.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-peek_opt"><a href="#val-peek_opt" class="anchor"></a><code><span><span class="keyword">val</span> peek_opt : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> option</span></span></code></div><div class="spec-doc"><p><code>peek_opt q</code> returns the first element in queue <code>q</code>, without removing it from the queue, or returns <code>None</code> if the queue is empty.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.08</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-top"><a href="#val-top" class="anchor"></a><code><span><span class="keyword">val</span> top : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span class="type-var">'a</span></span></code></div><div class="spec-doc"><p><code>top</code> is a synonym for <code>peek</code>.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-drop"><a href="#val-drop" class="anchor"></a><code><span><span class="keyword">val</span> drop : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> unit</span></code></div><div class="spec-doc"><p><code>drop q</code> removes the first element in queue <code>q</code>, or raises <a href="#exception-Empty"><code>Empty</code></a> if the queue is empty.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 5.3</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-clear"><a href="#val-clear" class="anchor"></a><code><span><span class="keyword">val</span> clear : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> unit</span></code></div><div class="spec-doc"><p>Discard all elements from a queue.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-copy"><a href="#val-copy" class="anchor"></a><code><span><span class="keyword">val</span> copy : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Return a copy of the given queue.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-is_empty"><a href="#val-is_empty" class="anchor"></a><code><span><span class="keyword">val</span> is_empty : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> bool</span></code></div><div class="spec-doc"><p>Return <code>true</code> if the given queue is empty, <code>false</code> otherwise.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-length"><a href="#val-length" class="anchor"></a><code><span><span class="keyword">val</span> length : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> int</span></code></div><div class="spec-doc"><p>Return the number of elements in a queue.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-iter"><a href="#val-iter" class="anchor"></a><code><span><span class="keyword">val</span> iter : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> unit)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> unit</span></code></div><div class="spec-doc"><p><code>iter f q</code> applies <code>f</code> in turn to all elements of <code>q</code>, from the least recently entered to the most recently entered. The queue itself is unchanged.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-fold"><a href="#val-fold" class="anchor"></a><code><span><span class="keyword">val</span> fold : <span><span>(<span><span class="type-var">'acc</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span class="type-var">'acc</span>)</span> <span class="arrow">-></span></span> <span><span class="type-var">'acc</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span class="type-var">'acc</span></span></code></div><div class="spec-doc"><p><code>fold f accu q</code> is equivalent to <code>List.fold_left f accu l</code>, where <code>l</code> is the list of <code>q</code>'s elements. The queue remains unchanged.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-transfer"><a href="#val-transfer" class="anchor"></a><code><span><span class="keyword">val</span> transfer : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> unit</span></code></div><div class="spec-doc"><p><code>transfer q1 q2</code> adds all of <code>q1</code>'s elements at the end of the queue <code>q2</code>, then clears <code>q1</code>. It is equivalent to the sequence <code>iter (fun x -> add x q2) q1; clear q1</code>, but runs in constant time.</p></div></div><h2 id="iterators"><a href="#iterators" class="anchor"></a>Iterators</h2><div class="odoc-spec"><div class="spec value anchored" id="val-to_seq"><a href="#val-to_seq" class="anchor"></a><code><span><span class="keyword">val</span> to_seq : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="../Seq/index.html#type-t">Seq.t</a></span></span></code></div><div class="spec-doc"><p>Iterate on the queue, in front-to-back order. The behavior is not specified if the queue is modified during the iteration.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.07</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-add_seq"><a href="#val-add_seq" class="anchor"></a><code><span><span class="keyword">val</span> add_seq : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="../Seq/index.html#type-t">Seq.t</a></span> <span class="arrow">-></span></span> unit</span></code></div><div class="spec-doc"><p>Add the elements from a sequence to the end of the queue.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.07</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-of_seq"><a href="#val-of_seq" class="anchor"></a><code><span><span class="keyword">val</span> of_seq : <span><span><span class="type-var">'a</span> <a href="../Seq/index.html#type-t">Seq.t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Create a queue from a sequence.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 4.07</li></ul></div></div><h2 id="examples"><a href="#examples" class="anchor"></a>Examples</h2><h3 id="basic-example"><a href="#basic-example" class="anchor"></a>Basic Example</h3><p>A basic example:</p><pre class="language-ocaml"><code># let q = Queue.create ()
|
||
val q : '_weak1 Queue.t = <abstr>
|
||
|
||
|
||
# Queue.push 1 q; Queue.push 2 q; Queue.push 3 q
|
||
- : unit = ()
|
||
|
||
# Queue.length q
|
||
- : int = 3
|
||
|
||
# Queue.pop q
|
||
- : int = 1
|
||
|
||
# Queue.pop q
|
||
- : int = 2
|
||
|
||
# Queue.pop q
|
||
- : int = 3
|
||
|
||
# Queue.pop q
|
||
Exception: Stdlib.Queue.Empty.</code></pre><h3 id="search-through-a-graph"><a href="#search-through-a-graph" class="anchor"></a>Search Through a Graph</h3><p>For a more elaborate example, a classic algorithmic use of queues is to implement a BFS (breadth-first search) through a graph.</p><pre class="language-ocaml"><code> type graph = {
|
||
edges: (int, int list) Hashtbl.t
|
||
}
|
||
|
||
(* Search in graph [g] using BFS, starting from node [start].
|
||
It returns the first node that satisfies [p], or [None] if
|
||
no node reachable from [start] satisfies [p].
|
||
*)
|
||
let search_for ~(g:graph) ~(start:int) (p:int -> bool) : int option =
|
||
let to_explore = Queue.create() in
|
||
let explored = Hashtbl.create 16 in
|
||
|
||
Queue.push start to_explore;
|
||
let rec loop () =
|
||
if Queue.is_empty to_explore then None
|
||
else
|
||
(* node to explore *)
|
||
let node = Queue.pop to_explore in
|
||
explore_node node
|
||
|
||
and explore_node node =
|
||
if not (Hashtbl.mem explored node) then (
|
||
if p node then Some node (* found *)
|
||
else (
|
||
Hashtbl.add explored node ();
|
||
let children =
|
||
Hashtbl.find_opt g.edges node
|
||
|> Option.value ~default:[]
|
||
in
|
||
List.iter (fun child -> Queue.push child to_explore) children;
|
||
loop()
|
||
)
|
||
) else loop()
|
||
in
|
||
loop()
|
||
|
||
(* a sample graph *)
|
||
let my_graph: graph =
|
||
let edges =
|
||
List.to_seq [
|
||
1, [2;3];
|
||
2, [10; 11];
|
||
3, [4;5];
|
||
5, [100];
|
||
11, [0; 20];
|
||
]
|
||
|> Hashtbl.of_seq
|
||
in {edges}
|
||
|
||
# search_for ~g:my_graph ~start:1 (fun x -> x = 30)
|
||
- : int option = None
|
||
|
||
# search_for ~g:my_graph ~start:1 (fun x -> x >= 15)
|
||
- : int option = Some 20
|
||
|
||
# search_for ~g:my_graph ~start:1 (fun x -> x >= 50)
|
||
- : int option = Some 100</code></pre></div></body></html>
|