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