????JFIF??x?x????'
| Server IP : 79.136.114.73 / Your IP : 216.73.216.191 Web Server : Apache/2.4.7 (Ubuntu) PHP/5.5.9-1ubuntu4.29 OpenSSL/1.0.1f System : Linux b8009 3.13.0-170-generic #220-Ubuntu SMP Thu May 9 12:40:49 UTC 2019 x86_64 User : www-data ( 33) PHP Version : 5.5.9-1ubuntu4.29 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority, MySQL : ON | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /proc/self/root/home/b8009/thermia/Python-3.6.3/Modules/ |
Upload File : |
#include "rotatingtree.h"
#define KEY_LOWER_THAN(key1, key2) ((char*)(key1) < (char*)(key2))
/* The randombits() function below is a fast-and-dirty generator that
* is probably irregular enough for our purposes. Note that it's biased:
* I think that ones are slightly more probable than zeroes. It's not
* important here, though.
*/
static unsigned int random_value = 1;
static unsigned int random_stream = 0;
static int
randombits(int bits)
{
int result;
if (random_stream < (1U << bits)) {
random_value *= 1082527;
random_stream = random_value;
}
result = random_stream & ((1<<bits)-1);
random_stream >>= bits;
return result;
}
/* Insert a new node into the tree.
(*root) is modified to point to the new root. */
void
RotatingTree_Add(rotating_node_t **root, rotating_node_t *node)
{
while (*root != NULL) {
if (KEY_LOWER_THAN(node->key, (*root)->key))
root = &((*root)->left);
else
root = &((*root)->right);
}
node->left = NULL;
node->right = NULL;
*root = node;
}
/* Locate the node with the given key. This is the most complicated
function because it occasionally rebalances the tree to move the
resulting node closer to the root. */
rotating_node_t *
RotatingTree_Get(rotating_node_t **root, void *key)
{
if (randombits(3) != 4) {
/* Fast path, no rebalancing */
rotating_node_t *node = *root;
while (node != NULL) {
if (node->key == key)
return node;
if (KEY_LOWER_THAN(key, node->key))
node = node->left;
else
node = node->right;
}
return NULL;
}
else {
rotating_node_t **pnode = root;
rotating_node_t *node = *pnode;
rotating_node_t *next;
int rotate;
if (node == NULL)
return NULL;
while (1) {
if (node->key == key)
return node;
rotate = !randombits(1);
if (KEY_LOWER_THAN(key, node->key)) {
next = node->left;
if (next == NULL)
return NULL;
if (rotate) {
node->left = next->right;
next->right = node;
*pnode = next;
}
else
pnode = &(node->left);
}
else {
next = node->right;
if (next == NULL)
return NULL;
if (rotate) {
node->right = next->left;
next->left = node;
*pnode = next;
}
else
pnode = &(node->right);
}
node = next;
}
}
}
/* Enumerate all nodes in the tree. The callback enumfn() should return
zero to continue the enumeration, or non-zero to interrupt it.
A non-zero value is directly returned by RotatingTree_Enum(). */
int
RotatingTree_Enum(rotating_node_t *root, rotating_tree_enum_fn enumfn,
void *arg)
{
int result;
rotating_node_t *node;
while (root != NULL) {
result = RotatingTree_Enum(root->left, enumfn, arg);
if (result != 0) return result;
node = root->right;
result = enumfn(root, arg);
if (result != 0) return result;
root = node;
}
return 0;
}