xref: /aosp_15_r20/external/curl/docs/internals/SPLAY.md (revision 6236dae45794135f37c4eb022389c904c8b0090d)
1*6236dae4SAndroid Build Coastguard Worker<!--
2*6236dae4SAndroid Build Coastguard WorkerCopyright (C) Daniel Stenberg, <[email protected]>, et al.
3*6236dae4SAndroid Build Coastguard Worker
4*6236dae4SAndroid Build Coastguard WorkerSPDX-License-Identifier: curl
5*6236dae4SAndroid Build Coastguard Worker-->
6*6236dae4SAndroid Build Coastguard Worker
7*6236dae4SAndroid Build Coastguard Worker# `splay`
8*6236dae4SAndroid Build Coastguard Worker
9*6236dae4SAndroid Build Coastguard Worker    #include "splay.h"
10*6236dae4SAndroid Build Coastguard Worker
11*6236dae4SAndroid Build Coastguard WorkerThis is an internal module for splay tree management. A splay tree is a binary
12*6236dae4SAndroid Build Coastguard Workersearch tree with the additional property that recently accessed elements are
13*6236dae4SAndroid Build Coastguard Workerquick to access again. A self-balancing tree.
14*6236dae4SAndroid Build Coastguard Worker
15*6236dae4SAndroid Build Coastguard WorkerNodes are added to the tree, they are accessed and removed from the tree and
16*6236dae4SAndroid Build Coastguard Workerit automatically rebalances itself in each operation.
17*6236dae4SAndroid Build Coastguard Worker
18*6236dae4SAndroid Build Coastguard Worker## libcurl use
19*6236dae4SAndroid Build Coastguard Worker
20*6236dae4SAndroid Build Coastguard Workerlibcurl adds fixed timeout expiry timestamps to the splay tree, and is meant
21*6236dae4SAndroid Build Coastguard Workerto scale up to holding a huge amount of pending timeouts with decent
22*6236dae4SAndroid Build Coastguard Workerperformance.
23*6236dae4SAndroid Build Coastguard Worker
24*6236dae4SAndroid Build Coastguard WorkerThe splay tree is used to:
25*6236dae4SAndroid Build Coastguard Worker
26*6236dae4SAndroid Build Coastguard Worker1. figure out the next timeout expiry value closest in time
27*6236dae4SAndroid Build Coastguard Worker2. iterate over timeouts that already have expired
28*6236dae4SAndroid Build Coastguard Worker
29*6236dae4SAndroid Build Coastguard WorkerThis splay tree rebalances itself based on the time value.
30*6236dae4SAndroid Build Coastguard Worker
31*6236dae4SAndroid Build Coastguard WorkerEach node in the splay tree points to a `struct Curl_easy`. Each `Curl_easy`
32*6236dae4SAndroid Build Coastguard Workerstruct is represented only once in the tree. To still allow each easy handle
33*6236dae4SAndroid Build Coastguard Workerto have a large number of timeouts per handle, each handle has a sorted linked
34*6236dae4SAndroid Build Coastguard Workerlist of pending timeouts. Only the handle's timeout that is closest to expire
35*6236dae4SAndroid Build Coastguard Workeris the timestamp used for the splay tree node.
36*6236dae4SAndroid Build Coastguard Worker
37*6236dae4SAndroid Build Coastguard WorkerWhen a specific easy handle's timeout expires, the node gets removed from the
38*6236dae4SAndroid Build Coastguard Workersplay tree and from the handle's linked list of timeouts. The next timeout for
39*6236dae4SAndroid Build Coastguard Workerthat handle is then first in line and becomes the new timeout value as the
40*6236dae4SAndroid Build Coastguard Workernode is re-added to the splay.
41*6236dae4SAndroid Build Coastguard Worker
42*6236dae4SAndroid Build Coastguard Worker## `Curl_splay`
43*6236dae4SAndroid Build Coastguard Worker
44*6236dae4SAndroid Build Coastguard Worker~~~c
45*6236dae4SAndroid Build Coastguard Workerstruct Curl_tree *Curl_splay(struct curltime i, struct Curl_tree *t);
46*6236dae4SAndroid Build Coastguard Worker~~~
47*6236dae4SAndroid Build Coastguard Worker
48*6236dae4SAndroid Build Coastguard WorkerRearranges the tree `t` after the provide time `i`.
49*6236dae4SAndroid Build Coastguard Worker
50*6236dae4SAndroid Build Coastguard Worker## `Curl_splayinsert`
51*6236dae4SAndroid Build Coastguard Worker
52*6236dae4SAndroid Build Coastguard Worker~~~c
53*6236dae4SAndroid Build Coastguard Workerstruct Curl_tree *Curl_splayinsert(struct curltime key,
54*6236dae4SAndroid Build Coastguard Worker                                   struct Curl_tree *t,
55*6236dae4SAndroid Build Coastguard Worker                                   struct Curl_tree *node);
56*6236dae4SAndroid Build Coastguard Worker~~~
57*6236dae4SAndroid Build Coastguard Worker
58*6236dae4SAndroid Build Coastguard WorkerThis function inserts a new `node` in the tree, using the given `key`
59*6236dae4SAndroid Build Coastguard Workertimestamp. The `node` struct has a field called `->payload` that can be set to
60*6236dae4SAndroid Build Coastguard Workerpoint to anything. libcurl sets this to the `struct Curl_easy` handle that is
61*6236dae4SAndroid Build Coastguard Workerassociated with the timeout value set in `key`.
62*6236dae4SAndroid Build Coastguard Worker
63*6236dae4SAndroid Build Coastguard WorkerThe splay insert function does not allocate any memory, it assumes the caller
64*6236dae4SAndroid Build Coastguard Workerhas that arranged.
65*6236dae4SAndroid Build Coastguard Worker
66*6236dae4SAndroid Build Coastguard WorkerIt returns a pointer to the new tree root.
67*6236dae4SAndroid Build Coastguard Worker
68*6236dae4SAndroid Build Coastguard Worker## `Curl_splaygetbest`
69*6236dae4SAndroid Build Coastguard Worker
70*6236dae4SAndroid Build Coastguard Worker~~~c
71*6236dae4SAndroid Build Coastguard Workerstruct Curl_tree *Curl_splaygetbest(struct curltime key,
72*6236dae4SAndroid Build Coastguard Worker                                    struct Curl_tree *tree,
73*6236dae4SAndroid Build Coastguard Worker                                    struct Curl_tree **removed);
74*6236dae4SAndroid Build Coastguard Worker~~~
75*6236dae4SAndroid Build Coastguard Worker
76*6236dae4SAndroid Build Coastguard WorkerIf there is a node in the `tree` that has a time value that is less than the
77*6236dae4SAndroid Build Coastguard Workerprovided `key`, this function removes that node from the tree and provides it
78*6236dae4SAndroid Build Coastguard Workerin the `*removed` pointer (or NULL if there was no match).
79*6236dae4SAndroid Build Coastguard Worker
80*6236dae4SAndroid Build Coastguard WorkerIt returns a pointer to the new tree root.
81*6236dae4SAndroid Build Coastguard Worker
82*6236dae4SAndroid Build Coastguard Worker## `Curl_splayremove`
83*6236dae4SAndroid Build Coastguard Worker
84*6236dae4SAndroid Build Coastguard Worker~~~c
85*6236dae4SAndroid Build Coastguard Workerint Curl_splayremove(struct Curl_tree *tree,
86*6236dae4SAndroid Build Coastguard Worker                     struct Curl_tree *node,
87*6236dae4SAndroid Build Coastguard Worker                     struct Curl_tree **newroot);
88*6236dae4SAndroid Build Coastguard Worker~~~
89*6236dae4SAndroid Build Coastguard Worker
90*6236dae4SAndroid Build Coastguard WorkerRemoves a given `node` from a splay `tree`, and returns the `newroot`
91*6236dae4SAndroid Build Coastguard Workeridentifying the new tree root.
92*6236dae4SAndroid Build Coastguard Worker
93*6236dae4SAndroid Build Coastguard WorkerNote that a clean tree without any nodes present implies a NULL pointer.
94*6236dae4SAndroid Build Coastguard Worker
95*6236dae4SAndroid Build Coastguard Worker## `Curl_splayset`
96*6236dae4SAndroid Build Coastguard Worker
97*6236dae4SAndroid Build Coastguard Worker~~~c
98*6236dae4SAndroid Build Coastguard Workervoid Curl_splayset(struct Curl_tree *node, void *payload);
99*6236dae4SAndroid Build Coastguard Worker~~~
100*6236dae4SAndroid Build Coastguard Worker
101*6236dae4SAndroid Build Coastguard WorkerSet a custom pointer to be stored in the splay node. This pointer is not used
102*6236dae4SAndroid Build Coastguard Workerby the splay code itself and can be retrieved again with `Curl_splayget`.
103*6236dae4SAndroid Build Coastguard Worker
104*6236dae4SAndroid Build Coastguard Worker## `Curl_splayget`
105*6236dae4SAndroid Build Coastguard Worker
106*6236dae4SAndroid Build Coastguard Worker~~~c
107*6236dae4SAndroid Build Coastguard Workervoid *Curl_splayget(struct Curl_tree *node);
108*6236dae4SAndroid Build Coastguard Worker~~~
109*6236dae4SAndroid Build Coastguard Worker
110*6236dae4SAndroid Build Coastguard WorkerGet the custom pointer from the splay node that was previously set with
111*6236dae4SAndroid Build Coastguard Worker`Curl_splayset`. If no pointer was set before, it returns NULL.
112