113498266Sopenharmony_ci/*************************************************************************** 213498266Sopenharmony_ci * _ _ ____ _ 313498266Sopenharmony_ci * Project ___| | | | _ \| | 413498266Sopenharmony_ci * / __| | | | |_) | | 513498266Sopenharmony_ci * | (__| |_| | _ <| |___ 613498266Sopenharmony_ci * \___|\___/|_| \_\_____| 713498266Sopenharmony_ci * 813498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 913498266Sopenharmony_ci * 1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which 1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms 1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html. 1313498266Sopenharmony_ci * 1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell 1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is 1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file. 1713498266Sopenharmony_ci * 1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 1913498266Sopenharmony_ci * KIND, either express or implied. 2013498266Sopenharmony_ci * 2113498266Sopenharmony_ci * SPDX-License-Identifier: curl 2213498266Sopenharmony_ci * 2313498266Sopenharmony_ci ***************************************************************************/ 2413498266Sopenharmony_ci#include "curlcheck.h" 2513498266Sopenharmony_ci 2613498266Sopenharmony_ci#include "splay.h" 2713498266Sopenharmony_ci#include "warnless.h" 2813498266Sopenharmony_ci 2913498266Sopenharmony_ci 3013498266Sopenharmony_cistatic CURLcode unit_setup(void) 3113498266Sopenharmony_ci{ 3213498266Sopenharmony_ci return CURLE_OK; 3313498266Sopenharmony_ci} 3413498266Sopenharmony_ci 3513498266Sopenharmony_cistatic void unit_stop(void) 3613498266Sopenharmony_ci{ 3713498266Sopenharmony_ci 3813498266Sopenharmony_ci} 3913498266Sopenharmony_ci 4013498266Sopenharmony_cistatic void splayprint(struct Curl_tree *t, int d, char output) 4113498266Sopenharmony_ci{ 4213498266Sopenharmony_ci struct Curl_tree *node; 4313498266Sopenharmony_ci int i; 4413498266Sopenharmony_ci int count; 4513498266Sopenharmony_ci if(!t) 4613498266Sopenharmony_ci return; 4713498266Sopenharmony_ci 4813498266Sopenharmony_ci splayprint(t->larger, d + 1, output); 4913498266Sopenharmony_ci for(i = 0; i<d; i++) 5013498266Sopenharmony_ci if(output) 5113498266Sopenharmony_ci printf(" "); 5213498266Sopenharmony_ci 5313498266Sopenharmony_ci if(output) { 5413498266Sopenharmony_ci printf("%ld.%ld[%d]", (long)t->key.tv_sec, 5513498266Sopenharmony_ci (long)t->key.tv_usec, i); 5613498266Sopenharmony_ci } 5713498266Sopenharmony_ci 5813498266Sopenharmony_ci for(count = 0, node = t->samen; node != t; node = node->samen, count++) 5913498266Sopenharmony_ci ; 6013498266Sopenharmony_ci 6113498266Sopenharmony_ci if(output) { 6213498266Sopenharmony_ci if(count) 6313498266Sopenharmony_ci printf(" [%d more]\n", count); 6413498266Sopenharmony_ci else 6513498266Sopenharmony_ci printf("\n"); 6613498266Sopenharmony_ci } 6713498266Sopenharmony_ci 6813498266Sopenharmony_ci splayprint(t->smaller, d + 1, output); 6913498266Sopenharmony_ci} 7013498266Sopenharmony_ci 7113498266Sopenharmony_ciUNITTEST_START 7213498266Sopenharmony_ci 7313498266Sopenharmony_ci/* number of nodes to add to the splay tree */ 7413498266Sopenharmony_ci#define NUM_NODES 50 7513498266Sopenharmony_ci 7613498266Sopenharmony_ci struct Curl_tree *root, *removed; 7713498266Sopenharmony_ci struct Curl_tree nodes[NUM_NODES*3]; 7813498266Sopenharmony_ci size_t storage[NUM_NODES*3]; 7913498266Sopenharmony_ci int rc; 8013498266Sopenharmony_ci int i, j; 8113498266Sopenharmony_ci struct curltime tv_now = {0, 0}; 8213498266Sopenharmony_ci root = NULL; /* the empty tree */ 8313498266Sopenharmony_ci 8413498266Sopenharmony_ci /* add nodes */ 8513498266Sopenharmony_ci for(i = 0; i < NUM_NODES; i++) { 8613498266Sopenharmony_ci struct curltime key; 8713498266Sopenharmony_ci 8813498266Sopenharmony_ci key.tv_sec = 0; 8913498266Sopenharmony_ci key.tv_usec = (541*i)%1023; 9013498266Sopenharmony_ci storage[i] = key.tv_usec; 9113498266Sopenharmony_ci nodes[i].payload = &storage[i]; 9213498266Sopenharmony_ci root = Curl_splayinsert(key, root, &nodes[i]); 9313498266Sopenharmony_ci } 9413498266Sopenharmony_ci 9513498266Sopenharmony_ci puts("Result:"); 9613498266Sopenharmony_ci splayprint(root, 0, 1); 9713498266Sopenharmony_ci 9813498266Sopenharmony_ci for(i = 0; i < NUM_NODES; i++) { 9913498266Sopenharmony_ci int rem = (i + 7)%NUM_NODES; 10013498266Sopenharmony_ci printf("Tree look:\n"); 10113498266Sopenharmony_ci splayprint(root, 0, 1); 10213498266Sopenharmony_ci printf("remove pointer %d, payload %zu\n", rem, 10313498266Sopenharmony_ci *(size_t *)nodes[rem].payload); 10413498266Sopenharmony_ci rc = Curl_splayremove(root, &nodes[rem], &root); 10513498266Sopenharmony_ci if(rc) { 10613498266Sopenharmony_ci /* failed! */ 10713498266Sopenharmony_ci printf("remove %d failed!\n", rem); 10813498266Sopenharmony_ci fail("remove"); 10913498266Sopenharmony_ci } 11013498266Sopenharmony_ci } 11113498266Sopenharmony_ci 11213498266Sopenharmony_ci fail_unless(root == NULL, "tree not empty after removing all nodes"); 11313498266Sopenharmony_ci 11413498266Sopenharmony_ci /* rebuild tree */ 11513498266Sopenharmony_ci for(i = 0; i < NUM_NODES; i++) { 11613498266Sopenharmony_ci struct curltime key; 11713498266Sopenharmony_ci 11813498266Sopenharmony_ci key.tv_sec = 0; 11913498266Sopenharmony_ci key.tv_usec = (541*i)%1023; 12013498266Sopenharmony_ci 12113498266Sopenharmony_ci /* add some nodes with the same key */ 12213498266Sopenharmony_ci for(j = 0; j <= i % 3; j++) { 12313498266Sopenharmony_ci storage[i * 3 + j] = key.tv_usec*10 + j; 12413498266Sopenharmony_ci nodes[i * 3 + j].payload = &storage[i * 3 + j]; 12513498266Sopenharmony_ci root = Curl_splayinsert(key, root, &nodes[i * 3 + j]); 12613498266Sopenharmony_ci } 12713498266Sopenharmony_ci } 12813498266Sopenharmony_ci 12913498266Sopenharmony_ci removed = NULL; 13013498266Sopenharmony_ci for(i = 0; i <= 1100; i += 100) { 13113498266Sopenharmony_ci printf("Removing nodes not larger than %d\n", i); 13213498266Sopenharmony_ci tv_now.tv_usec = i; 13313498266Sopenharmony_ci root = Curl_splaygetbest(tv_now, root, &removed); 13413498266Sopenharmony_ci while(removed) { 13513498266Sopenharmony_ci printf("removed payload %zu[%zu]\n", 13613498266Sopenharmony_ci (*(size_t *)removed->payload) / 10, 13713498266Sopenharmony_ci (*(size_t *)removed->payload) % 10); 13813498266Sopenharmony_ci root = Curl_splaygetbest(tv_now, root, &removed); 13913498266Sopenharmony_ci } 14013498266Sopenharmony_ci } 14113498266Sopenharmony_ci 14213498266Sopenharmony_ci fail_unless(root == NULL, "tree not empty when it should be"); 14313498266Sopenharmony_ci 14413498266Sopenharmony_ciUNITTEST_STOP 145