├── GNUmakefile ├── Makefile ├── README ├── critbit-test-data.h ├── critbit-test-rb.h ├── critbit-test-tree.h ├── critbit-test.c ├── critbit.c └── critbit.h /GNUmakefile: -------------------------------------------------------------------------------- 1 | CFLAGS:= -std=gnu99 -Wall -Wno-unused -fno-strict-aliasing -g -I. 2 | 3 | TARGETS:= critbit-test 4 | 5 | all: ${TARGETS} 6 | 7 | .PHONY: clean 8 | clean: 9 | rm -f ${TARGETS} 10 | 11 | critbit-test: critbit.c critbit.h critbit-test.c 12 | ${CC} ${CFLAGS} -o $@ $(filter %.c,$^) 13 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PROG= critbit-test 2 | SRCS= critbit.c critbit.h critbit-test.c 3 | 4 | DEBUG_FLAGS=-g 5 | WARNS=6 6 | 7 | NO_MAN= 8 | 9 | .include 10 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Crit-bit tree 2 | 3 | http://cr.yp.to/critbit.html 4 | https://github.com/agl/critbit 5 | 6 | Original code is taken from Dan Bernstein's qhasm. Adam Langley's CWEB sources 7 | were converted to human parsable C adding easy to use interface for string, 8 | buffer and integer keys. 9 | 10 | This code, like Prof. Bernstein's original code, is released into the public 11 | domain. 12 | -------------------------------------------------------------------------------- /critbit-test-data.h: -------------------------------------------------------------------------------- 1 | const char *test_data[] = { 2 | "wheshivGowghisheex)", 3 | "noibbeDyrumvoteecig}", 4 | "firtyis", 5 | "EfElRagsujemphIb~", 6 | "AyWev", 7 | "RotUv", 8 | "OctilGanUkKoj", 9 | "NikJeizjoTyitVejmo", 10 | "GadsocdojVenlo", 11 | "Jiwrodaithquek_", 12 | "rajWiaHiUgMytyurEcha", 13 | "frebdaz^", 14 | "Dipipcys", 15 | "Knukfa", 16 | "TeevtybtynovGo", 17 | "SavFiawkacga", 18 | "dulRugEt", 19 | "jawyimsyujak0", 20 | "taHiHifaycsim2", 21 | "Ug5SetkouffOmpAtbye", 22 | "leumheitcoHay", 23 | "HauvdeuptIndOo", 24 | "rigetogdior", 25 | "netEjren", 26 | "wubEgzy", 27 | "oawb5", 28 | "peishcon", 29 | "ShanBiOghuedjo", 30 | "voirf", 31 | "najCyreGhautgoucNu", 32 | "CejOkByxUshcithGiect", 33 | "Cushyuk", 34 | "obsum+", 35 | "cicsigVodOotJidKinow", 36 | "oagg-", 37 | "tranbi", 38 | "VefAr7old", 39 | "DoymWotMimomkiHyov", 40 | "ninExrotAmdum", 41 | "GuerIckCodVel", 42 | "IajPaned", 43 | "AjcicogtibMoog|", 44 | "wajejya", 45 | "dicguwea", 46 | "KnawpUzgeek\"", 47 | "RinkeuvagBaucUv<", 48 | "cofcoGrojya", 49 | "SeinWeo", 50 | "UjIkJeyd", 51 | "quoyctEyldic", 52 | "ejkudjewHalb", 53 | "lautDydnewdIfEr", 54 | "viagOwOsk&", 55 | "gazyoax3", 56 | "owoicebviethnoik", 57 | "RedcyobmirOdojRaffoc", 58 | "PloGriptickdeHa", 59 | "KidtoiHazPi", 60 | "byftyornIb", 61 | "NethNeb[", 62 | "vebamajBashtOz", 63 | "PaHuReOthFigg", 64 | "yiGreitjicFifeert", 65 | "KevFom#", 66 | "RuthjetOisAphorthUv!", 67 | "GuHup", 68 | "weHimya", 69 | "crodWoc", 70 | "Nepbyn2", 71 | "WofOdfeanHikBir", 72 | "migidwoilWenOk", 73 | "3fredBecOawbUs", 74 | "ricEvtobmid6", 75 | "Fes>opOfeftojIsturl", 76 | "fownyinhabOph,", 77 | "yidpyfsEdgu", 78 | "Fayshuec3", 79 | "BebgarjOf", 80 | "Dierfom4", 81 | "udHyfruOkronn0", 82 | "2Swet0", 83 | "becob", 84 | "GrygciWosBufAsya", 85 | "HyewAd`", 86 | "OjNifWaw9", 87 | "dyikub", 88 | "cartergyolt", 89 | "gerk>On\\", 90 | "wytfawv;", 91 | "TraivyovkofIgyeiff", 92 | "sledemDuad", 93 | "ClaHajBighCouzsern", 94 | "UtEptAbr9", 95 | "VoiptIkothTan8", 96 | "aydJocCir", 97 | "fusdityoghap", 98 | "Cishked4MubCeakimyim", 99 | "iteectEsDakDotLauc", 100 | "EabdidMos", 101 | "cofmoyppyotyue", 102 | "EredHucjeopdib", 103 | "drelCu", 104 | "Kehis", 105 | "JeatNaspon", 106 | "tools", 107 | "eydHoquewnof", 108 | "TawlojimWu", 109 | "BotColniHyShib,", 110 | "Tovufvabco", 111 | "UpetpodPeciabFilk", 112 | "ryebyov", 113 | "Nudkevchu", 114 | "Hir4Ov", 115 | "thrappArpAk", 116 | "luedMourOc", 117 | "Teup2", 118 | "NewHicfig", 119 | "ryinOf$", 120 | "VeorvAn9", 121 | "lyts)", 122 | "lugUpyacNefAtyemFiaz", 123 | "Barg{", 124 | "yodifAdNeoshgeticav!", 125 | "tepyipetgu", 126 | "awmIvIdifguk", 127 | "powkyid4", 128 | "neosojLabVepaik7Jub", 129 | "odwik", 130 | "swirUzvapquep5Quo", 131 | "GefCu", 132 | "wehab", 133 | "yathajCukTemEdLa", 134 | "EetsyunOsAyhyn", 135 | "MonOoHedAcGic", 136 | "VicshaimEj>", 137 | "DashtEcUp<", 138 | "acnidboowwiv", 139 | "oujMonria", 140 | "Oytee", 141 | "idchoHoshcyRu", 142 | "LinOoquewdyideycsod0", 143 | "yikDy", 144 | "wukMadmapOm<", 145 | "yaifyeervEjpot", 146 | "KanthEi", 147 | "WakpopJilNeemFeig", 148 | "LytLilforshyeasZuor", 149 | "edUzcibif", 150 | "TylfAdFo", 151 | "anOdOudPeebyatyilv-", 152 | "tavCuwed7", 153 | "SucjiJalrucich2", 154 | "GoyctyanCovBaptArn", 155 | "biSlarepOiHojMyb", 156 | "utMackuishkort", 157 | "AynpicbamFiOjTidBoc", 158 | "IkBinjivUsAthkew", 159 | "WysIajTob", 160 | "fihevVu", 161 | "Ejhon", 162 | "lettUfniOlyu", 163 | "pibr^", 164 | "ShmalWolRagnorf}", 165 | "iawyil", 166 | "dosAigJeekshiatIb", 167 | "Bavig", 168 | "swalvidwuwred", 169 | "Gewugdyidjumvo", 170 | "kojTeirp9", 171 | "fevImserj:oceskaj", 172 | "lifOzwokheyp(", 173 | "doutphArdocHal8", 174 | "BliQuairdOoBy", 175 | "DaulrauriphgimUp3", 176 | "Tocca", 177 | "dolmyaivmyecsirv", 178 | "yetcofipkardout", 179 | "woagIljArb", 180 | "Oaggacew7", 181 | "RiejyeOtdig", 182 | "yifEo", 183 | "AddosFidFienvo", 184 | "mofWudCush", 185 | "Cockoccye", 186 | "regTeckShoomBocga", 187 | "udwaHybTuAnFamOstOb{", 188 | "eimforashboum", 189 | "CeyHeeghiv0", 190 | "whiaggIanjeewgadId", 191 | "CurvibcifyecorpingUs", 192 | "hildOjBa", 193 | "vebcasyeirzOrOshCeHu", 194 | "EnsyepnabUg2", 195 | "fecOrt0", 196 | "cheynRoshk*", 197 | "mabOctednev5", 198 | "GengAdsOrArvoforn", 199 | "igdorbUctur", 200 | "FeesUbjuv", 201 | "Je*Driurretbech", 202 | "niKrios`", 203 | "CralowjodtucJit", 204 | "AphgheHuviled.", 205 | "]FrovkudifdarpUvoos", 206 | "guhuethays", 207 | "snoglir", 208 | "ciefWya", 209 | "CacsIsjeevetUnQuiWy", 210 | "cyofwyk", 211 | "gick!quelidEk", 212 | "babjapGod", 213 | "daHicyoodJi", 214 | "Renva", 215 | "BoquoiHebyaubbivwyp", 216 | "Phretceidegejbinn@", 217 | "irgevroitocUvyon", 218 | "yicCak1swejEi", 219 | "&twecCedjawrarlyi", 220 | "diOdiffi", 221 | "Whepref", 222 | "yuotonrir7", 223 | "Whawf1", 224 | "liggaifMijOun#oxIv", 225 | "bacguwrohoc", 226 | "dixetKilrevwojOsHayd", 227 | "EvpaduvmabOym", 228 | "ItyeTa", 229 | "TwyadsIj", 230 | "wryagyashkyiv", 231 | "NufUv", 232 | "pepEdsad", 233 | "neocojMarvyadBodnod", 234 | "evpobcymbur", 235 | "IkUtitNiddojNehom", 236 | "DeavAdfottIgyut<", 237 | "CekyokkowxawCimvim5", 238 | "grothpyugwi", 239 | "WresEaf", 240 | "rinthAsbujedLu", 241 | "GresOc", 242 | "denRapsEdBodUdsagg", 243 | "jagoynsofPacfoj}", 244 | "GagbicEudditni", 245 | "ThaffUnren", 246 | "leimIbBeOdCabishAw", 247 | "Oirpafanirs>", 248 | "gitduvew", 249 | "biovoibgedath", 250 | "EerrocDycsupAifs", 251 | "RiSwops", 252 | "EdWacjuWob", 253 | "quifOs", 254 | "ubAdIdAnFirc", 255 | "FeObbavAjKeygNuorv", 256 | "ErsyuqueHykPeu", 257 | "rojRu", 258 | "Noct5", 259 | "yaiksixag_", 260 | "gicHek", 261 | "KuegIkmoccicEnej3", 262 | "4okgonAphOkquitCi", 263 | "OocainexnibMoct", 264 | "Utyic", 265 | "egCymbocshijItBac", 266 | "ivgekurdElUkVeynd", 267 | "obsyeapNibCid>", 268 | "dydLefCebPoajpan", 269 | "yeepkuAm", 270 | "skisAdpadVafvek.", 271 | "MicnopCogHeOnJaQueid", 272 | "obryesadZugBatCi", 273 | "LosIfGod", 274 | "yaddicEwhyobNisvu", 275 | "VovfedkubsEequis", 276 | "tweycsijId(", 277 | "LowupMov", 278 | "podyenenjothatLushby", 279 | "nasOvHidGewim3", 280 | "waifPyzUbJeo", 281 | "rofkapWotvaitshUg", 282 | "LicOjIvyagOwlaptaif", 283 | "uthnoanabear", 284 | "pyFrimOdsiavQuo", 285 | "BlykIn", 286 | "shmufdakeim5", 287 | "epsAi", 288 | "VacRotOc", 289 | "pilKar", 290 | "dodfebyocjialyoikop", 291 | "KnidIgmufwalpya", 292 | "DebhyljojVadcaicfac{", 293 | "valcargheneudOvByash", 294 | "VifKupMeyppeirya", 295 | "wubbuheavVuKnayg", 296 | "tryaggawtAnEfekkec9", 297 | "IdneynneaphFod?", 298 | "udeenkyalNutyebNirut", 299 | "beyRutwyWicIrojketh7", 300 | "ayGhivAnyie", 301 | "kiryejcofpolp\"", 302 | "nidoo", 303 | "LaltoocJanyie", 304 | "bianryRerryemt", 305 | "vanvugsUcbudMonk", 306 | "filOsh7", 307 | "pomNacEwkAcViWykdok", 308 | "WyimpImnecOj", 309 | "TeOtebheyplun", 310 | "JadmutBirawgoypInJeb", 311 | "IsViesyefDapdikFoo", 312 | "yeshly", 313 | "guItveyHeurt", 314 | "kekowpIk", 315 | "DootGiQueghopinn8ac+", 316 | "IgNoilRevryb", 317 | "lumUkio", 318 | "Udyodfeymthoik", 319 | "TunIv0", 320 | "dedsAwgeigsyeo", 321 | "Neusog6", 322 | "Nipatyo", 323 | "AjWyEng", 324 | "ShlannAfnafeyhiv]", 325 | "keHamIa", 326 | "GijlullEnirfacoak,", 327 | "dryFlag", 328 | "EtBajOfyefCocyorkug", 329 | "Mapt|ochcojobnay", 330 | "4Blufrya", 331 | "simLaxRorz%", 332 | "WeshWyaw", 333 | "ajNekaid-", 334 | "TyeljUbudmoifPef", 335 | "Lutact", 336 | "Owovye", 337 | "vaggAdgozesDo", 338 | "HosEt5", 339 | "necogsejUnHask_", 340 | "foagries21knazKov{", 341 | "WyhaHophauphiv1", 342 | "geitpyo", 343 | "onyueHuocNeArkAfMi", 344 | "MytsulQuakejyaipVet}", 345 | "joSwugsUbga", 346 | "leersElsopty", 347 | "bitUcethOzhai", 348 | "icdeph", 349 | "asvobr", 350 | "shiOsyuf", 351 | "ijHoyRafjalb5", 352 | "Jep7ogchymdoa", 353 | "DurloovKiOdWabpo", 354 | "AnHavvinafOok", 355 | "OkciweltAifRo", 356 | "wurcUrGoibfuj1", 357 | "azatByctunmyip'", 358 | "LalgagojbypAnd", 359 | "figfemonph", 360 | "yidNig1", 361 | "PrinyesElyed", 362 | "vubthofyonidonhacFav", 363 | "norbudbivriAvShey", 364 | "CyWijAfVu", 365 | "EvVamcyochtythessOc", 366 | "tectaHynEanes7", 367 | "OodOykibAfvujUv", 368 | "klothgivpooldya", 369 | "bahertofye", 370 | "RuheffidMeofGhont", 371 | "watbinRycs\"Twok", 372 | "AjVocbingib", 373 | "AcbejauftOaccaj", 374 | "fleOwOomHoyg0", 375 | "jobImWajWof`", 376 | "ebtouwecfednians8", 377 | "NisjobowCee", 378 | "BubzyxguIt", 379 | "Mipfep<", 380 | "undecsodsacteshga", 381 | "JiHanejShujamGheng", 382 | "UrbAcwetMytNokku", 383 | "lonAutt8", 384 | "giFrityin", 385 | "Kircyu", 386 | "IcNiktiesBu", 387 | "asJofImordEtyo", 388 | "EppEtitnif", 389 | "irOoHiad", 390 | "PanFeang", 391 | "HydUchagMenbeHeccaf", 392 | "yoipRyg", 393 | "JiudNacDyomgabSaf", 394 | "yasfoptEbun", 395 | "TiajRecarHendyobr", 396 | "yabKu", 397 | "EnHetId", 398 | "5OwHimWugog", 399 | "RiemkapsyemJajmoj", 400 | "Wamt{", 401 | "egNijCyhyfyedro", 402 | "Batkim1", 403 | "eysEidVeskea", 404 | "LeepNog#", 405 | "ibhiasFoyshtatGa", 406 | "acNejcapt", 407 | "Biewch:", 408 | "eucIgpa", 409 | "urjAn", 410 | "LiptUch", 411 | "BanyivPiamitdilAtNo", 412 | "jilEtDawCyfheOd[", 413 | "ApEnardyibvirursh6", 414 | "Anhyegg:", 415 | "shnuSibFoysAwyous,", 416 | "tanVigrappyadbetag@", 417 | "nospErc&", 418 | "traldyibOug", 419 | "Meidquicdamyilzow", 420 | "Grersuv", 421 | "dreKaHomLidam6Ov;", 422 | "FacksOa", 423 | "satIkappyoj&", 424 | "SkyRyg>", 425 | "InacUtsAcWetTonyoum", 426 | "Uthedhaj", 427 | "smytDaldOwlyer", 428 | "canendufdef8", 429 | "craggOacshindidNoy", 430 | "vaydOlnisOyds", 431 | "idBydIdkirHuf", 432 | "EwGhomjader", 433 | "endyoi", 434 | "Betcee", 435 | "ceblekOckrithedIksAf", 436 | "hoheGrejNijRu", 437 | "Povjonlu", 438 | "PryidEcPhadOpJoig<", 439 | "CiowcasJoy", 440 | "WodNoifci", 441 | "donviehesyond{", 442 | "rist5owas{", 443 | "aujFaveaj1knenkEv", 444 | "EsthobtoxyebkukVu", 445 | "huAsIcawtUjpo", 446 | "goshyewkajNondIc", 447 | "crowvye", 448 | "axosOlQueenyead@", 449 | "PirryimnaspIjajOit", 450 | "runBif2", 451 | "aynukto", 452 | "Mos&Twell'", 453 | "bawginarUksawvirtAb", 454 | "dreetvoog9", 455 | "Kaunrorad", 456 | "codsyickEutBisVoHik3", 457 | "Vehar+", 458 | "ranvens", 459 | "GourkilUd'Ogneamt", 460 | "cyghilerbyodJifCirl,", 461 | "uxDygdyResyiecgolt@", 462 | "thuel9Ajhis", 463 | "cugBuchCy", 464 | "UkFawoad-Gripyk", 465 | "IdVapyotEe", 466 | "geytgieboy", 467 | "MiavmesoucOvCybvevar", 468 | "clonWopir", 469 | "cecpifeiven!", 470 | "akVuromyecKa", 471 | "ajMunfumEylf7Wokye", 472 | "5ogwibrOug", 473 | "Needd2", 474 | "paycseuct", 475 | "doishSeikcoog0", 476 | "LipBurjAchHorervyig", 477 | "OosOdVikya", 478 | "plojhikyeicterdopp", 479 | "Lenped", 480 | "yitch", 481 | "CoajaskesgoogNeg", 482 | "fiphanIpoyktya", 483 | "sodinjocWyubs", 484 | "yadkiUpDim", 485 | "EwsOlrutbokvedFoc", 486 | "FrotaphJinoitvilye", 487 | "noygadfi", 488 | "geckwynic5", 489 | "TrantorIc", 490 | "drosFoshtoav", 491 | "bipvalCo", 492 | "derWegnedoiktetKiff", 493 | "CetJercabfuft(", 494 | "OigIcye", 495 | "TridibGotCu", 496 | "BifchedweivKedQuas", 497 | "neifnuewfEbditNatRug", 498 | "GeurzopBand", 499 | "krogdutMeyrocNee", 500 | "KerjEurumfifDiav}", 501 | "UdneaHicijSibtav)", 502 | "naibwukTofoc", 503 | "OsockasFid0", 504 | "soyryfsoinpie", 505 | "temgak", 506 | "kawk8", 507 | "wocev7", 508 | "tydHyesghet0", 509 | "ubAfChuj1", 510 | "awHickHoytduthEk", 511 | "GimimHiopNoawap|", 512 | "opJodJert", 513 | "guemtyiafogUgdo", 514 | "HoFladsik", 515 | "5Dyri", 516 | "Knap4", 517 | "ukWoadVorIa", 518 | "odCuIdWa", 519 | "BohosbuewfInritOk", 520 | "RolceiTwocfucVu", 521 | "nedAkJoc", 522 | "TimyaifWo", 523 | "VahitVekhobBanen", 524 | "BlagWicyexCyrith1", 525 | "coixaj7SwerHivVugJi", 526 | "skyrieksak", 527 | "bocreo", 528 | "EcixHotyirAkdyen", 529 | "IkEpwovfiebVafIa", 530 | "foiFit", 531 | "EpWudr", 532 | "WugujBepyodfirfacfek", 533 | "nadAfeapiterhiepMeif", 534 | "yeadziHissyeil", 535 | "HuvByffubAvIgpye", 536 | "goHyt/Quacnich$", 537 | "DiodLerErudkemran", 538 | "byovseubWalv9", 539 | "Sypkop~osjigmirdOc5", 540 | "mebdapNa", 541 | "cildAijivcob-", 542 | "mekCimetOk", 543 | "dreerudtitOptot", 544 | "jarvajyic?", 545 | "WejAjCu", 546 | "adojAcepHakyek3", 547 | "givIjbeal", 548 | "Preocyunred", 549 | "chisUbtyk", 550 | "julpyijCazOghids9", 551 | "diOdosbis", 552 | "MivlicklawAwv", 553 | "cuajeitPoar", 554 | "ivEbUkti", 555 | "FuzigNeadAyk", 556 | "DosBynZedWuasitsh$ja", 557 | "agictaiQuimoinHiat", 558 | "udwesOvewhekGia", 559 | "HetGa", 560 | "pittidCaj?", 561 | "arvOaxfoyrobTumosh", 562 | "wecEbrOwnyuIdnopDoog", 563 | "AbOtodcy", 564 | "nihokdanikTiamfuIjwo", 565 | "Hopdyzbeigvij", 566 | "yacsIxkujRi", 567 | "upFocWunn9", 568 | "Tytshockorg", 569 | "Goopnusit", 570 | "EtpapCemRucwoho", 571 | "8okOl", 572 | "sirWoodOlHy", 573 | "udoyFrokfubIv8", 574 | "fekdepp", 575 | "Ipnunsh2", 576 | "VidudawnUticCafuc4", 577 | "atOab'", 578 | "SyftiponJakogDib", 579 | "mecraynGheb6", 580 | "JuWadGi", 581 | "CenyilAmOabcej5", 582 | "boijpoic-", 583 | "zeth}ogjicMov1", 584 | "blactUb2", 585 | "NottApyaw5", 586 | "CronBazAgpifvosBa", 587 | "molurnupneiz", 588 | "yiecbi", 589 | "Catseryiajyat1", 590 | "snodgemBy", 591 | "witZenkigId4SwuKut", 592 | "kebEkajObcaytyHeaf", 593 | "CrorgAit", 594 | "neShreogwa", 595 | "pivZangevoxOn", 596 | "vumIrvag1", 597 | "EvNeol", 598 | "FocboagdotmipHyn", 599 | "neyttIvBicAygpa", 600 | "HyRemDaUkTums", 601 | "Nauvtown3quoa", 602 | "bicgolEpdeani", 603 | "iavyivmytefOxEtyaydd", 604 | "tihilfolusEk", 605 | "yamRewIfegwufufchir", 606 | "ganlaj8", 607 | "nuejyonkeggUnId", 608 | "JeghoowdAiclIbrEj", 609 | "dryursIfPysBeTwoj\"", 610 | "craHidyivVovGoon1", 611 | "Ushfeidrec", 612 | "ec.Ocheyg+", 613 | "CeWriwuikovUsDetan^", 614 | "DupsUnWyovadWupWov", 615 | "neirvofAdtuseb1", 616 | "gupJongAr", 617 | "buvCuojoodJij>", 618 | "RogMitMawMeyd", 619 | "SikEvkotDab", 620 | "GhiadFejkay", 621 | "AdHimutPhi", 622 | "evJuquadwadKenJur3", 623 | "FoddArugvib3", 624 | "FifPygbakTebs", 625 | "loquefbuShrekWyac", 626 | "VisOdd", 627 | "Loommit4", 628 | "CukFuewdIcOuKni", 629 | "furashtogebCephDet", 630 | "Geopyoym", 631 | "kreichUgHyWrixEnia", 632 | "EdCiPyukwavSuryo", 633 | "decnarcIaceijteam", 634 | "IcotDyflaibJuwan4", 635 | "lihatgakph*", 636 | "Whowyashtov:", 637 | "FlejVig6", 638 | "CiackNusDyim$", 639 | "GreypdypUcmivmu", 640 | "eeccajajheut", 641 | "ToalyidVev8", 642 | "cicteu", 643 | "deheyRelusbamGofs", 644 | "crenvijfoab", 645 | "knedyityeHeyn", 646 | "WreOvyic~Flepp?", 647 | "OapodJesh3Glo", 648 | "Ebdaukcat1", 649 | "OgOgPon", 650 | "voawwemGhic", 651 | "OuHek1", 652 | "lokMylbuc", 653 | "lalcavafdetak<", 654 | "WridIlibrArEewf&", 655 | "viawf|BlolRirya", 656 | "Goidim1", 657 | "wumacenVakVaijro", 658 | "SpoylvEkIfs", 659 | "EfDytboncilIdTo", 660 | "WharEmp", 661 | "nughyFrodhopEmpUbvi", 662 | "kevIashEgOjabzudbo", 663 | "AjMav6Cuph9", 664 | "EgJitCiddagudUg", 665 | "veddups", 666 | "Normebs", 667 | "wert0", 668 | "yeuslalnifKumnoav>", 669 | "nisejIkfubyey", 670 | "UdCebCotfoalEa", 671 | "istyam", 672 | "Pedid(", 673 | "cicAfJivgishtuptOk8", 674 | "nufyuhiocceupgog", 675 | "OckJetzatEzBo", 676 | "JajOricAfKop4", 677 | "latAf%", 678 | "Nac?Odyu", 679 | "vohou", 680 | "ShertOfIj", 681 | "FrobBebAiduvqueHet", 682 | "NogniUngEjIagau", 683 | "ubadtirbabcaiddUgOdd", 684 | "awpIvNojCatCetonzen", 685 | "Scorlaf", 686 | "rushipyeuHebhoacesk", 687 | "byikgackWid]FrieGher", 688 | "ThejatcegFihotKess\"", 689 | "outec7", 690 | "JoyHymficHishgarl6", 691 | "odegopNejAdIr", 692 | "FudvuipokKa", 693 | "grevrey", 694 | "JebVerhytNunof", 695 | "gheanloc", 696 | "yuejuc", 697 | "deadogTash0", 698 | "Isryct4", 699 | "deSwedTeijHojeghigs", 700 | "Dypsyej", 701 | "enGhenOt*", 702 | "bajabs5", 703 | "Mieweglyac0", 704 | "wiasAvlicGoff", 705 | "idyeaharjOckaphfiaj", 706 | "EbUdsojWocks", 707 | "FadNagepVewvIg", 708 | "AdDicyonAf&", 709 | "bicyijRir7", 710 | "kiWarfEmyuPajmas", 711 | "koujyiefIdto", 712 | "Vackreirillimyik;", 713 | "Jijpienfeghavcen", 714 | "JuhiphtojArpIpOcJev", 715 | "ViryajbogboGra", 716 | "vavqueybvunRijDoDraf", 717 | "yinifjoiv0", 718 | "OukGuWokcisca", 719 | "ocHarwyopJof", 720 | "JoihusjuexOuj7", 721 | "scejOvbadniv", 722 | "ScemEecigyu", 723 | "LuvCuikDufs", 724 | "HoshGucwukHuOrvavTyo", 725 | "jojFajIdefna", 726 | "TibTovhedJournObcet", 727 | "PigAnkOv=", 728 | "irtEbningibweg", 729 | "JafUddAtgajRetnai", 730 | "yabeiboors'", 731 | "ghedjumDycsOpIfKirs", 732 | "Mofkodraij", 733 | "CatMorUkebFocEdba", 734 | "FiMaw", 735 | "Cysk+OfcavDic", 736 | "guvFidouxHibOuj3", 737 | "Wynlealt", 738 | "piwamvusder", 739 | "nacbiefAwyoylm0", 740 | "ShwectecMy", 741 | "tajCads", 742 | "PooslalCanevJunoos", 743 | "LuBacawWa", 744 | "PindircEg", 745 | "ebalgAshistokFiLemm", 746 | "osFord,", 747 | "jintaiv1", 748 | "Tref&", 749 | "JooldirtOmRoHaj", 750 | "BiadUnOtJagCylkug", 751 | "ipgapOxRopwak/", 752 | "1DutulceSwyns", 753 | "bahoclafVejCucBij", 754 | "tysewabTapabvach", 755 | "onhobsEdHyrachKa", 756 | "gahivip", 757 | "Hijevbymjuluvyafow", 758 | "yughLep", 759 | "RuiphFooriakWas,", 760 | "OkvacAcefkaxyefuszio", 761 | "ruWrekweebijAvHok8", 762 | "dojdyp4OmAg", 763 | ",sloufDi", 764 | "TrawJavdu", 765 | "iskErcAfvirfyoigDa", 766 | "VapDesyevocfotItju", 767 | "Tuickacdeeb7", 768 | "VeHigtiHidLoceukboav", 769 | "MijAcOkkuced", 770 | "IjReot", 771 | "KoDratlo", 772 | "yujopFeghibJa", 773 | "tygMadNaubgasjul", 774 | "ecktejIttheusdydBi", 775 | "wenEbEbfotCu", 776 | "InomgimdyRevNift", 777 | "OajcolHuijDymyarEs", 778 | "uchut\"Ockatigap7quix", 779 | "gupepitpy", 780 | "moidfevnuppye", 781 | "WypyiarrUfKektug", 782 | "padeawmeal", 783 | "vigDaphodNiajUlsh", 784 | "WykMizujnirUtTid", 785 | "KiavRyk", 786 | "ushawyiacGehetep^", 787 | "AnnosbaifDissirmep", 788 | "hithAshdok1", 789 | "Iryum", 790 | "VuvlevDinnyarj>", 791 | "ednoHicKic", 792 | "Ducsobboo", 793 | "WrennendebJafol", 794 | "JochafAj>", 795 | "codJivNenVovGisJel", 796 | "newbUccaf6", 797 | "wabQueicta", 798 | "Fradser9", 799 | "kogh?DrobHenCarth3", 800 | "FejChetdoodaicbal4", 801 | "PixByethPifs", 802 | "dafhotwanziabWadAr", 803 | "RokAbVo", 804 | "eyljAjIn", 805 | "lorvekibac", 806 | "twowcurryuabnazEn8", 807 | "Hessecyipyov", 808 | "fadJodghowsEv", 809 | "CritNasFirIm", 810 | "KroHoonPidoapdod", 811 | "CebHyacbo", 812 | "keyFraytnoavViv", 813 | "IddeutKulk", 814 | "GliOffye", 815 | "ejocGotaksyup", 816 | "ujGhalyaJil", 817 | "ReadNep", 818 | "WreakHagCyrywedTa", 819 | "CravDonJosudBu", 820 | "^HandUfyeapjonRagAv", 821 | "thanVoovgoucDetGopon", 822 | "IgDorhef3", 823 | "emobgidefmifJajicni", 824 | "JaQuakjumrimpEaph8", 825 | "NadJashJeabryafUc4", 826 | "CrojdolgEf", 827 | "FawnEthyacyakZun5", 828 | "PyddabsabCyshmeQui", 829 | "beshCecs5oc2", 830 | "Vekoan", 831 | "woros]", 832 | "udAid@", 833 | "emwespitAk", 834 | "DouphUjto", 835 | "yuhynejtabtecbewf", 836 | "OtCiowAv", 837 | "JiveshOk", 838 | "rogijKoind", 839 | "cliocHyfficsInirm", 840 | "opbustEbrOgniWee", 841 | "RochupnepnoQuedd", 842 | "Ben^Omroj", 843 | "fevtojLue", 844 | "nafwocnoas3", 845 | "DryzpopDohoHak", 846 | "CovErim", 847 | "AwyirjajcoujEdFedd", 848 | "Kevvej", 849 | "taxDas", 850 | "BuvdegEjMi", 851 | "fafBion", 852 | "zeftucamcy", 853 | "umeckJean", 854 | "Ac2Kna", 855 | "gheisk6", 856 | "gheerk", 857 | "EcAt6", 858 | "Myavlyuryirn", 859 | "abTagduHujhowIb}", 860 | "poctev9", 861 | "TykvubsyuOj3", 862 | "EnciakApfa", 863 | "alomNurewonjeuc", 864 | "yijSundyeggodBavquoi", 865 | "7twekWyatCew2", 866 | "rybuf5", 867 | "TwasDehutNabni", 868 | "TrejSuth+", 869 | "BaigCicervopDifWiaj", 870 | "turmyatOgyelk\\", 871 | "ebdirIrf", 872 | "CedVoGryhubWygAuct", 873 | "IajnolciWu", 874 | "godVahouxeib2", 875 | "OcCeekCygipFilm", 876 | "rawrenk7", 877 | "nagDau", 878 | "buIckabacGa", 879 | "UvgugErgIlWuhanri", 880 | "bleebres:Quor", 881 | "ijhobr", 882 | "OckMoxcajAgyey", 883 | "DivJa", 884 | "quivCudWojIs", 885 | "Ingonyefexfelnu", 886 | "DecsojDojcakOtKogWy", 887 | "CheunenAtEsIkCo", 888 | "fiasisAykup&", 889 | "ClarmIloawbintApkib", 890 | "nertoaGrouc1", 891 | "BemGejigdamyoag", 892 | "quivtutVidruHossOt2", 893 | "FitDikUr", 894 | "tipt.", 895 | "GijenghaivEjnosGond", 896 | "owWuibvoundyookKicvo", 897 | "rakyuteagIcs2", 898 | "EikVu", 899 | "whimuc", 900 | "pi#queelufjaHastif|", 901 | "OpkewEwgAcjoyb", 902 | "KegCujogNiddUvobdo", 903 | "dargowCuOcOank\"odads", 904 | "CubNag4", 905 | "QuovSynryec", 906 | "Iawkess", 907 | "igTugsiss*Fra", 908 | "DeagBubEfsoimWugiv2", 909 | "Choctic/", 910 | "covdeaTidpainendOr", 911 | "piHerOwkatfedIdoo", 912 | "PiWann", 913 | "yaskEumkefUsGeinkaqu", 914 | "oirfaijCewHo", 915 | "SadWait", 916 | "ceasimVoytFu", 917 | "CecvavEe", 918 | "yirkEbUvCa", 919 | "Crisee", 920 | "meinkunCydhysOo", 921 | "vic8plezEwtyoFrickfa", 922 | "otOducEv", 923 | "swepovFebmyt0", 924 | "fiwutimgoakcubecThia", 925 | "Niowen", 926 | "Socnomar8", 927 | "FutNumya", 928 | "didfootyains:Fra", 929 | "jeft1", 930 | "essyu", 931 | "ojnoxcheutBeybJam\"", 932 | "hepsIb", 933 | "HythybrOkfoltya", 934 | "SamDycsEytnemtIcgec", 935 | "Aikopdef8", 936 | "lojAkOcOr", 937 | "quimp9", 938 | "secsEkya", 939 | "povLoinyashDafVivwy", 940 | "gawtItActagjor", 941 | "FilcunHampAbgonij", 942 | "yaHedfagIckRasghelg/", 943 | "eavyocsUddIlbewcak", 944 | "orsOa", 945 | "midrerUk>", 946 | "kacCotMidban", 947 | "loabjivucyeHuJa", 948 | "lypBeHeit", 949 | "wroKosarujomFiad", 950 | "risJovquak", 951 | "deejyoafVickyebOv?", 952 | "yeyryxfu", 953 | "oajAnujryatro", 954 | "Scansapp", 955 | "drauckIlt", 956 | "teloacOshk9", 957 | "larrias", 958 | "wicApCedZoccydVotjo", 959 | "paryamacHyac;", 960 | "Wisp0", 961 | "hefOwyelm", 962 | "egJoutvied", 963 | "pabuv:", 964 | "AzjiwriryotLam~", 965 | "tetHuedKetabiagHa", 966 | "phufovCojRij", 967 | "netdeesIr<", 968 | "UkwinevshugjerOj", 969 | "edsarcavOtIbub", 970 | "jefPoottebHuWaf.", 971 | "jimtEdBiUp0", 972 | "AchaddArrIther6", 973 | "Ipyij-", 974 | "yagVifPilshaydvis", 975 | "buhancit\"", 976 | "wepOft1QuigHea", 977 | "spofijwithomyaVet", 978 | "KnawckyiGryahackiwo", 979 | "ratdudBacweHai", 980 | "codGi", 981 | "OcutAxugCacyuefZugbi", 982 | "quebnoglaHit", 983 | "yadWytt", 984 | "Chruesfiajwijfaj", 985 | "jeltEvanyel", 986 | "Hipcit(", 987 | "Ingurf2", 988 | "WetObVerfankAi", 989 | "yedrob+", 990 | "yijNo", 991 | "yusVafAr", 992 | "heecpeDrezekBan=", 993 | "HoinjocFoibEymVo", 994 | "yuilvyarrOmboynsAk}", 995 | "jidag9otZaisyitcedd", 996 | "Doythok2", 997 | "vorlyogmerp4", 998 | "yeyworhaHoit", 999 | "evKecHojiacJap", 1000 | "vagnobBicdoHonaimRy", 1001 | "pylvEj", 1002 | "zwabUksa", 1003 | "Itpok", 1004 | "sutGinyac", 1005 | "FadtaisjaQuewnEcJif", 1006 | "BinyocZehi", 1007 | "Erdevserk&", 1008 | "Grovquehi", 1009 | "RafevsecnartAsedAb\"", 1010 | "FeanowsApDeadrigTyk", 1011 | "twaudou", 1012 | "youmtepyiv", 1013 | "munFeul,otnad", 1014 | ",fraHewf", 1015 | "treErsh", 1016 | "IlbAigoddyipyibsarz%", 1017 | "picJuxWalIgInPimim8", 1018 | "feHashyev", 1019 | "eabEcgotDu", 1020 | "mectOrjOdcygto", 1021 | "RynAupvegOmRuvtit1", 1022 | "hebyutGhoalv7writEts", 1023 | "ninHiockEnnovkuf7", 1024 | "vefbu", 1025 | "giudEdNi", 1026 | "KejdeichVogyauckmu", 1027 | "DycsinSegfiptOk", 1028 | "Renwodnovyawjaink", 1029 | "akEltEnk", 1030 | "cassyeOxiagCiaws", 1031 | "sheocThoorrIboketGie", 1032 | "bifJapJonra", 1033 | "Navyoph`", 1034 | "BytobModseejKorpimaw", 1035 | "wunbekunsij_", 1036 | "RocNi", 1037 | "elleexiac", 1038 | "CilelEdvolf]", 1039 | "doorf5", 1040 | "NabHogBykwekenyis2", 1041 | "RetOmm", 1042 | "PhiphAts", 1043 | "RurnoatfobEcphofs", 1044 | "yocKilylpEaput$", 1045 | "pacOts", 1046 | "jiep6Swu#ha", 1047 | "bi2Swodsyaslos", 1048 | "MatjunrelNupoyts", 1049 | "Akjuew", 1050 | "doihyitHathQuig", 1051 | "UcVeownIdFojDovric", 1052 | "klifhanEetBewAtCoc4", 1053 | "ekjap*", 1054 | "FreghajTa", 1055 | "bevEaHacsAdibya", 1056 | "DoobsItGiEnFebcyk", 1057 | "nueczuvAcJo", 1058 | "tygrib@", 1059 | "EkTisibrUmisItna", 1060 | "JekarchOts", 1061 | "HadyoffIsUf]", 1062 | "vidyicjicNovHirk", 1063 | "yeharkedUkKo", 1064 | "tafryopNifs6OwUc>", 1065 | "eepsyosEk0", 1066 | "creeth", 1067 | "Eps_quaybduggAi", 1068 | "Ghimnufdis", 1069 | "Knubboocsudotveu", 1070 | "VecthalshyubBo", 1071 | "NevugUtVod]", 1072 | "Vushwounupnem", 1073 | "paysnIcnu", 1074 | "KlecjegBynpea", 1075 | "icsecWarEbgachco", 1076 | "kockba", 1077 | "BoygjeOpnio", 1078 | "Jompyokhec", 1079 | "ChovShiubdegasaukid", 1080 | "DourvItMou", 1081 | "OgoogJeews8tygbycs", 1082 | "Uddyoha", 1083 | "thiFleckiOtFap,", 1084 | "CerhyapIj'Obag{", 1085 | "pyivacKicanbicevjeks", 1086 | "TyatJiOlv3wrey", 1087 | "BoanWiphhof", 1088 | "JaderrukUrAgdovogOs", 1089 | "bunisibgodBy", 1090 | "VohakDayg", 1091 | "jijNezgogAshAc6gralp", 1092 | "acvivkecgiltukvouhuc", 1093 | "iafagshyefgapIgav7", 1094 | "osyayReldem", 1095 | "JuenshogAy", 1096 | "AdLic", 1097 | "kuap3", 1098 | "jarmosVanbydsosbimm", 1099 | "yonpoavAsIt", 1100 | "Stan+ojoj", 1101 | "cloupyobwojruvtajMai", 1102 | "cukyudEygOrsUc\\", 1103 | "PrenBeonanFoussAkZo", 1104 | "4shluwyRicyemroubTu", 1105 | "erposhtOjMovEytvic", 1106 | "dogCotkatComyimBiahi", 1107 | "daygcer", 1108 | "ouhificGiats", 1109 | "lepyedreed5", 1110 | "CrodCoorHifDonut8", 1111 | "BatNivIkRespOtbio", 1112 | "SowfyiegNeyns8", 1113 | "idefgasaifyikTeb", 1114 | "HyRetFovHootetar", 1115 | "jiwafvuctUc1", 1116 | "bijVioldyagFatJef4", 1117 | "Getguk", 1118 | "OkabHeOddyekthogs2", 1119 | "Priojli", 1120 | "neiveduryafbyeSwom", 1121 | "CanupIsHushGiktur6", 1122 | "BokTyStedPelyenCye", 1123 | "norgutiltEmcealpEa", 1124 | "rhetzooGlavJivenyaHa", 1125 | "pagli", 1126 | "ivErIcJibockEpda", 1127 | "vibyattokVefsok", 1128 | "UryotJaptOfnipoap", 1129 | "6QuitDobomeubRic", 1130 | "whidPydnid'", 1131 | "Krisht", 1132 | "vedemKoltyif5", 1133 | "JipmytDityaifwobdig@", 1134 | "GrevEubhashcof9", 1135 | "afHirc2ogjag/", 1136 | "WinFuawbaseo", 1137 | "usUnmafDyp4quagfowv", 1138 | "euhoc&", 1139 | "gairtIlf", 1140 | "finnAbrAljyekBor3", 1141 | "MijOaph", 1142 | "knidJu", 1143 | "ojvatJafilNa", 1144 | "MymyarbOnFepp/ond", 1145 | "ClojeavNerdav3", 1146 | "Etoans@", 1147 | "Wosna", 1148 | "fiolAr", 1149 | "peavPecipGawkEgPyHy", 1150 | "BowfidBiater", 1151 | "Elujradsab", 1152 | "WonRokciv", 1153 | "tesworyugBosteckust", 1154 | "yigHis", 1155 | "ecdarhimghir", 1156 | "IpBocofivjoichDag-", 1157 | "osyidvodpip)", 1158 | "thotdymRuHo", 1159 | "elucmewio", 1160 | "FlacomOot=OckCett", 1161 | "yegdejhodPip", 1162 | "flavHut{", 1163 | "twetNa", 1164 | "UchadveekTiWie", 1165 | "Aygphivgou", 1166 | "LashJokOrtasbiervEu", 1167 | "ShidnavocNegJujPosau", 1168 | "crocs", 1169 | "hetAisJofjevoys-", 1170 | "ScelyebnifDiWosawEnn", 1171 | "DowpyipCakGadriccyri", 1172 | "jodFectyuWocOvdo", 1173 | "ridcawfaikVeol9", 1174 | "TafEnumAjvam", 1175 | "Kevoc", 1287 | "Rhivchy", 1288 | "Dayms", 1289 | "ikmee", 1290 | "krilpOtBuzt", 1291 | "Shicroigsemnib3", 1292 | "whonHujBal5", 1293 | "MyabmyovVek$", 1294 | "ubEfhadAidRo", 1295 | "gritkaddakDensidCac", 1296 | "KnyorpyamkaiftIgsuk", 1297 | "okUng,oc3", 1298 | "iphcyokpiotAcEc^", 1299 | "soxnuddyercesh;", 1300 | "bouWyctyoc4", 1301 | "Bedlydvo", 1302 | "ChrainOcwy", 1303 | "nothnadsyuGeit", 1304 | "myRurOygeemtAjlis\\", 1305 | "SoftOsDybMowedVis@", 1306 | "dyevJowvAphAb", 1307 | "mepnegaijutt^", 1308 | "CiEcks", 1309 | "Weutdog", 1310 | "DudTenAdUft]", 1311 | "ghem/", 1312 | "DroheHevjophaHig", 1313 | "Menorp", 1314 | "AkCouc", 1315 | "diVesot5", 1316 | "HeshyacOn0", 1317 | "joyltEp", 1318 | "NieHedheajQuikyewxef", 1319 | "SadejLoarg", 1320 | "pijoogOyns7", 1321 | "riFliafjapotFu", 1322 | "LykvapIth+", 1323 | "Danhavnet", 1324 | "abpojWitkugEedchovey", 1325 | "FithUb8", 1326 | "Rydhyllunalgobphid", 1327 | "NeizditLidMeoc", 1328 | "TriUdjajWobyinha", 1329 | "-twudneOtJujnac", 1330 | "kovdaf", 1331 | "lipdecgiOrmib9on", 1332 | "dafNeivcharWoncasp", 1333 | "UrshIl", 1334 | "attofnuWyitgelIn", 1335 | "GhirtItHypyijcyavgau", 1336 | "niawAlreutEp", 1337 | "OjBubecDoctyekEit", 1338 | "NakJudnahou", 1339 | "EgeacCobeuFrievJutap", 1340 | "rierdEehyelthEnd", 1341 | "myng5", 1342 | "awvEvNel", 1343 | "patcicjocEuksh", 1344 | "pacEemyecichdio", 1345 | "efyukhunVicyemRo", 1346 | "RoojreunIgDujyas;", 1347 | "ishIadjamral", 1348 | "IluvDegeesJogasIj", 1349 | "Mojdan", 1350 | "joirvughiflushvomt", 1351 | "vopryk", 1352 | "MedNawip6", 1353 | "nawcosivWatKoybEcJi", 1354 | "yokanIrWodta", 1355 | "UfaijthedAfospashUp-", 1356 | "CipCocnaijlukdo", 1357 | "keWitDoisfaydKecoul", 1358 | "dudjiel}", 1359 | "guWitFieksavyieHi", 1360 | "GattIf", 1361 | "ocPydFadunru", 1362 | "wejfilixot", 1363 | "hattEcEtJojCurduvcon", 1364 | "uv1quouff[", 1365 | "Nahefwup", 1366 | "Travyu", 1367 | "grysUthjoyk", 1368 | "BavelnekEbEshk!bla", 1369 | "byntowvEurcOuv.Of[", 1370 | "JuomrictevyeHacUm", 1371 | "codHu", 1372 | "EwUlodId4", 1373 | "IadtoufKu", 1374 | "yoacwo", 1375 | "IrdididjerbamcejCo", 1376 | "9ObgenHuIdva", 1377 | "hasJittopWap8", 1378 | "omtOs", 1379 | "CaHutJifmap8", 1380 | "idsaufhannowk", 1381 | "VarIdmag7", 1382 | "VoobawVigbytsetfu", 1383 | "femNejBibIcCiOc9", 1384 | "napechUbs8", 1385 | "tracdyenciFu", 1386 | "DyrabKusJo", 1387 | "IranUtt", 1388 | "dyraphboowAw9", 1389 | "RhoptItdogOvPyguv,", 1390 | "jaryorpEphBay", 1391 | "IsShemCy", 1392 | "daiWrytsics0", 1393 | "FucEjbesBu", 1394 | "Apidwo", 1395 | "Idas1", 1396 | "EcIanOvCukdugAuvsobs", 1397 | "erIkphevshecni", 1398 | "SheorkEpil1", 1399 | "KivDeshAs", 1400 | "javLepeng", 1401 | "Ligti", 1402 | "loctic", 1403 | "nawmibjeojEb", 1404 | "ecGegsIc_fremGha", 1405 | "emciapofhatJem", 1406 | "cinhemNijIldAdQuon", 1407 | "LintafthushGeph", 1408 | "mecbefnetnacots^", 1409 | "byct'", 1410 | "PievjotConzeo", 1411 | "deakWeutAynOckibrubr", 1412 | "meryoyhof", 1413 | "galwobcijfalzeij?", 1414 | "yeymgab", 1415 | "gradfassAvacUc9", 1416 | "derdyahytVunn@", 1417 | "LeUmDi", 1418 | "an6Dri", 1419 | "scogajyalNeynjib", 1420 | "weruAbvoocHict", 1421 | "ockheedat9", 1422 | "Repol4", 1423 | "AwowCip6od", 1424 | "mashGep8quan", 1425 | "Oc1ObwefGhoanOmdew1", 1426 | "yivPheOdTo", 1427 | "Wojrys\"Li", 1428 | "pibNa", 1429 | "clodJobthukfejKag", 1430 | "cadyis", 1431 | "tucafemGoijyom", 1432 | "ajwoybJiOrryij2", 1433 | "Fodvecos", 1434 | "nilCataydmoghEen[", 1435 | "nidcisk", 1436 | "wevViHaufiv8", 1437 | "yijerIcyimtEjLia", 1438 | "yeyffosdetManVotem", 1439 | "exkodFuchkaigWa", 1440 | "ikghoudVa", 1441 | "RigrartyenRiowwelner", 1442 | "NipKiavDebgupin'", 1443 | "howCahijbieduth2", 1444 | "fevEdseyHye", 1445 | "Frecdygmerirsyo", 1446 | "VufJi", 1447 | "FruljojEsGerlAfViJou", 1448 | "titIjOgIss", 1449 | "RawlifogDy", 1450 | "KredichFicesjocishfu", 1451 | "tiorucnagsodedwel", 1452 | "3grukneEdbee", 1453 | "FeochMajconByRec4", 1454 | "viskIvJan8", 1455 | "idpoctAc", 1456 | "yacEckpy", 1457 | "Erryew5Gruheik", 1458 | "8wropFidHomEa", 1459 | "dogferk%Blofrer", 1460 | "dek0Och", 1461 | "MombajTeytMas", 1462 | "BlyuvFulgicIn5Slos9", 1463 | "fumyoakvinjeinVowx", 1464 | "yejdoushk", 1465 | "Lohuj", 1466 | "PeambykotEpdeks<", 1467 | "crukWywachArs", 1468 | "RecHajwuexrihy", 1469 | "CeacKockhish3", 1470 | "mockco", 1471 | "vaivcybUj4", 1472 | "WecyimrettemunpoHap", 1473 | "slyrycs3", 1474 | "Tevdot", 1475 | "gaphKijujSepyuraudUm", 1476 | "CusnOyb8", 1477 | "RohajTipgucyerf", 1478 | "ShriajtabGilibgut", 1479 | "DykfejLijonjodot", 1480 | "IfJacOadsOcmuj", 1481 | "DajBayk", 1482 | "olHejAxBubPef", 1483 | "yeaduthOdsOdyetCeik", 1484 | "futTunMiccobEfya", 1485 | "yem>OfhuShreelixJow", 1486 | "neicHalbObEulEut+", 1487 | "BiJuheibsEkmazJo", 1488 | "agNonbyShynnOvye", 1489 | "TemMo", 1490 | "RyazFoGlubNaj1", 1491 | "fucJatabAmt", 1492 | "Froothkaxazmy", 1493 | "PhuvWenAjdofyo", 1494 | "yebTavGish", 1495 | "Racjabyusfalm#", 1496 | "jedigEjyelg", 1497 | "LipOadNokadEkoxEtEo", 1498 | "DyHiebWyp", 1499 | "UfIdyelgAwUrvye", 1500 | "KrerpofeckwyinFok", 1501 | "oomDiwawufcocsotBat9", 1502 | "KroubImtItt", 1503 | "EigIdku", 1504 | "duAmcubOlbajTycs1", 1505 | "TheHy", 1506 | "jivdecamgojmuvJag~", 1507 | "drojAfJivNer", 1508 | "mavSo", 1509 | "DavWefPhiheen2", 1510 | "LifGa", 1511 | "shelj", 1512 | "biBladGecUjnosVef9", 1513 | "ghaimKadvibli", 1514 | "dawJighigoyWerOuchya", 1515 | "etDofdabterAdelp0Oc0", 1516 | "apGefGukomobyitodpia", 1517 | "TyffEcHobcoaHadBi", 1518 | "lirc3", 1519 | "yuWoashsoot", 1520 | "dejojsabbuchoc", 1521 | "poksultafcendeun", 1522 | "jajmik", 1523 | "Coawghobtig", 1524 | "narikculol", 1525 | "pycheev", 1526 | "tocNob+", 1527 | "Rendau", 1528 | "WuvveriajAkEwsEtVa", 1529 | "VicetpiadAs^", 1530 | "VesArteax", 1531 | "AcEyg", 1532 | "TobGochAfim3", 1533 | "Tujreiv2QuoksUds", 1534 | "ot\\kniorcIabba", 1535 | "Akreindegbofewcaj", 1536 | "fryRopyuOcGovvix", 1537 | "wedorpidNec", 1538 | "UvHamreattufio", 1539 | "1ovdysopNoheFreitjev", 1540 | "emmyaHipUbWerfOv\\", 1541 | "JanjegVa", 1542 | "DroickOgjipNanciol9", 1543 | "TeTwokIr", 1544 | "yikurv", 1545 | "migAv[", 1546 | "evvishjubWiek6", 1547 | "Apgovudmivghek!", 1548 | "rigvedajoshBawl", 1549 | "spivyatka", 1550 | "EtCoy", 1551 | "jehulkobyam", 1552 | "JicHet8", 1553 | "NilCeufdalb", 1554 | "UggAigVourj(onph", 1555 | "gaHogFa", 1556 | "nulgyidnalcefs", 1557 | "yoymBiwegha", 1558 | "cithAkbecbarth#", 1559 | "HannIjFuigOt7", 1560 | "@Bleijdaufnegyonec", 1561 | "Avpodhyb8", 1562 | "toavyegbufbue", 1563 | "Fimfin]QuaidryelZasp", 1564 | "glavyoawckAv", 1565 | "CujcujyojungyaHabsyi", 1566 | "UdLecAfhixLidoicPa", 1567 | "fesdesh", 1568 | "glauquilj", 1569 | "EbwufGhad", 1570 | "ProvCiavVegEy", 1571 | "uforyunbicpet*", 1572 | "kojrydrynn", 1573 | "IavCuotmimcagg", 1574 | "suher?Quiewyaun0", 1575 | "motGidGinhacpi", 1576 | "HobHyham", 1577 | "abbogzatfem[", 1578 | "lygmon0", 1579 | "StyksuphIthMuvuObau", 1580 | "CravnotGucJue", 1581 | "netpyHeipirn@", 1582 | "JujBojdan", 1583 | "TomWiho", 1584 | "opidwotAkAv", 1585 | "VogTubhadbee", 1586 | "Slusp7", 1587 | "otbupSheenIpzin", 1588 | "AgMibfanJisdejos1", 1589 | "CewfeptEulfoathdowt;", 1590 | "odUdChad", 1591 | "lowmAgcutEnd;", 1592 | "EdLop6Ofij3", 1593 | "TuecobZugoacgigJef", 1594 | "UdwudWamt", 1595 | "CemEfGuitLinyefowEb\\", 1596 | "EannedJocsagewnAccal", 1597 | "mimiagCend", 1598 | "Gibai", 1599 | "AwdOlt4", 1600 | "giweb", 1601 | "nakGuAdGazLelElk5", 1602 | "TaxWovNig", 1603 | "dibrUlcumgawnOik", 1604 | "igFicvetgiUtNiOrp{", 1605 | "BuptOmDolWyRok9", 1606 | "DitLeydibDarEciss", 1607 | "KeQuicVowItbuAl", 1608 | "oyltIbr+Quormok1", 1609 | "NeuWershIasji", 1610 | "Clirwinyoyff", 1611 | "yefdo", 1612 | "JowyinhovghindEf", 1613 | "Grobcicemyenpi", 1614 | "RerjattOgdakvush\\", 1615 | "Joowval", 1616 | "yossyoahed", 1617 | "UlwunoGreusjahujodeo", 1618 | "Boylk", 1619 | "cryod", 1620 | "yetudJoi", 1621 | "LeHybkihoysbeipJeys", 1622 | "peexRonMikEnoikdetwy", 1623 | "Atfavcomjiosh5", 1624 | "yousDu", 1625 | "yerwofad", 1626 | "frogdimOcjet0", 1627 | "BofyokTipCewl", 1628 | "imfed:", 1629 | "GaydVejyegcyg", 1630 | "riupOmNuespOrd", 1631 | "FavRa", 1632 | "myHybAwkAmgob", 1633 | "vuWreHotsav3", 1634 | "luwup", 1635 | "2Queitnu", 1636 | "hokPidesIcModLucDoom", 1637 | "vawhuojMawyarmuvij1", 1638 | "WyctUrd3flofIp@", 1639 | "kaniarcAfvedsen", 1640 | "fowyagJad", 1641 | "revor", 1642 | "Lafdafleug2", 1643 | "roammeskiddyuhav8", 1644 | "feavrocug#", 1645 | "Uccenjav#", 1646 | "DobOcKog6tr", 1647 | "JufwatnujphealNea", 1648 | "LiedBuHoskegg", 1649 | "pandUsyowgyan>", 1650 | "igPeg", 1651 | "keak7", 1652 | "Krothjac", 1653 | "yirdAf8", 1654 | "ranthArl{", 1655 | "DibyWoockOwsanarlEw", 1656 | "EiksAggavTus7", 1657 | "nawmalavid", 1658 | "JapJededwaHaun", 1659 | "byojhurf", 1660 | "iroowcetJafnox", 1661 | "frailtacvu", 1662 | "tuweshCad", 1663 | "Pennaun%", 1664 | "IkhiebMowt", 1665 | "VeHinrielshidJoan", 1666 | "fudAjdof*", 1667 | "tirpeuhyephhicsefbix", 1668 | "DiwyzFaymveemshawdac", 1669 | "oijMeryagOdjic", 1670 | "FrisvagditNic", 1671 | "Mofeinniakfa", 1672 | "OicDodNergOireccaf", 1673 | "RyHughoGriUtNebfidd", 1674 | "clisDothKird", 1675 | "MydEgIdnimAjrek", 1676 | "Vouc4", 1677 | "JartirpErladOrIdTeyk", 1678 | "Ityoirwig", 1679 | "jastyundAganyehor", 1680 | "EjHejHafmud;", 1681 | "DyokatOn", 1682 | "ondOldaddeashAj|", 1683 | "hakendyobobjicEym", 1684 | "Jobsosp", 1685 | "lyGhadIalNaygIdCyar", 1686 | "Pidth>", 1687 | "Seafoyk5", 1688 | "UgCakDis2", 1689 | "LiastevOjlagiken", 1690 | "twunegs", 1691 | "CujReabTebUfeg3", 1692 | "NejagjuesFaj", 1693 | "LyuchBekBanbet", 1694 | "Odorvyuasyoi", 1695 | "thalvyadbeibHegot", 1696 | "GlakMor", 1697 | "EnArWo", 1698 | "orkAbFomedUkKov)", 1699 | "VoingExmysbarkUbWeaf", 1700 | "OcIfsaic", 1701 | "TidlotVabnarAkOi", 1702 | "dafdessuzJorucgat", 1703 | "Kidsurbyatirropjut", 1704 | "SceerlEmub", 1705 | ".Tweug", 1706 | "ReunAnkad", 1707 | "RuWijkuc<", 1708 | "trirkicCyn", 1709 | "pynRyHodJorkyuca", 1710 | "Preurtyin", 1711 | "grigpyes", 1712 | "Olsed", 1713 | "pecnel,", 1714 | "liutCewthokvav$", 1715 | "GicJet5", 1716 | "vobKegMa", 1717 | "EcBishjisBuvPem", 1718 | "bettyijIlciGed", 1719 | "moHelnew`", 1720 | "EjTesVol5queewrauch", 1721 | "IdGejDomNowmOmjem9", 1722 | "HasBifPed", 1723 | "doowyechtafEijuvRun", 1724 | "drekbyumeurp:", 1725 | "smujatCisVaHewkya", 1726 | "quokzi", 1727 | "deGruob2", 1728 | "tetmyFlitLydsic", 1729 | "IdvogulGhozjas5", 1730 | "eesyowCeogovGenMij", 1731 | "KnighRavEf", 1732 | "WremRocHidro", 1733 | "yarEcdodCecheitsOm", 1734 | "latrecs8Glic0", 1735 | "WiacfisVabIo", 1736 | "cywyow", 1737 | "runBivniHebci", 1738 | "cajFejevHydecsej7", 1739 | "GoomIpjeDredPou", 1740 | "EcHewfetEshBi", 1741 | "NickgehennEcBuseuph5", 1742 | "ugMiofVabCa", 1743 | "]shnihifhatcodwy", 1744 | "plurphoins", 1745 | "smerc'qua", 1746 | "wharsharn", 1747 | "cicUchjoaztoifbenkat", 1748 | "avWonliWewEnCu", 1749 | "natvekOkpoof", 1750 | "DujPytPifoitt^", 1751 | "Giacaivdarrog", 1752 | "RoivdukEanLikhidr", 1753 | "raveuhuvowAckwiarn[", 1754 | "sagAuWytyavsid8", 1755 | "KafGaugviKenBumCyu", 1756 | "KodImOjAcdian", 1757 | "crizJacPeask", 1758 | "yurjAfer", 1759 | "KeheQuad$", 1760 | "KnulCysen8", 1761 | "NuetOo", 1762 | "imnoopucsyerlIrrye", 1763 | "Egtheb", 1764 | "JadUssEjBactAfWoc7", 1765 | "juAcdabheipjerVuAsk", 1766 | "etnixAlceOcmij", 1767 | "ShyurrUg", 1768 | "MeHunras", 1769 | "AptInleHethaybOkAib", 1770 | "yuekAtjixByibsArsOl", 1771 | "CusjehuvLednitpemyey", 1772 | "ConcebnoxTopCurt", 1773 | "shwanumayRogigdo", 1774 | "tuchDoyftAwl", 1775 | "LymImtibfaWrep", 1776 | "yequetNuondaskejci", 1777 | "naifHuhogBugtazSikto", 1778 | "NojBen?ovRaiphUb^", 1779 | "koynRivshuj", 1780 | "ezdaj", 1781 | "ruevWij", 1782 | "BegPounrainPysayreb", 1783 | "afEvUtleObr", 1784 | "provdelvEmKest3", 1785 | "fethdunUcdyhakMagyi", 1786 | "HewOisObruvfek", 1787 | "Cofdajzo", 1788 | "hefkalfIdfiquofalkaw", 1789 | "CopNej", 1790 | "BilbyacemDam", 1791 | "custUrdakItOc\\", 1792 | "yidUgyirjou", 1793 | "icderfOwfektev", 1794 | "hoosIrrAfvafivNo", 1795 | "yoveetsat", 1796 | "Sugar=owx\"", 1797 | "geegUttOicWyu", 1798 | "Jiphkol0", 1799 | "KaddAfdipNegsuc0", 1800 | "yoifjiv", 1801 | "Cheggoigwonoiqueef", 1802 | "mibvaifdultAir", 1803 | "peOs0AppErsodAfGa", 1804 | "twyevfig", 1805 | "nuOrm", 1806 | "8GryubCuk", 1807 | "OrvyivpolsyopyepIf9", 1808 | "cykpyotufDiwash\\", 1809 | "drutt3Quol'", 1810 | "NusEjtuAmyiegPeft", 1811 | "tu\"swacks", 1812 | "WroGrylkObHynvevar", 1813 | "CycsesAfjatDulafjof^", 1814 | "naDroucMiectAfsyeg", 1815 | "sonCycsobusckUmrys", 1816 | "yufub(", 1817 | "DordItNonoxCaljAym", 1818 | "OnnyojyunfurWiOmDy", 1819 | "TwechtefvedkanBowv", 1820 | "WedNejUvSilmOmoniduc", 1821 | "WrengIbrokEjUt5", 1822 | "kiWiacViaphzihakigs", 1823 | "NityiSwowmovBepIdHi", 1824 | "atdon^", 1825 | "Teats", 1826 | "VepbehufKedsEj|", 1827 | "vuryudtuszedco", 1828 | "MopphifFijdiusBot", 1829 | "NifEvyeedakOtyadNu", 1830 | "Dujpi", 1831 | "OkgarghawvOk2", 1832 | "idwouphjadPhuwakAwk", 1833 | "dekchicWor", 1834 | "einvaFrewWow4", 1835 | "enwarr", 1836 | "OofErcInwifOjAkrio", 1837 | "RihoghCuOt,od", 1838 | "WiapOaWremDed", 1839 | "OveacbyifUtvaHi", 1840 | "PeHetkej", 1841 | "FamLodObIsjuQuof+", 1842 | "RhekGhigekEqu", 1843 | "Shefeernya", 1844 | "priWev9", 1845 | "Me9Rer", 1846 | "necIvbaindEanWicEj", 1847 | "eksIvWicDoysekAvda", 1848 | "AgbawbEzGim", 1849 | "nilkowUbso", 1850 | "gejReetok8OkBygTo", 1851 | "CoHircecOodfakeit", 1852 | "NulsElj", 1853 | "Deiksonsyob8", 1854 | "joc8Gliup", 1855 | "rebNecks", 1856 | "jurodPobIjwonIcEn", 1857 | "BiOfjovCerdAcKoiKej", 1858 | "Kehyobvov:", 1859 | "CukHacElEe", 1860 | "akpeiph}grysckentip5", 1861 | "Edgubeuv&", 1862 | "GibSha", 1863 | "IgyaicJikcaddacwed", 1864 | "jaFlib", 1865 | "Wath2", 1866 | "mosh7", 1867 | "Befvi", 1868 | "Sybidyejeewb", 1869 | "ghegdyftorcitTa", 1870 | "CyTwok7", 1871 | "NebJeafNutvoidyinAf;", 1872 | "cowlormumfoi", 1873 | "sheashels", 1874 | "NiewEe", 1875 | "necuvpojeudMil@", 1876 | "Peodnig", 1877 | "CagNeffatApKuvji", 1878 | "UcFijAgcuwyctasFeuj", 1879 | "VaWract4", 1880 | "emnaucef", 1881 | "RockamOfijpenyokadyo", 1882 | "NumDoSweBylchobpy", 1883 | "jeyljojAj", 1884 | "oaryoushOnrugit", 1885 | "AnLoy", 1886 | "tenRa", 1887 | "hybEs", 1888 | "afguvpehyryidsEc", 1889 | "Ijubs]", 1890 | "LecnagNadjoveus\"", 1891 | "TowufAw", 1892 | "onEkwuwonbowya", 1893 | "Novyipwapdyn", 1894 | "Phrawn$", 1895 | "shiesShic", 1896 | "giudhenk", 1897 | "Eudli", 1898 | "nidmysJiryipwysHif", 1899 | "Lejfial\\", 1900 | "TheimyegBip3", 1901 | "idUnjiotJapom)", 1902 | "nacan", 1903 | "UgJeGul", 1904 | "pyweacdovHy", 1905 | "yidMarHujHarEckga", 1906 | "ucIfMegwofda", 1907 | "BeagaiblibGoy", 1908 | "todsumUt", 1909 | "krebWeacWiwovriztyie", 1910 | "pretdycsuphooksajCo", 1911 | "umOshpojtentadWicmol", 1912 | "Cott9", 1913 | "acCumZusvedcayxNo", 1914 | "TowisabmofWy", 1915 | "Ceelunnyan", 1916 | "&Tejyiekyojuk", 1917 | "omBeskOgonla", 1918 | "uphCofJin$", 1919 | "AirasAibjipbila", 1920 | "Nogjolebdazomug]", 1921 | "KoSwyoryoi", 1922 | "Tymdithehag", 1923 | "EegniFuvAin", 1924 | "Grav2AbAfmeavCad7", 1925 | "EnHynvenFiOcEnJuCr", 1926 | "RotJi", 1927 | "Udvid5", 1928 | "igocKeyWydlacphijteg", 1929 | "ujufvuvEbpheec", 1930 | "VitlyreujdigVoc", 1931 | "SygbanthuvGutAc", 1932 | "Ooflavyue", 1933 | "Rhairg=omdegjeegnem+", 1934 | "ReenVosekUcCug", 1935 | "VoymDeip", 1936 | "osyoshAvVicheotafs", 1937 | "KnyljIgyekjibHor|", 1938 | "JoggelAndOsBokVu", 1939 | "Upjovurhens", 1940 | "Kij6om", 1941 | "phauljyoHia", 1942 | "kash6", 1943 | "KiFrewIdNocOord{", 1944 | "tenrob", 1945 | "loGryowvit", 1946 | "goir}SwoinIaj{", 1947 | "gix1DruKnorrEys<", 1948 | "icIrsAf", 1949 | "ovlagItErnebya", 1950 | "DimpakIcathbyg", 1951 | "dabrinwyheefCaigliaf", 1952 | "yirvonBatec6", 1953 | "afEignuc", 1954 | "ovUcIpyoifs", 1955 | "mekIfOttaddAx5", 1956 | "reydodyafVadOdfilya", 1957 | "OafyutsUg<", 1958 | "tenn\"", 1959 | "Tronrucmidvaddup4", 1960 | "PackjogdakasigpejKue", 1961 | "NiabkatCoyldoipshes", 1962 | "RuOkofma", 1963 | "frejVenjavepdin", 1964 | "amsop", 1965 | "molberukvofKi", 1966 | "OfAyctocJelloc", 1967 | "JivhubAdEednobfabr", 1968 | "ilHenen", 1969 | "IvhairvIvko", 1970 | "botwolcanPoimnirc~", 1971 | "Dekef", 1972 | "flamUresoakkofEj}", 1973 | "skerdOt.", 1974 | "darets3", 1975 | "zanejcizutyicbygdi", 1976 | "eafDueshigubleog", 1977 | "vetcy", 1978 | "vequickgitdekganLys}", 1979 | "UdCudkaHoam(", 1980 | "viecvit", 1981 | "geckrijleKnip", 1982 | "zolmeiphAn%", 1983 | "EfOdKecJorrUmAst", 1984 | "waHytelyinCekauj8", 1985 | "notIkWeuHerOicOdin", 1986 | "EcsAjComs=OnJilyof\"", 1987 | "NaphlocCepIc", 1988 | "AtobEs'", 1989 | "dyeshVogshEynd", 1990 | "pypjepmersAryafUjhul", 1991 | "EebhanyajvobvawriOct", 1992 | "yinUtcye", 1993 | "Modlygjennarravar", 1994 | "keirdIzHudBuocwacCy", 1995 | "rorjyarbinhiatJic", 1996 | "odGoukfad", 1997 | "cophMotuvgicdib/", 1998 | "yeebtekKot3", 1999 | "tiUnrohivEvCoatMif", 2000 | "cipoyraryec7", 2001 | "idutcygDo", 2002 | 0 2003 | }; 2004 | 2005 | -------------------------------------------------------------------------------- /critbit-test-rb.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (C) 2002-present Jason Evans . 3 | * All rights reserved. 4 | * Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved. 5 | * Copyright (C) 2009-present Facebook, Inc. All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 1. Redistributions of source code must retain the above copyright notice(s), 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright notice(s), 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS 16 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 17 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 18 | * EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 22 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 23 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | ******************************************************************************* 26 | * 27 | * cpp macro implementation of left-leaning 2-3 red-black trees. Parent 28 | * pointers are not used, and color bits are stored in the least significant 29 | * bit of right-child pointers (if RB_COMPACT is defined), thus making node 30 | * linkage as compact as is possible for red-black trees. 31 | * 32 | * Usage: 33 | * 34 | * #include 35 | * #include 36 | * #define NDEBUG // (Optional, see assert(3).) 37 | * #include 38 | * #define RB_COMPACT // (Optional, embed color bits in right-child pointers.) 39 | * #include 40 | * ... 41 | * 42 | ******************************************************************************* 43 | */ 44 | 45 | #ifndef RB_H_ 46 | #define RB_H_ 47 | 48 | #ifdef RB_COMPACT 49 | /* Node structure. */ 50 | #define rb_node(a_type) \ 51 | struct { \ 52 | a_type *rbn_left; \ 53 | a_type *rbn_right_red; \ 54 | } 55 | #else 56 | #define rb_node(a_type) \ 57 | struct { \ 58 | a_type *rbn_left; \ 59 | a_type *rbn_right; \ 60 | bool rbn_red; \ 61 | } 62 | #endif 63 | 64 | /* Root structure. */ 65 | #define rbt(a_type) \ 66 | struct { \ 67 | a_type *rbt_root; \ 68 | a_type rbt_nil; \ 69 | } 70 | 71 | /* Left accessors. */ 72 | #define rbtn_left_get(a_type, a_field, a_node) \ 73 | ((a_node)->a_field.rbn_left) 74 | #define rbtn_left_set(a_type, a_field, a_node, a_left) do { \ 75 | (a_node)->a_field.rbn_left = a_left; \ 76 | } while (0) 77 | 78 | #ifdef RB_COMPACT 79 | /* Right accessors. */ 80 | #define rbtn_right_get(a_type, a_field, a_node) \ 81 | ((a_type *) (((intptr_t) (a_node)->a_field.rbn_right_red) \ 82 | & ((ssize_t)-2))) 83 | #define rbtn_right_set(a_type, a_field, a_node, a_right) do { \ 84 | (a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t) a_right) \ 85 | | (((uintptr_t) (a_node)->a_field.rbn_right_red) & ((size_t)1))); \ 86 | } while (0) 87 | 88 | /* Color accessors. */ 89 | #define rbtn_red_get(a_type, a_field, a_node) \ 90 | ((bool) (((uintptr_t) (a_node)->a_field.rbn_right_red) \ 91 | & ((size_t)1))) 92 | #define rbtn_color_set(a_type, a_field, a_node, a_red) do { \ 93 | (a_node)->a_field.rbn_right_red = (a_type *) ((((intptr_t) \ 94 | (a_node)->a_field.rbn_right_red) & ((ssize_t)-2)) \ 95 | | ((ssize_t)a_red)); \ 96 | } while (0) 97 | #define rbtn_red_set(a_type, a_field, a_node) do { \ 98 | (a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t) \ 99 | (a_node)->a_field.rbn_right_red) | ((size_t)1)); \ 100 | } while (0) 101 | #define rbtn_black_set(a_type, a_field, a_node) do { \ 102 | (a_node)->a_field.rbn_right_red = (a_type *) (((intptr_t) \ 103 | (a_node)->a_field.rbn_right_red) & ((ssize_t)-2)); \ 104 | } while (0) 105 | #else 106 | /* Right accessors. */ 107 | #define rbtn_right_get(a_type, a_field, a_node) \ 108 | ((a_node)->a_field.rbn_right) 109 | #define rbtn_right_set(a_type, a_field, a_node, a_right) do { \ 110 | (a_node)->a_field.rbn_right = a_right; \ 111 | } while (0) 112 | 113 | /* Color accessors. */ 114 | #define rbtn_red_get(a_type, a_field, a_node) \ 115 | ((a_node)->a_field.rbn_red) 116 | #define rbtn_color_set(a_type, a_field, a_node, a_red) do { \ 117 | (a_node)->a_field.rbn_red = (a_red); \ 118 | } while (0) 119 | #define rbtn_red_set(a_type, a_field, a_node) do { \ 120 | (a_node)->a_field.rbn_red = true; \ 121 | } while (0) 122 | #define rbtn_black_set(a_type, a_field, a_node) do { \ 123 | (a_node)->a_field.rbn_red = false; \ 124 | } while (0) 125 | #endif 126 | 127 | /* Node initializer. */ 128 | #define rbt_node_new(a_type, a_field, a_rbt, a_node) do { \ 129 | rbtn_left_set(a_type, a_field, (a_node), &(a_rbt)->rbt_nil); \ 130 | rbtn_right_set(a_type, a_field, (a_node), &(a_rbt)->rbt_nil); \ 131 | rbtn_red_set(a_type, a_field, (a_node)); \ 132 | } while (0) 133 | 134 | /* Tree initializer. */ 135 | #define rb_new(a_type, a_field, a_rbt) do { \ 136 | (a_rbt)->rbt_root = &(a_rbt)->rbt_nil; \ 137 | rbt_node_new(a_type, a_field, a_rbt, &(a_rbt)->rbt_nil); \ 138 | rbtn_black_set(a_type, a_field, &(a_rbt)->rbt_nil); \ 139 | } while (0) 140 | 141 | /* Internal utility macros. */ 142 | #define rbtn_first(a_type, a_field, a_rbt, a_root, r_node) do { \ 143 | (r_node) = (a_root); \ 144 | if ((r_node) != &(a_rbt)->rbt_nil) { \ 145 | for (; \ 146 | rbtn_left_get(a_type, a_field, (r_node)) != &(a_rbt)->rbt_nil;\ 147 | (r_node) = rbtn_left_get(a_type, a_field, (r_node))) { \ 148 | } \ 149 | } \ 150 | } while (0) 151 | 152 | #define rbtn_last(a_type, a_field, a_rbt, a_root, r_node) do { \ 153 | (r_node) = (a_root); \ 154 | if ((r_node) != &(a_rbt)->rbt_nil) { \ 155 | for (; rbtn_right_get(a_type, a_field, (r_node)) != \ 156 | &(a_rbt)->rbt_nil; (r_node) = rbtn_right_get(a_type, a_field, \ 157 | (r_node))) { \ 158 | } \ 159 | } \ 160 | } while (0) 161 | 162 | #define rbtn_rotate_left(a_type, a_field, a_node, r_node) do { \ 163 | (r_node) = rbtn_right_get(a_type, a_field, (a_node)); \ 164 | rbtn_right_set(a_type, a_field, (a_node), \ 165 | rbtn_left_get(a_type, a_field, (r_node))); \ 166 | rbtn_left_set(a_type, a_field, (r_node), (a_node)); \ 167 | } while (0) 168 | 169 | #define rbtn_rotate_right(a_type, a_field, a_node, r_node) do { \ 170 | (r_node) = rbtn_left_get(a_type, a_field, (a_node)); \ 171 | rbtn_left_set(a_type, a_field, (a_node), \ 172 | rbtn_right_get(a_type, a_field, (r_node))); \ 173 | rbtn_right_set(a_type, a_field, (r_node), (a_node)); \ 174 | } while (0) 175 | 176 | /* 177 | * The rb_proto() macro generates function prototypes that correspond to the 178 | * functions generated by an equivalently parameterized call to rb_gen(). 179 | */ 180 | 181 | #define rb_proto(a_attr, a_prefix, a_rbt_type, a_type) \ 182 | a_attr void \ 183 | a_prefix##new(a_rbt_type *rbtree); \ 184 | a_attr a_type * \ 185 | a_prefix##first(a_rbt_type *rbtree); \ 186 | a_attr a_type * \ 187 | a_prefix##last(a_rbt_type *rbtree); \ 188 | a_attr a_type * \ 189 | a_prefix##next(a_rbt_type *rbtree, a_type *node); \ 190 | a_attr a_type * \ 191 | a_prefix##prev(a_rbt_type *rbtree, a_type *node); \ 192 | a_attr a_type * \ 193 | a_prefix##search(a_rbt_type *rbtree, a_type *key); \ 194 | a_attr a_type * \ 195 | a_prefix##nsearch(a_rbt_type *rbtree, a_type *key); \ 196 | a_attr a_type * \ 197 | a_prefix##psearch(a_rbt_type *rbtree, a_type *key); \ 198 | a_attr void \ 199 | a_prefix##insert(a_rbt_type *rbtree, a_type *node); \ 200 | a_attr void \ 201 | a_prefix##remove(a_rbt_type *rbtree, a_type *node); \ 202 | a_attr a_type * \ 203 | a_prefix##iter(a_rbt_type *rbtree, a_type *start, a_type *(*cb)( \ 204 | a_rbt_type *, a_type *, void *), void *arg); \ 205 | a_attr a_type * \ 206 | a_prefix##reverse_iter(a_rbt_type *rbtree, a_type *start, \ 207 | a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg); 208 | 209 | /* 210 | * The rb_gen() macro generates a type-specific red-black tree implementation, 211 | * based on the above cpp macros. 212 | * 213 | * Arguments: 214 | * 215 | * a_attr : Function attribute for generated functions (ex: static). 216 | * a_prefix : Prefix for generated functions (ex: ex_). 217 | * a_rb_type : Type for red-black tree data structure (ex: ex_t). 218 | * a_type : Type for red-black tree node data structure (ex: ex_node_t). 219 | * a_field : Name of red-black tree node linkage (ex: ex_link). 220 | * a_cmp : Node comparison function name, with the following prototype: 221 | * int (a_cmp *)(a_type *a_node, a_type *a_other); 222 | * ^^^^^^ 223 | * or a_key 224 | * Interpretation of comparision function return values: 225 | * -1 : a_node < a_other 226 | * 0 : a_node == a_other 227 | * 1 : a_node > a_other 228 | * In all cases, the a_node or a_key macro argument is the first 229 | * argument to the comparison function, which makes it possible 230 | * to write comparison functions that treat the first argument 231 | * specially. 232 | * 233 | * Assuming the following setup: 234 | * 235 | * typedef struct ex_node_s ex_node_t; 236 | * struct ex_node_s { 237 | * rb_node(ex_node_t) ex_link; 238 | * }; 239 | * typedef rbt(ex_node_t) ex_t; 240 | * rb_gen(static, ex_, ex_t, ex_node_t, ex_link, ex_cmp) 241 | * 242 | * The following API is generated: 243 | * 244 | * static void 245 | * ex_new(ex_t *tree); 246 | * Description: Initialize a red-black tree structure. 247 | * Args: 248 | * tree: Pointer to an uninitialized red-black tree object. 249 | * 250 | * static ex_node_t * 251 | * ex_first(ex_t *tree); 252 | * static ex_node_t * 253 | * ex_last(ex_t *tree); 254 | * Description: Get the first/last node in tree. 255 | * Args: 256 | * tree: Pointer to an initialized red-black tree object. 257 | * Ret: First/last node in tree, or NULL if tree is empty. 258 | * 259 | * static ex_node_t * 260 | * ex_next(ex_t *tree, ex_node_t *node); 261 | * static ex_node_t * 262 | * ex_prev(ex_t *tree, ex_node_t *node); 263 | * Description: Get node's successor/predecessor. 264 | * Args: 265 | * tree: Pointer to an initialized red-black tree object. 266 | * node: A node in tree. 267 | * Ret: node's successor/predecessor in tree, or NULL if node is 268 | * last/first. 269 | * 270 | * static ex_node_t * 271 | * ex_search(ex_t *tree, ex_node_t *key); 272 | * Description: Search for node that matches key. 273 | * Args: 274 | * tree: Pointer to an initialized red-black tree object. 275 | * key : Search key. 276 | * Ret: Node in tree that matches key, or NULL if no match. 277 | * 278 | * static ex_node_t * 279 | * ex_nsearch(ex_t *tree, ex_node_t *key); 280 | * static ex_node_t * 281 | * ex_psearch(ex_t *tree, ex_node_t *key); 282 | * Description: Search for node that matches key. If no match is found, 283 | * return what would be key's successor/predecessor, were 284 | * key in tree. 285 | * Args: 286 | * tree: Pointer to an initialized red-black tree object. 287 | * key : Search key. 288 | * Ret: Node in tree that matches key, or if no match, hypothetical node's 289 | * successor/predecessor (NULL if no successor/predecessor). 290 | * 291 | * static void 292 | * ex_insert(ex_t *tree, ex_node_t *node); 293 | * Description: Insert node into tree. 294 | * Args: 295 | * tree: Pointer to an initialized red-black tree object. 296 | * node: Node to be inserted into tree. 297 | * 298 | * static void 299 | * ex_remove(ex_t *tree, ex_node_t *node); 300 | * Description: Remove node from tree. 301 | * Args: 302 | * tree: Pointer to an initialized red-black tree object. 303 | * node: Node in tree to be removed. 304 | * 305 | * static ex_node_t * 306 | * ex_iter(ex_t *tree, ex_node_t *start, ex_node_t *(*cb)(ex_t *, 307 | * ex_node_t *, void *), void *arg); 308 | * static ex_node_t * 309 | * ex_reverse_iter(ex_t *tree, ex_node_t *start, ex_node *(*cb)(ex_t *, 310 | * ex_node_t *, void *), void *arg); 311 | * Description: Iterate forward/backward over tree, starting at node. If 312 | * tree is modified, iteration must be immediately 313 | * terminated by the callback function that causes the 314 | * modification. 315 | * Args: 316 | * tree : Pointer to an initialized red-black tree object. 317 | * start: Node at which to start iteration, or NULL to start at 318 | * first/last node. 319 | * cb : Callback function, which is called for each node during 320 | * iteration. Under normal circumstances the callback function 321 | * should return NULL, which causes iteration to continue. If a 322 | * callback function returns non-NULL, iteration is immediately 323 | * terminated and the non-NULL return value is returned by the 324 | * iterator. This is useful for re-starting iteration after 325 | * modifying tree. 326 | * arg : Opaque pointer passed to cb(). 327 | * Ret: NULL if iteration completed, or the non-NULL callback return value 328 | * that caused termination of the iteration. 329 | */ 330 | #define rb_gen(a_attr, a_prefix, a_rbt_type, a_type, a_field, a_cmp) \ 331 | a_attr void \ 332 | a_prefix##new(a_rbt_type *rbtree) { \ 333 | rb_new(a_type, a_field, rbtree); \ 334 | } \ 335 | a_attr a_type * \ 336 | a_prefix##first(a_rbt_type *rbtree) { \ 337 | a_type *ret; \ 338 | rbtn_first(a_type, a_field, rbtree, rbtree->rbt_root, ret); \ 339 | if (ret == &rbtree->rbt_nil) { \ 340 | ret = NULL; \ 341 | } \ 342 | return (ret); \ 343 | } \ 344 | a_attr a_type * \ 345 | a_prefix##last(a_rbt_type *rbtree) { \ 346 | a_type *ret; \ 347 | rbtn_last(a_type, a_field, rbtree, rbtree->rbt_root, ret); \ 348 | if (ret == &rbtree->rbt_nil) { \ 349 | ret = NULL; \ 350 | } \ 351 | return (ret); \ 352 | } \ 353 | a_attr a_type * \ 354 | a_prefix##next(a_rbt_type *rbtree, a_type *node) { \ 355 | a_type *ret; \ 356 | if (rbtn_right_get(a_type, a_field, node) != &rbtree->rbt_nil) { \ 357 | rbtn_first(a_type, a_field, rbtree, rbtn_right_get(a_type, \ 358 | a_field, node), ret); \ 359 | } else { \ 360 | a_type *tnode = rbtree->rbt_root; \ 361 | assert(tnode != &rbtree->rbt_nil); \ 362 | ret = &rbtree->rbt_nil; \ 363 | while (true) { \ 364 | int cmp = (a_cmp)(node, tnode); \ 365 | if (cmp < 0) { \ 366 | ret = tnode; \ 367 | tnode = rbtn_left_get(a_type, a_field, tnode); \ 368 | } else if (cmp > 0) { \ 369 | tnode = rbtn_right_get(a_type, a_field, tnode); \ 370 | } else { \ 371 | break; \ 372 | } \ 373 | assert(tnode != &rbtree->rbt_nil); \ 374 | } \ 375 | } \ 376 | if (ret == &rbtree->rbt_nil) { \ 377 | ret = (NULL); \ 378 | } \ 379 | return (ret); \ 380 | } \ 381 | a_attr a_type * \ 382 | a_prefix##prev(a_rbt_type *rbtree, a_type *node) { \ 383 | a_type *ret; \ 384 | if (rbtn_left_get(a_type, a_field, node) != &rbtree->rbt_nil) { \ 385 | rbtn_last(a_type, a_field, rbtree, rbtn_left_get(a_type, \ 386 | a_field, node), ret); \ 387 | } else { \ 388 | a_type *tnode = rbtree->rbt_root; \ 389 | assert(tnode != &rbtree->rbt_nil); \ 390 | ret = &rbtree->rbt_nil; \ 391 | while (true) { \ 392 | int cmp = (a_cmp)(node, tnode); \ 393 | if (cmp < 0) { \ 394 | tnode = rbtn_left_get(a_type, a_field, tnode); \ 395 | } else if (cmp > 0) { \ 396 | ret = tnode; \ 397 | tnode = rbtn_right_get(a_type, a_field, tnode); \ 398 | } else { \ 399 | break; \ 400 | } \ 401 | assert(tnode != &rbtree->rbt_nil); \ 402 | } \ 403 | } \ 404 | if (ret == &rbtree->rbt_nil) { \ 405 | ret = (NULL); \ 406 | } \ 407 | return (ret); \ 408 | } \ 409 | a_attr a_type * \ 410 | a_prefix##search(a_rbt_type *rbtree, a_type *key) { \ 411 | a_type *ret; \ 412 | int cmp; \ 413 | ret = rbtree->rbt_root; \ 414 | while (ret != &rbtree->rbt_nil \ 415 | && (cmp = (a_cmp)(key, ret)) != 0) { \ 416 | if (cmp < 0) { \ 417 | ret = rbtn_left_get(a_type, a_field, ret); \ 418 | } else { \ 419 | ret = rbtn_right_get(a_type, a_field, ret); \ 420 | } \ 421 | } \ 422 | if (ret == &rbtree->rbt_nil) { \ 423 | ret = (NULL); \ 424 | } \ 425 | return (ret); \ 426 | } \ 427 | a_attr a_type * \ 428 | a_prefix##nsearch(a_rbt_type *rbtree, a_type *key) { \ 429 | a_type *ret; \ 430 | a_type *tnode = rbtree->rbt_root; \ 431 | ret = &rbtree->rbt_nil; \ 432 | while (tnode != &rbtree->rbt_nil) { \ 433 | int cmp = (a_cmp)(key, tnode); \ 434 | if (cmp < 0) { \ 435 | ret = tnode; \ 436 | tnode = rbtn_left_get(a_type, a_field, tnode); \ 437 | } else if (cmp > 0) { \ 438 | tnode = rbtn_right_get(a_type, a_field, tnode); \ 439 | } else { \ 440 | ret = tnode; \ 441 | break; \ 442 | } \ 443 | } \ 444 | if (ret == &rbtree->rbt_nil) { \ 445 | ret = (NULL); \ 446 | } \ 447 | return (ret); \ 448 | } \ 449 | a_attr a_type * \ 450 | a_prefix##psearch(a_rbt_type *rbtree, a_type *key) { \ 451 | a_type *ret; \ 452 | a_type *tnode = rbtree->rbt_root; \ 453 | ret = &rbtree->rbt_nil; \ 454 | while (tnode != &rbtree->rbt_nil) { \ 455 | int cmp = (a_cmp)(key, tnode); \ 456 | if (cmp < 0) { \ 457 | tnode = rbtn_left_get(a_type, a_field, tnode); \ 458 | } else if (cmp > 0) { \ 459 | ret = tnode; \ 460 | tnode = rbtn_right_get(a_type, a_field, tnode); \ 461 | } else { \ 462 | ret = tnode; \ 463 | break; \ 464 | } \ 465 | } \ 466 | if (ret == &rbtree->rbt_nil) { \ 467 | ret = (NULL); \ 468 | } \ 469 | return (ret); \ 470 | } \ 471 | a_attr void \ 472 | a_prefix##insert(a_rbt_type *rbtree, a_type *node) { \ 473 | struct { \ 474 | a_type *node; \ 475 | int cmp; \ 476 | } path[sizeof(void *) << 4], *pathp; \ 477 | rbt_node_new(a_type, a_field, rbtree, node); \ 478 | /* Wind. */ \ 479 | path->node = rbtree->rbt_root; \ 480 | for (pathp = path; pathp->node != &rbtree->rbt_nil; pathp++) { \ 481 | int cmp = pathp->cmp = a_cmp(node, pathp->node); \ 482 | assert(cmp != 0); \ 483 | if (cmp < 0) { \ 484 | pathp[1].node = rbtn_left_get(a_type, a_field, \ 485 | pathp->node); \ 486 | } else { \ 487 | pathp[1].node = rbtn_right_get(a_type, a_field, \ 488 | pathp->node); \ 489 | } \ 490 | } \ 491 | pathp->node = node; \ 492 | /* Unwind. */ \ 493 | for (pathp--; (uintptr_t)pathp >= (uintptr_t)path; pathp--) { \ 494 | a_type *cnode = pathp->node; \ 495 | if (pathp->cmp < 0) { \ 496 | a_type *left = pathp[1].node; \ 497 | rbtn_left_set(a_type, a_field, cnode, left); \ 498 | if (rbtn_red_get(a_type, a_field, left)) { \ 499 | a_type *leftleft = rbtn_left_get(a_type, a_field, left);\ 500 | if (rbtn_red_get(a_type, a_field, leftleft)) { \ 501 | /* Fix up 4-node. */ \ 502 | a_type *tnode; \ 503 | rbtn_black_set(a_type, a_field, leftleft); \ 504 | rbtn_rotate_right(a_type, a_field, cnode, tnode); \ 505 | cnode = tnode; \ 506 | } \ 507 | } else { \ 508 | return; \ 509 | } \ 510 | } else { \ 511 | a_type *right = pathp[1].node; \ 512 | rbtn_right_set(a_type, a_field, cnode, right); \ 513 | if (rbtn_red_get(a_type, a_field, right)) { \ 514 | a_type *left = rbtn_left_get(a_type, a_field, cnode); \ 515 | if (rbtn_red_get(a_type, a_field, left)) { \ 516 | /* Split 4-node. */ \ 517 | rbtn_black_set(a_type, a_field, left); \ 518 | rbtn_black_set(a_type, a_field, right); \ 519 | rbtn_red_set(a_type, a_field, cnode); \ 520 | } else { \ 521 | /* Lean left. */ \ 522 | a_type *tnode; \ 523 | bool tred = rbtn_red_get(a_type, a_field, cnode); \ 524 | rbtn_rotate_left(a_type, a_field, cnode, tnode); \ 525 | rbtn_color_set(a_type, a_field, tnode, tred); \ 526 | rbtn_red_set(a_type, a_field, cnode); \ 527 | cnode = tnode; \ 528 | } \ 529 | } else { \ 530 | return; \ 531 | } \ 532 | } \ 533 | pathp->node = cnode; \ 534 | } \ 535 | /* Set root, and make it black. */ \ 536 | rbtree->rbt_root = path->node; \ 537 | rbtn_black_set(a_type, a_field, rbtree->rbt_root); \ 538 | } \ 539 | a_attr void \ 540 | a_prefix##remove(a_rbt_type *rbtree, a_type *node) { \ 541 | struct { \ 542 | a_type *node; \ 543 | int cmp; \ 544 | } *pathp, *nodep, path[sizeof(void *) << 4]; \ 545 | /* Wind. */ \ 546 | nodep = NULL; /* Silence compiler warning. */ \ 547 | path->node = rbtree->rbt_root; \ 548 | for (pathp = path; pathp->node != &rbtree->rbt_nil; pathp++) { \ 549 | int cmp = pathp->cmp = a_cmp(node, pathp->node); \ 550 | if (cmp < 0) { \ 551 | pathp[1].node = rbtn_left_get(a_type, a_field, \ 552 | pathp->node); \ 553 | } else { \ 554 | pathp[1].node = rbtn_right_get(a_type, a_field, \ 555 | pathp->node); \ 556 | if (cmp == 0) { \ 557 | /* Find node's successor, in preparation for swap. */ \ 558 | pathp->cmp = 1; \ 559 | nodep = pathp; \ 560 | for (pathp++; pathp->node != &rbtree->rbt_nil; \ 561 | pathp++) { \ 562 | pathp->cmp = -1; \ 563 | pathp[1].node = rbtn_left_get(a_type, a_field, \ 564 | pathp->node); \ 565 | } \ 566 | break; \ 567 | } \ 568 | } \ 569 | } \ 570 | assert(nodep->node == node); \ 571 | pathp--; \ 572 | if (pathp->node != node) { \ 573 | /* Swap node with its successor. */ \ 574 | bool tred = rbtn_red_get(a_type, a_field, pathp->node); \ 575 | rbtn_color_set(a_type, a_field, pathp->node, \ 576 | rbtn_red_get(a_type, a_field, node)); \ 577 | rbtn_left_set(a_type, a_field, pathp->node, \ 578 | rbtn_left_get(a_type, a_field, node)); \ 579 | /* If node's successor is its right child, the following code */\ 580 | /* will do the wrong thing for the right child pointer. */\ 581 | /* However, it doesn't matter, because the pointer will be */\ 582 | /* properly set when the successor is pruned. */\ 583 | rbtn_right_set(a_type, a_field, pathp->node, \ 584 | rbtn_right_get(a_type, a_field, node)); \ 585 | rbtn_color_set(a_type, a_field, node, tred); \ 586 | /* The pruned leaf node's child pointers are never accessed */\ 587 | /* again, so don't bother setting them to nil. */\ 588 | nodep->node = pathp->node; \ 589 | pathp->node = node; \ 590 | if (nodep == path) { \ 591 | rbtree->rbt_root = nodep->node; \ 592 | } else { \ 593 | if (nodep[-1].cmp < 0) { \ 594 | rbtn_left_set(a_type, a_field, nodep[-1].node, \ 595 | nodep->node); \ 596 | } else { \ 597 | rbtn_right_set(a_type, a_field, nodep[-1].node, \ 598 | nodep->node); \ 599 | } \ 600 | } \ 601 | } else { \ 602 | a_type *left = rbtn_left_get(a_type, a_field, node); \ 603 | if (left != &rbtree->rbt_nil) { \ 604 | /* node has no successor, but it has a left child. */\ 605 | /* Splice node out, without losing the left child. */\ 606 | assert(rbtn_red_get(a_type, a_field, node) == false); \ 607 | assert(rbtn_red_get(a_type, a_field, left)); \ 608 | rbtn_black_set(a_type, a_field, left); \ 609 | if (pathp == path) { \ 610 | rbtree->rbt_root = left; \ 611 | } else { \ 612 | if (pathp[-1].cmp < 0) { \ 613 | rbtn_left_set(a_type, a_field, pathp[-1].node, \ 614 | left); \ 615 | } else { \ 616 | rbtn_right_set(a_type, a_field, pathp[-1].node, \ 617 | left); \ 618 | } \ 619 | } \ 620 | return; \ 621 | } else if (pathp == path) { \ 622 | /* The tree only contained one node. */ \ 623 | rbtree->rbt_root = &rbtree->rbt_nil; \ 624 | return; \ 625 | } \ 626 | } \ 627 | if (rbtn_red_get(a_type, a_field, pathp->node)) { \ 628 | /* Prune red node, which requires no fixup. */ \ 629 | assert(pathp[-1].cmp < 0); \ 630 | rbtn_left_set(a_type, a_field, pathp[-1].node, \ 631 | &rbtree->rbt_nil); \ 632 | return; \ 633 | } \ 634 | /* The node to be pruned is black, so unwind until balance is */\ 635 | /* restored. */\ 636 | pathp->node = &rbtree->rbt_nil; \ 637 | for (pathp--; (uintptr_t)pathp >= (uintptr_t)path; pathp--) { \ 638 | assert(pathp->cmp != 0); \ 639 | if (pathp->cmp < 0) { \ 640 | rbtn_left_set(a_type, a_field, pathp->node, \ 641 | pathp[1].node); \ 642 | assert(rbtn_red_get(a_type, a_field, pathp[1].node) \ 643 | == false); \ 644 | if (rbtn_red_get(a_type, a_field, pathp->node)) { \ 645 | a_type *right = rbtn_right_get(a_type, a_field, \ 646 | pathp->node); \ 647 | a_type *rightleft = rbtn_left_get(a_type, a_field, \ 648 | right); \ 649 | a_type *tnode; \ 650 | if (rbtn_red_get(a_type, a_field, rightleft)) { \ 651 | /* In the following diagrams, ||, //, and \\ */\ 652 | /* indicate the path to the removed node. */\ 653 | /* */\ 654 | /* || */\ 655 | /* pathp(r) */\ 656 | /* // \ */\ 657 | /* (b) (b) */\ 658 | /* / */\ 659 | /* (r) */\ 660 | /* */\ 661 | rbtn_black_set(a_type, a_field, pathp->node); \ 662 | rbtn_rotate_right(a_type, a_field, right, tnode); \ 663 | rbtn_right_set(a_type, a_field, pathp->node, tnode);\ 664 | rbtn_rotate_left(a_type, a_field, pathp->node, \ 665 | tnode); \ 666 | } else { \ 667 | /* || */\ 668 | /* pathp(r) */\ 669 | /* // \ */\ 670 | /* (b) (b) */\ 671 | /* / */\ 672 | /* (b) */\ 673 | /* */\ 674 | rbtn_rotate_left(a_type, a_field, pathp->node, \ 675 | tnode); \ 676 | } \ 677 | /* Balance restored, but rotation modified subtree */\ 678 | /* root. */\ 679 | assert((uintptr_t)pathp > (uintptr_t)path); \ 680 | if (pathp[-1].cmp < 0) { \ 681 | rbtn_left_set(a_type, a_field, pathp[-1].node, \ 682 | tnode); \ 683 | } else { \ 684 | rbtn_right_set(a_type, a_field, pathp[-1].node, \ 685 | tnode); \ 686 | } \ 687 | return; \ 688 | } else { \ 689 | a_type *right = rbtn_right_get(a_type, a_field, \ 690 | pathp->node); \ 691 | a_type *rightleft = rbtn_left_get(a_type, a_field, \ 692 | right); \ 693 | if (rbtn_red_get(a_type, a_field, rightleft)) { \ 694 | /* || */\ 695 | /* pathp(b) */\ 696 | /* // \ */\ 697 | /* (b) (b) */\ 698 | /* / */\ 699 | /* (r) */\ 700 | a_type *tnode; \ 701 | rbtn_black_set(a_type, a_field, rightleft); \ 702 | rbtn_rotate_right(a_type, a_field, right, tnode); \ 703 | rbtn_right_set(a_type, a_field, pathp->node, tnode);\ 704 | rbtn_rotate_left(a_type, a_field, pathp->node, \ 705 | tnode); \ 706 | /* Balance restored, but rotation modified */\ 707 | /* subree root, which may actually be the tree */\ 708 | /* root. */\ 709 | if (pathp == path) { \ 710 | /* Set root. */ \ 711 | rbtree->rbt_root = tnode; \ 712 | } else { \ 713 | if (pathp[-1].cmp < 0) { \ 714 | rbtn_left_set(a_type, a_field, \ 715 | pathp[-1].node, tnode); \ 716 | } else { \ 717 | rbtn_right_set(a_type, a_field, \ 718 | pathp[-1].node, tnode); \ 719 | } \ 720 | } \ 721 | return; \ 722 | } else { \ 723 | /* || */\ 724 | /* pathp(b) */\ 725 | /* // \ */\ 726 | /* (b) (b) */\ 727 | /* / */\ 728 | /* (b) */\ 729 | a_type *tnode; \ 730 | rbtn_red_set(a_type, a_field, pathp->node); \ 731 | rbtn_rotate_left(a_type, a_field, pathp->node, \ 732 | tnode); \ 733 | pathp->node = tnode; \ 734 | } \ 735 | } \ 736 | } else { \ 737 | a_type *left; \ 738 | rbtn_right_set(a_type, a_field, pathp->node, \ 739 | pathp[1].node); \ 740 | left = rbtn_left_get(a_type, a_field, pathp->node); \ 741 | if (rbtn_red_get(a_type, a_field, left)) { \ 742 | a_type *tnode; \ 743 | a_type *leftright = rbtn_right_get(a_type, a_field, \ 744 | left); \ 745 | a_type *leftrightleft = rbtn_left_get(a_type, a_field, \ 746 | leftright); \ 747 | if (rbtn_red_get(a_type, a_field, leftrightleft)) { \ 748 | /* || */\ 749 | /* pathp(b) */\ 750 | /* / \\ */\ 751 | /* (r) (b) */\ 752 | /* \ */\ 753 | /* (b) */\ 754 | /* / */\ 755 | /* (r) */\ 756 | a_type *unode; \ 757 | rbtn_black_set(a_type, a_field, leftrightleft); \ 758 | rbtn_rotate_right(a_type, a_field, pathp->node, \ 759 | unode); \ 760 | rbtn_rotate_right(a_type, a_field, pathp->node, \ 761 | tnode); \ 762 | rbtn_right_set(a_type, a_field, unode, tnode); \ 763 | rbtn_rotate_left(a_type, a_field, unode, tnode); \ 764 | } else { \ 765 | /* || */\ 766 | /* pathp(b) */\ 767 | /* / \\ */\ 768 | /* (r) (b) */\ 769 | /* \ */\ 770 | /* (b) */\ 771 | /* / */\ 772 | /* (b) */\ 773 | assert(leftright != &rbtree->rbt_nil); \ 774 | rbtn_red_set(a_type, a_field, leftright); \ 775 | rbtn_rotate_right(a_type, a_field, pathp->node, \ 776 | tnode); \ 777 | rbtn_black_set(a_type, a_field, tnode); \ 778 | } \ 779 | /* Balance restored, but rotation modified subtree */\ 780 | /* root, which may actually be the tree root. */\ 781 | if (pathp == path) { \ 782 | /* Set root. */ \ 783 | rbtree->rbt_root = tnode; \ 784 | } else { \ 785 | if (pathp[-1].cmp < 0) { \ 786 | rbtn_left_set(a_type, a_field, pathp[-1].node, \ 787 | tnode); \ 788 | } else { \ 789 | rbtn_right_set(a_type, a_field, pathp[-1].node, \ 790 | tnode); \ 791 | } \ 792 | } \ 793 | return; \ 794 | } else if (rbtn_red_get(a_type, a_field, pathp->node)) { \ 795 | a_type *leftleft = rbtn_left_get(a_type, a_field, left);\ 796 | if (rbtn_red_get(a_type, a_field, leftleft)) { \ 797 | /* || */\ 798 | /* pathp(r) */\ 799 | /* / \\ */\ 800 | /* (b) (b) */\ 801 | /* / */\ 802 | /* (r) */\ 803 | a_type *tnode; \ 804 | rbtn_black_set(a_type, a_field, pathp->node); \ 805 | rbtn_red_set(a_type, a_field, left); \ 806 | rbtn_black_set(a_type, a_field, leftleft); \ 807 | rbtn_rotate_right(a_type, a_field, pathp->node, \ 808 | tnode); \ 809 | /* Balance restored, but rotation modified */\ 810 | /* subtree root. */\ 811 | assert((uintptr_t)pathp > (uintptr_t)path); \ 812 | if (pathp[-1].cmp < 0) { \ 813 | rbtn_left_set(a_type, a_field, pathp[-1].node, \ 814 | tnode); \ 815 | } else { \ 816 | rbtn_right_set(a_type, a_field, pathp[-1].node, \ 817 | tnode); \ 818 | } \ 819 | return; \ 820 | } else { \ 821 | /* || */\ 822 | /* pathp(r) */\ 823 | /* / \\ */\ 824 | /* (b) (b) */\ 825 | /* / */\ 826 | /* (b) */\ 827 | rbtn_red_set(a_type, a_field, left); \ 828 | rbtn_black_set(a_type, a_field, pathp->node); \ 829 | /* Balance restored. */ \ 830 | return; \ 831 | } \ 832 | } else { \ 833 | a_type *leftleft = rbtn_left_get(a_type, a_field, left);\ 834 | if (rbtn_red_get(a_type, a_field, leftleft)) { \ 835 | /* || */\ 836 | /* pathp(b) */\ 837 | /* / \\ */\ 838 | /* (b) (b) */\ 839 | /* / */\ 840 | /* (r) */\ 841 | a_type *tnode; \ 842 | rbtn_black_set(a_type, a_field, leftleft); \ 843 | rbtn_rotate_right(a_type, a_field, pathp->node, \ 844 | tnode); \ 845 | /* Balance restored, but rotation modified */\ 846 | /* subtree root, which may actually be the tree */\ 847 | /* root. */\ 848 | if (pathp == path) { \ 849 | /* Set root. */ \ 850 | rbtree->rbt_root = tnode; \ 851 | } else { \ 852 | if (pathp[-1].cmp < 0) { \ 853 | rbtn_left_set(a_type, a_field, \ 854 | pathp[-1].node, tnode); \ 855 | } else { \ 856 | rbtn_right_set(a_type, a_field, \ 857 | pathp[-1].node, tnode); \ 858 | } \ 859 | } \ 860 | return; \ 861 | } else { \ 862 | /* || */\ 863 | /* pathp(b) */\ 864 | /* / \\ */\ 865 | /* (b) (b) */\ 866 | /* / */\ 867 | /* (b) */\ 868 | rbtn_red_set(a_type, a_field, left); \ 869 | } \ 870 | } \ 871 | } \ 872 | } \ 873 | /* Set root. */ \ 874 | rbtree->rbt_root = path->node; \ 875 | assert(rbtn_red_get(a_type, a_field, rbtree->rbt_root) == false); \ 876 | } \ 877 | a_attr a_type * \ 878 | a_prefix##iter_recurse(a_rbt_type *rbtree, a_type *node, \ 879 | a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) { \ 880 | if (node == &rbtree->rbt_nil) { \ 881 | return (&rbtree->rbt_nil); \ 882 | } else { \ 883 | a_type *ret; \ 884 | if ((ret = a_prefix##iter_recurse(rbtree, rbtn_left_get(a_type, \ 885 | a_field, node), cb, arg)) != &rbtree->rbt_nil \ 886 | || (ret = cb(rbtree, node, arg)) != NULL) { \ 887 | return (ret); \ 888 | } \ 889 | return (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type, \ 890 | a_field, node), cb, arg)); \ 891 | } \ 892 | } \ 893 | a_attr a_type * \ 894 | a_prefix##iter_start(a_rbt_type *rbtree, a_type *start, a_type *node, \ 895 | a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) { \ 896 | int cmp = a_cmp(start, node); \ 897 | if (cmp < 0) { \ 898 | a_type *ret; \ 899 | if ((ret = a_prefix##iter_start(rbtree, start, \ 900 | rbtn_left_get(a_type, a_field, node), cb, arg)) != \ 901 | &rbtree->rbt_nil || (ret = cb(rbtree, node, arg)) != NULL) { \ 902 | return (ret); \ 903 | } \ 904 | return (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type, \ 905 | a_field, node), cb, arg)); \ 906 | } else if (cmp > 0) { \ 907 | return (a_prefix##iter_start(rbtree, start, \ 908 | rbtn_right_get(a_type, a_field, node), cb, arg)); \ 909 | } else { \ 910 | a_type *ret; \ 911 | if ((ret = cb(rbtree, node, arg)) != NULL) { \ 912 | return (ret); \ 913 | } \ 914 | return (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type, \ 915 | a_field, node), cb, arg)); \ 916 | } \ 917 | } \ 918 | a_attr a_type * \ 919 | a_prefix##iter(a_rbt_type *rbtree, a_type *start, a_type *(*cb)( \ 920 | a_rbt_type *, a_type *, void *), void *arg) { \ 921 | a_type *ret; \ 922 | if (start != NULL) { \ 923 | ret = a_prefix##iter_start(rbtree, start, rbtree->rbt_root, \ 924 | cb, arg); \ 925 | } else { \ 926 | ret = a_prefix##iter_recurse(rbtree, rbtree->rbt_root, cb, arg);\ 927 | } \ 928 | if (ret == &rbtree->rbt_nil) { \ 929 | ret = NULL; \ 930 | } \ 931 | return (ret); \ 932 | } \ 933 | a_attr a_type * \ 934 | a_prefix##reverse_iter_recurse(a_rbt_type *rbtree, a_type *node, \ 935 | a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) { \ 936 | if (node == &rbtree->rbt_nil) { \ 937 | return (&rbtree->rbt_nil); \ 938 | } else { \ 939 | a_type *ret; \ 940 | if ((ret = a_prefix##reverse_iter_recurse(rbtree, \ 941 | rbtn_right_get(a_type, a_field, node), cb, arg)) != \ 942 | &rbtree->rbt_nil || (ret = cb(rbtree, node, arg)) != NULL) { \ 943 | return (ret); \ 944 | } \ 945 | return (a_prefix##reverse_iter_recurse(rbtree, \ 946 | rbtn_left_get(a_type, a_field, node), cb, arg)); \ 947 | } \ 948 | } \ 949 | a_attr a_type * \ 950 | a_prefix##reverse_iter_start(a_rbt_type *rbtree, a_type *start, \ 951 | a_type *node, a_type *(*cb)(a_rbt_type *, a_type *, void *), \ 952 | void *arg) { \ 953 | int cmp = a_cmp(start, node); \ 954 | if (cmp > 0) { \ 955 | a_type *ret; \ 956 | if ((ret = a_prefix##reverse_iter_start(rbtree, start, \ 957 | rbtn_right_get(a_type, a_field, node), cb, arg)) != \ 958 | &rbtree->rbt_nil || (ret = cb(rbtree, node, arg)) != NULL) { \ 959 | return (ret); \ 960 | } \ 961 | return (a_prefix##reverse_iter_recurse(rbtree, \ 962 | rbtn_left_get(a_type, a_field, node), cb, arg)); \ 963 | } else if (cmp < 0) { \ 964 | return (a_prefix##reverse_iter_start(rbtree, start, \ 965 | rbtn_left_get(a_type, a_field, node), cb, arg)); \ 966 | } else { \ 967 | a_type *ret; \ 968 | if ((ret = cb(rbtree, node, arg)) != NULL) { \ 969 | return (ret); \ 970 | } \ 971 | return (a_prefix##reverse_iter_recurse(rbtree, \ 972 | rbtn_left_get(a_type, a_field, node), cb, arg)); \ 973 | } \ 974 | } \ 975 | a_attr a_type * \ 976 | a_prefix##reverse_iter(a_rbt_type *rbtree, a_type *start, \ 977 | a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) { \ 978 | a_type *ret; \ 979 | if (start != NULL) { \ 980 | ret = a_prefix##reverse_iter_start(rbtree, start, \ 981 | rbtree->rbt_root, cb, arg); \ 982 | } else { \ 983 | ret = a_prefix##reverse_iter_recurse(rbtree, rbtree->rbt_root, \ 984 | cb, arg); \ 985 | } \ 986 | if (ret == &rbtree->rbt_nil) { \ 987 | ret = NULL; \ 988 | } \ 989 | return (ret); \ 990 | } 991 | 992 | #endif /* RB_H_ */ 993 | -------------------------------------------------------------------------------- /critbit-test-tree.h: -------------------------------------------------------------------------------- 1 | /* $NetBSD: tree.h,v 1.8 2004/03/28 19:38:30 provos Exp $ */ 2 | /* $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $ */ 3 | /* $FreeBSD$ */ 4 | 5 | /*- 6 | * Copyright 2002 Niels Provos 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions 11 | * are met: 12 | * 1. Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef _SYS_TREE_H_ 31 | #define _SYS_TREE_H_ 32 | 33 | #ifdef __FreeBSD__ 34 | #include 35 | #endif 36 | 37 | /* 38 | * This file defines data structures for different types of trees: 39 | * splay trees and red-black trees. 40 | * 41 | * A splay tree is a self-organizing data structure. Every operation 42 | * on the tree causes a splay to happen. The splay moves the requested 43 | * node to the root of the tree and partly rebalances it. 44 | * 45 | * This has the benefit that request locality causes faster lookups as 46 | * the requested nodes move to the top of the tree. On the other hand, 47 | * every lookup causes memory writes. 48 | * 49 | * The Balance Theorem bounds the total access time for m operations 50 | * and n inserts on an initially empty tree as O((m + n)lg n). The 51 | * amortized cost for a sequence of m accesses to a splay tree is O(lg n); 52 | * 53 | * A red-black tree is a binary search tree with the node color as an 54 | * extra attribute. It fulfills a set of conditions: 55 | * - every search path from the root to a leaf consists of the 56 | * same number of black nodes, 57 | * - each red node (except for the root) has a black parent, 58 | * - each leaf node is black. 59 | * 60 | * Every operation on a red-black tree is bounded as O(lg n). 61 | * The maximum height of a red-black tree is 2lg (n+1). 62 | */ 63 | 64 | #define SPLAY_HEAD(name, type) \ 65 | struct name { \ 66 | struct type *sph_root; /* root of the tree */ \ 67 | } 68 | 69 | #define SPLAY_INITIALIZER(root) \ 70 | { NULL } 71 | 72 | #define SPLAY_INIT(root) do { \ 73 | (root)->sph_root = NULL; \ 74 | } while (/*CONSTCOND*/ 0) 75 | 76 | #define SPLAY_ENTRY(type) \ 77 | struct { \ 78 | struct type *spe_left; /* left element */ \ 79 | struct type *spe_right; /* right element */ \ 80 | } 81 | 82 | #define SPLAY_LEFT(elm, field) (elm)->field.spe_left 83 | #define SPLAY_RIGHT(elm, field) (elm)->field.spe_right 84 | #define SPLAY_ROOT(head) (head)->sph_root 85 | #define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL) 86 | 87 | /* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */ 88 | #define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \ 89 | SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \ 90 | SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ 91 | (head)->sph_root = tmp; \ 92 | } while (/*CONSTCOND*/ 0) 93 | 94 | #define SPLAY_ROTATE_LEFT(head, tmp, field) do { \ 95 | SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \ 96 | SPLAY_LEFT(tmp, field) = (head)->sph_root; \ 97 | (head)->sph_root = tmp; \ 98 | } while (/*CONSTCOND*/ 0) 99 | 100 | #define SPLAY_LINKLEFT(head, tmp, field) do { \ 101 | SPLAY_LEFT(tmp, field) = (head)->sph_root; \ 102 | tmp = (head)->sph_root; \ 103 | (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ 104 | } while (/*CONSTCOND*/ 0) 105 | 106 | #define SPLAY_LINKRIGHT(head, tmp, field) do { \ 107 | SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ 108 | tmp = (head)->sph_root; \ 109 | (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ 110 | } while (/*CONSTCOND*/ 0) 111 | 112 | #define SPLAY_ASSEMBLE(head, node, left, right, field) do { \ 113 | SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \ 114 | SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\ 115 | SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \ 116 | SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \ 117 | } while (/*CONSTCOND*/ 0) 118 | 119 | /* Generates prototypes and inline functions */ 120 | 121 | #define SPLAY_PROTOTYPE(name, type, field, cmp) \ 122 | void name##_SPLAY(struct name *, struct type *); \ 123 | void name##_SPLAY_MINMAX(struct name *, int); \ 124 | struct type *name##_SPLAY_INSERT(struct name *, struct type *); \ 125 | struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \ 126 | \ 127 | /* Finds the node with the same key as elm */ \ 128 | static __inline struct type * \ 129 | name##_SPLAY_FIND(struct name *head, struct type *elm) \ 130 | { \ 131 | if (SPLAY_EMPTY(head)) \ 132 | return(NULL); \ 133 | name##_SPLAY(head, elm); \ 134 | if ((cmp)(elm, (head)->sph_root) == 0) \ 135 | return (head->sph_root); \ 136 | return (NULL); \ 137 | } \ 138 | \ 139 | static __inline struct type * \ 140 | name##_SPLAY_NEXT(struct name *head, struct type *elm) \ 141 | { \ 142 | name##_SPLAY(head, elm); \ 143 | if (SPLAY_RIGHT(elm, field) != NULL) { \ 144 | elm = SPLAY_RIGHT(elm, field); \ 145 | while (SPLAY_LEFT(elm, field) != NULL) { \ 146 | elm = SPLAY_LEFT(elm, field); \ 147 | } \ 148 | } else \ 149 | elm = NULL; \ 150 | return (elm); \ 151 | } \ 152 | \ 153 | static __inline struct type * \ 154 | name##_SPLAY_MIN_MAX(struct name *head, int val) \ 155 | { \ 156 | name##_SPLAY_MINMAX(head, val); \ 157 | return (SPLAY_ROOT(head)); \ 158 | } 159 | 160 | /* Main splay operation. 161 | * Moves node close to the key of elm to top 162 | */ 163 | #define SPLAY_GENERATE(name, type, field, cmp) \ 164 | struct type * \ 165 | name##_SPLAY_INSERT(struct name *head, struct type *elm) \ 166 | { \ 167 | if (SPLAY_EMPTY(head)) { \ 168 | SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \ 169 | } else { \ 170 | int __comp; \ 171 | name##_SPLAY(head, elm); \ 172 | __comp = (cmp)(elm, (head)->sph_root); \ 173 | if(__comp < 0) { \ 174 | SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\ 175 | SPLAY_RIGHT(elm, field) = (head)->sph_root; \ 176 | SPLAY_LEFT((head)->sph_root, field) = NULL; \ 177 | } else if (__comp > 0) { \ 178 | SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\ 179 | SPLAY_LEFT(elm, field) = (head)->sph_root; \ 180 | SPLAY_RIGHT((head)->sph_root, field) = NULL; \ 181 | } else \ 182 | return ((head)->sph_root); \ 183 | } \ 184 | (head)->sph_root = (elm); \ 185 | return (NULL); \ 186 | } \ 187 | \ 188 | struct type * \ 189 | name##_SPLAY_REMOVE(struct name *head, struct type *elm) \ 190 | { \ 191 | struct type *__tmp; \ 192 | if (SPLAY_EMPTY(head)) \ 193 | return (NULL); \ 194 | name##_SPLAY(head, elm); \ 195 | if ((cmp)(elm, (head)->sph_root) == 0) { \ 196 | if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \ 197 | (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\ 198 | } else { \ 199 | __tmp = SPLAY_RIGHT((head)->sph_root, field); \ 200 | (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\ 201 | name##_SPLAY(head, elm); \ 202 | SPLAY_RIGHT((head)->sph_root, field) = __tmp; \ 203 | } \ 204 | return (elm); \ 205 | } \ 206 | return (NULL); \ 207 | } \ 208 | \ 209 | void \ 210 | name##_SPLAY(struct name *head, struct type *elm) \ 211 | { \ 212 | struct type __node, *__left, *__right, *__tmp; \ 213 | int __comp; \ 214 | \ 215 | SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ 216 | __left = __right = &__node; \ 217 | \ 218 | while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) { \ 219 | if (__comp < 0) { \ 220 | __tmp = SPLAY_LEFT((head)->sph_root, field); \ 221 | if (__tmp == NULL) \ 222 | break; \ 223 | if ((cmp)(elm, __tmp) < 0){ \ 224 | SPLAY_ROTATE_RIGHT(head, __tmp, field); \ 225 | if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ 226 | break; \ 227 | } \ 228 | SPLAY_LINKLEFT(head, __right, field); \ 229 | } else if (__comp > 0) { \ 230 | __tmp = SPLAY_RIGHT((head)->sph_root, field); \ 231 | if (__tmp == NULL) \ 232 | break; \ 233 | if ((cmp)(elm, __tmp) > 0){ \ 234 | SPLAY_ROTATE_LEFT(head, __tmp, field); \ 235 | if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ 236 | break; \ 237 | } \ 238 | SPLAY_LINKRIGHT(head, __left, field); \ 239 | } \ 240 | } \ 241 | SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ 242 | } \ 243 | \ 244 | /* Splay with either the minimum or the maximum element \ 245 | * Used to find minimum or maximum element in tree. \ 246 | */ \ 247 | void name##_SPLAY_MINMAX(struct name *head, int __comp) \ 248 | { \ 249 | struct type __node, *__left, *__right, *__tmp; \ 250 | \ 251 | SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ 252 | __left = __right = &__node; \ 253 | \ 254 | while (1) { \ 255 | if (__comp < 0) { \ 256 | __tmp = SPLAY_LEFT((head)->sph_root, field); \ 257 | if (__tmp == NULL) \ 258 | break; \ 259 | if (__comp < 0){ \ 260 | SPLAY_ROTATE_RIGHT(head, __tmp, field); \ 261 | if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ 262 | break; \ 263 | } \ 264 | SPLAY_LINKLEFT(head, __right, field); \ 265 | } else if (__comp > 0) { \ 266 | __tmp = SPLAY_RIGHT((head)->sph_root, field); \ 267 | if (__tmp == NULL) \ 268 | break; \ 269 | if (__comp > 0) { \ 270 | SPLAY_ROTATE_LEFT(head, __tmp, field); \ 271 | if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ 272 | break; \ 273 | } \ 274 | SPLAY_LINKRIGHT(head, __left, field); \ 275 | } \ 276 | } \ 277 | SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ 278 | } 279 | 280 | #define SPLAY_NEGINF -1 281 | #define SPLAY_INF 1 282 | 283 | #define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y) 284 | #define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y) 285 | #define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y) 286 | #define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y) 287 | #define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \ 288 | : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF)) 289 | #define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \ 290 | : name##_SPLAY_MIN_MAX(x, SPLAY_INF)) 291 | 292 | #define SPLAY_FOREACH(x, name, head) \ 293 | for ((x) = SPLAY_MIN(name, head); \ 294 | (x) != NULL; \ 295 | (x) = SPLAY_NEXT(name, head, x)) 296 | 297 | /* Macros that define a red-black tree */ 298 | #define RB_HEAD(name, type) \ 299 | struct name { \ 300 | struct type *rbh_root; /* root of the tree */ \ 301 | } 302 | 303 | #define RB_INITIALIZER(root) \ 304 | { NULL } 305 | 306 | #define RB_INIT(root) do { \ 307 | (root)->rbh_root = NULL; \ 308 | } while (/*CONSTCOND*/ 0) 309 | 310 | #define RB_BLACK 0 311 | #define RB_RED 1 312 | #define RB_ENTRY(type) \ 313 | struct { \ 314 | struct type *rbe_left; /* left element */ \ 315 | struct type *rbe_right; /* right element */ \ 316 | struct type *rbe_parent; /* parent element */ \ 317 | int rbe_color; /* node color */ \ 318 | } 319 | 320 | #define RB_LEFT(elm, field) (elm)->field.rbe_left 321 | #define RB_RIGHT(elm, field) (elm)->field.rbe_right 322 | #define RB_PARENT(elm, field) (elm)->field.rbe_parent 323 | #define RB_COLOR(elm, field) (elm)->field.rbe_color 324 | #define RB_ROOT(head) (head)->rbh_root 325 | #define RB_EMPTY(head) (RB_ROOT(head) == NULL) 326 | 327 | #define RB_SET(elm, parent, field) do { \ 328 | RB_PARENT(elm, field) = parent; \ 329 | RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ 330 | RB_COLOR(elm, field) = RB_RED; \ 331 | } while (/*CONSTCOND*/ 0) 332 | 333 | #define RB_SET_BLACKRED(black, red, field) do { \ 334 | RB_COLOR(black, field) = RB_BLACK; \ 335 | RB_COLOR(red, field) = RB_RED; \ 336 | } while (/*CONSTCOND*/ 0) 337 | 338 | #ifndef RB_AUGMENT 339 | #define RB_AUGMENT(x) do {} while (0) 340 | #endif 341 | 342 | #define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ 343 | (tmp) = RB_RIGHT(elm, field); \ 344 | if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \ 345 | RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \ 346 | } \ 347 | RB_AUGMENT(elm); \ 348 | if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ 349 | if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ 350 | RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ 351 | else \ 352 | RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ 353 | } else \ 354 | (head)->rbh_root = (tmp); \ 355 | RB_LEFT(tmp, field) = (elm); \ 356 | RB_PARENT(elm, field) = (tmp); \ 357 | RB_AUGMENT(tmp); \ 358 | if ((RB_PARENT(tmp, field))) \ 359 | RB_AUGMENT(RB_PARENT(tmp, field)); \ 360 | } while (/*CONSTCOND*/ 0) 361 | 362 | #define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ 363 | (tmp) = RB_LEFT(elm, field); \ 364 | if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \ 365 | RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \ 366 | } \ 367 | RB_AUGMENT(elm); \ 368 | if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ 369 | if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ 370 | RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ 371 | else \ 372 | RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ 373 | } else \ 374 | (head)->rbh_root = (tmp); \ 375 | RB_RIGHT(tmp, field) = (elm); \ 376 | RB_PARENT(elm, field) = (tmp); \ 377 | RB_AUGMENT(tmp); \ 378 | if ((RB_PARENT(tmp, field))) \ 379 | RB_AUGMENT(RB_PARENT(tmp, field)); \ 380 | } while (/*CONSTCOND*/ 0) 381 | 382 | /* Generates prototypes and inline functions */ 383 | #define RB_PROTOTYPE(name, type, field, cmp) \ 384 | RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) 385 | #define RB_PROTOTYPE_STATIC(name, type, field, cmp) \ 386 | RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static) 387 | #define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \ 388 | attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \ 389 | attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ 390 | attr struct type *name##_RB_REMOVE(struct name *, struct type *); \ 391 | attr struct type *name##_RB_INSERT(struct name *, struct type *); \ 392 | attr struct type *name##_RB_FIND(struct name *, struct type *); \ 393 | attr struct type *name##_RB_NFIND(struct name *, struct type *); \ 394 | attr struct type *name##_RB_NEXT(struct type *); \ 395 | attr struct type *name##_RB_PREV(struct type *); \ 396 | attr struct type *name##_RB_MINMAX(struct name *, int); \ 397 | \ 398 | 399 | /* Main rb operation. 400 | * Moves node close to the key of elm to top 401 | */ 402 | #define RB_GENERATE(name, type, field, cmp) \ 403 | RB_GENERATE_INTERNAL(name, type, field, cmp,) 404 | #define RB_GENERATE_STATIC(name, type, field, cmp) \ 405 | RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static) 406 | #define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \ 407 | attr void \ 408 | name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ 409 | { \ 410 | struct type *parent, *gparent, *tmp; \ 411 | while ((parent = RB_PARENT(elm, field)) != NULL && \ 412 | RB_COLOR(parent, field) == RB_RED) { \ 413 | gparent = RB_PARENT(parent, field); \ 414 | if (parent == RB_LEFT(gparent, field)) { \ 415 | tmp = RB_RIGHT(gparent, field); \ 416 | if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ 417 | RB_COLOR(tmp, field) = RB_BLACK; \ 418 | RB_SET_BLACKRED(parent, gparent, field);\ 419 | elm = gparent; \ 420 | continue; \ 421 | } \ 422 | if (RB_RIGHT(parent, field) == elm) { \ 423 | RB_ROTATE_LEFT(head, parent, tmp, field);\ 424 | tmp = parent; \ 425 | parent = elm; \ 426 | elm = tmp; \ 427 | } \ 428 | RB_SET_BLACKRED(parent, gparent, field); \ 429 | RB_ROTATE_RIGHT(head, gparent, tmp, field); \ 430 | } else { \ 431 | tmp = RB_LEFT(gparent, field); \ 432 | if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ 433 | RB_COLOR(tmp, field) = RB_BLACK; \ 434 | RB_SET_BLACKRED(parent, gparent, field);\ 435 | elm = gparent; \ 436 | continue; \ 437 | } \ 438 | if (RB_LEFT(parent, field) == elm) { \ 439 | RB_ROTATE_RIGHT(head, parent, tmp, field);\ 440 | tmp = parent; \ 441 | parent = elm; \ 442 | elm = tmp; \ 443 | } \ 444 | RB_SET_BLACKRED(parent, gparent, field); \ 445 | RB_ROTATE_LEFT(head, gparent, tmp, field); \ 446 | } \ 447 | } \ 448 | RB_COLOR(head->rbh_root, field) = RB_BLACK; \ 449 | } \ 450 | \ 451 | attr void \ 452 | name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \ 453 | { \ 454 | struct type *tmp; \ 455 | while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \ 456 | elm != RB_ROOT(head)) { \ 457 | if (RB_LEFT(parent, field) == elm) { \ 458 | tmp = RB_RIGHT(parent, field); \ 459 | if (RB_COLOR(tmp, field) == RB_RED) { \ 460 | RB_SET_BLACKRED(tmp, parent, field); \ 461 | RB_ROTATE_LEFT(head, parent, tmp, field);\ 462 | tmp = RB_RIGHT(parent, field); \ 463 | } \ 464 | if ((RB_LEFT(tmp, field) == NULL || \ 465 | RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ 466 | (RB_RIGHT(tmp, field) == NULL || \ 467 | RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ 468 | RB_COLOR(tmp, field) = RB_RED; \ 469 | elm = parent; \ 470 | parent = RB_PARENT(elm, field); \ 471 | } else { \ 472 | if (RB_RIGHT(tmp, field) == NULL || \ 473 | RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\ 474 | struct type *oleft; \ 475 | if ((oleft = RB_LEFT(tmp, field)) \ 476 | != NULL) \ 477 | RB_COLOR(oleft, field) = RB_BLACK;\ 478 | RB_COLOR(tmp, field) = RB_RED; \ 479 | RB_ROTATE_RIGHT(head, tmp, oleft, field);\ 480 | tmp = RB_RIGHT(parent, field); \ 481 | } \ 482 | RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ 483 | RB_COLOR(parent, field) = RB_BLACK; \ 484 | if (RB_RIGHT(tmp, field)) \ 485 | RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\ 486 | RB_ROTATE_LEFT(head, parent, tmp, field);\ 487 | elm = RB_ROOT(head); \ 488 | break; \ 489 | } \ 490 | } else { \ 491 | tmp = RB_LEFT(parent, field); \ 492 | if (RB_COLOR(tmp, field) == RB_RED) { \ 493 | RB_SET_BLACKRED(tmp, parent, field); \ 494 | RB_ROTATE_RIGHT(head, parent, tmp, field);\ 495 | tmp = RB_LEFT(parent, field); \ 496 | } \ 497 | if ((RB_LEFT(tmp, field) == NULL || \ 498 | RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ 499 | (RB_RIGHT(tmp, field) == NULL || \ 500 | RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ 501 | RB_COLOR(tmp, field) = RB_RED; \ 502 | elm = parent; \ 503 | parent = RB_PARENT(elm, field); \ 504 | } else { \ 505 | if (RB_LEFT(tmp, field) == NULL || \ 506 | RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\ 507 | struct type *oright; \ 508 | if ((oright = RB_RIGHT(tmp, field)) \ 509 | != NULL) \ 510 | RB_COLOR(oright, field) = RB_BLACK;\ 511 | RB_COLOR(tmp, field) = RB_RED; \ 512 | RB_ROTATE_LEFT(head, tmp, oright, field);\ 513 | tmp = RB_LEFT(parent, field); \ 514 | } \ 515 | RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ 516 | RB_COLOR(parent, field) = RB_BLACK; \ 517 | if (RB_LEFT(tmp, field)) \ 518 | RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\ 519 | RB_ROTATE_RIGHT(head, parent, tmp, field);\ 520 | elm = RB_ROOT(head); \ 521 | break; \ 522 | } \ 523 | } \ 524 | } \ 525 | if (elm) \ 526 | RB_COLOR(elm, field) = RB_BLACK; \ 527 | } \ 528 | \ 529 | attr struct type * \ 530 | name##_RB_REMOVE(struct name *head, struct type *elm) \ 531 | { \ 532 | struct type *child, *parent, *old = elm; \ 533 | int color; \ 534 | if (RB_LEFT(elm, field) == NULL) \ 535 | child = RB_RIGHT(elm, field); \ 536 | else if (RB_RIGHT(elm, field) == NULL) \ 537 | child = RB_LEFT(elm, field); \ 538 | else { \ 539 | struct type *left; \ 540 | elm = RB_RIGHT(elm, field); \ 541 | while ((left = RB_LEFT(elm, field)) != NULL) \ 542 | elm = left; \ 543 | child = RB_RIGHT(elm, field); \ 544 | parent = RB_PARENT(elm, field); \ 545 | color = RB_COLOR(elm, field); \ 546 | if (child) \ 547 | RB_PARENT(child, field) = parent; \ 548 | if (parent) { \ 549 | if (RB_LEFT(parent, field) == elm) \ 550 | RB_LEFT(parent, field) = child; \ 551 | else \ 552 | RB_RIGHT(parent, field) = child; \ 553 | RB_AUGMENT(parent); \ 554 | } else \ 555 | RB_ROOT(head) = child; \ 556 | if (RB_PARENT(elm, field) == old) \ 557 | parent = elm; \ 558 | (elm)->field = (old)->field; \ 559 | if (RB_PARENT(old, field)) { \ 560 | if (RB_LEFT(RB_PARENT(old, field), field) == old)\ 561 | RB_LEFT(RB_PARENT(old, field), field) = elm;\ 562 | else \ 563 | RB_RIGHT(RB_PARENT(old, field), field) = elm;\ 564 | RB_AUGMENT(RB_PARENT(old, field)); \ 565 | } else \ 566 | RB_ROOT(head) = elm; \ 567 | RB_PARENT(RB_LEFT(old, field), field) = elm; \ 568 | if (RB_RIGHT(old, field)) \ 569 | RB_PARENT(RB_RIGHT(old, field), field) = elm; \ 570 | if (parent) { \ 571 | left = parent; \ 572 | do { \ 573 | RB_AUGMENT(left); \ 574 | } while ((left = RB_PARENT(left, field)) != NULL); \ 575 | } \ 576 | goto color; \ 577 | } \ 578 | parent = RB_PARENT(elm, field); \ 579 | color = RB_COLOR(elm, field); \ 580 | if (child) \ 581 | RB_PARENT(child, field) = parent; \ 582 | if (parent) { \ 583 | if (RB_LEFT(parent, field) == elm) \ 584 | RB_LEFT(parent, field) = child; \ 585 | else \ 586 | RB_RIGHT(parent, field) = child; \ 587 | RB_AUGMENT(parent); \ 588 | } else \ 589 | RB_ROOT(head) = child; \ 590 | color: \ 591 | if (color == RB_BLACK) \ 592 | name##_RB_REMOVE_COLOR(head, parent, child); \ 593 | return (old); \ 594 | } \ 595 | \ 596 | /* Inserts a node into the RB tree */ \ 597 | attr struct type * \ 598 | name##_RB_INSERT(struct name *head, struct type *elm) \ 599 | { \ 600 | struct type *tmp; \ 601 | struct type *parent = NULL; \ 602 | int comp = 0; \ 603 | tmp = RB_ROOT(head); \ 604 | while (tmp) { \ 605 | parent = tmp; \ 606 | comp = (cmp)(elm, parent); \ 607 | if (comp < 0) \ 608 | tmp = RB_LEFT(tmp, field); \ 609 | else if (comp > 0) \ 610 | tmp = RB_RIGHT(tmp, field); \ 611 | else \ 612 | return (tmp); \ 613 | } \ 614 | RB_SET(elm, parent, field); \ 615 | if (parent != NULL) { \ 616 | if (comp < 0) \ 617 | RB_LEFT(parent, field) = elm; \ 618 | else \ 619 | RB_RIGHT(parent, field) = elm; \ 620 | RB_AUGMENT(parent); \ 621 | } else \ 622 | RB_ROOT(head) = elm; \ 623 | name##_RB_INSERT_COLOR(head, elm); \ 624 | return (NULL); \ 625 | } \ 626 | \ 627 | /* Finds the node with the same key as elm */ \ 628 | attr struct type * \ 629 | name##_RB_FIND(struct name *head, struct type *elm) \ 630 | { \ 631 | struct type *tmp = RB_ROOT(head); \ 632 | int comp; \ 633 | while (tmp) { \ 634 | comp = cmp(elm, tmp); \ 635 | if (comp < 0) \ 636 | tmp = RB_LEFT(tmp, field); \ 637 | else if (comp > 0) \ 638 | tmp = RB_RIGHT(tmp, field); \ 639 | else \ 640 | return (tmp); \ 641 | } \ 642 | return (NULL); \ 643 | } \ 644 | \ 645 | /* Finds the first node greater than or equal to the search key */ \ 646 | attr struct type * \ 647 | name##_RB_NFIND(struct name *head, struct type *elm) \ 648 | { \ 649 | struct type *tmp = RB_ROOT(head); \ 650 | struct type *res = NULL; \ 651 | int comp; \ 652 | while (tmp) { \ 653 | comp = cmp(elm, tmp); \ 654 | if (comp < 0) { \ 655 | res = tmp; \ 656 | tmp = RB_LEFT(tmp, field); \ 657 | } \ 658 | else if (comp > 0) \ 659 | tmp = RB_RIGHT(tmp, field); \ 660 | else \ 661 | return (tmp); \ 662 | } \ 663 | return (res); \ 664 | } \ 665 | \ 666 | /* ARGSUSED */ \ 667 | attr struct type * \ 668 | name##_RB_NEXT(struct type *elm) \ 669 | { \ 670 | if (RB_RIGHT(elm, field)) { \ 671 | elm = RB_RIGHT(elm, field); \ 672 | while (RB_LEFT(elm, field)) \ 673 | elm = RB_LEFT(elm, field); \ 674 | } else { \ 675 | if (RB_PARENT(elm, field) && \ 676 | (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ 677 | elm = RB_PARENT(elm, field); \ 678 | else { \ 679 | while (RB_PARENT(elm, field) && \ 680 | (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\ 681 | elm = RB_PARENT(elm, field); \ 682 | elm = RB_PARENT(elm, field); \ 683 | } \ 684 | } \ 685 | return (elm); \ 686 | } \ 687 | \ 688 | /* ARGSUSED */ \ 689 | attr struct type * \ 690 | name##_RB_PREV(struct type *elm) \ 691 | { \ 692 | if (RB_LEFT(elm, field)) { \ 693 | elm = RB_LEFT(elm, field); \ 694 | while (RB_RIGHT(elm, field)) \ 695 | elm = RB_RIGHT(elm, field); \ 696 | } else { \ 697 | if (RB_PARENT(elm, field) && \ 698 | (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ 699 | elm = RB_PARENT(elm, field); \ 700 | else { \ 701 | while (RB_PARENT(elm, field) && \ 702 | (elm == RB_LEFT(RB_PARENT(elm, field), field)))\ 703 | elm = RB_PARENT(elm, field); \ 704 | elm = RB_PARENT(elm, field); \ 705 | } \ 706 | } \ 707 | return (elm); \ 708 | } \ 709 | \ 710 | attr struct type * \ 711 | name##_RB_MINMAX(struct name *head, int val) \ 712 | { \ 713 | struct type *tmp = RB_ROOT(head); \ 714 | struct type *parent = NULL; \ 715 | while (tmp) { \ 716 | parent = tmp; \ 717 | if (val < 0) \ 718 | tmp = RB_LEFT(tmp, field); \ 719 | else \ 720 | tmp = RB_RIGHT(tmp, field); \ 721 | } \ 722 | return (parent); \ 723 | } 724 | 725 | #define RB_NEGINF -1 726 | #define RB_INF 1 727 | 728 | #define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) 729 | #define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) 730 | #define RB_FIND(name, x, y) name##_RB_FIND(x, y) 731 | #define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) 732 | #define RB_NEXT(name, x, y) name##_RB_NEXT(y) 733 | #define RB_PREV(name, x, y) name##_RB_PREV(y) 734 | #define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) 735 | #define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) 736 | 737 | #define RB_FOREACH(x, name, head) \ 738 | for ((x) = RB_MIN(name, head); \ 739 | (x) != NULL; \ 740 | (x) = name##_RB_NEXT(x)) 741 | 742 | #define RB_FOREACH_FROM(x, name, y) \ 743 | for ((x) = (y); \ 744 | ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ 745 | (x) = (y)) 746 | 747 | #define RB_FOREACH_SAFE(x, name, head, y) \ 748 | for ((x) = RB_MIN(name, head); \ 749 | ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ 750 | (x) = (y)) 751 | 752 | #define RB_FOREACH_REVERSE(x, name, head) \ 753 | for ((x) = RB_MAX(name, head); \ 754 | (x) != NULL; \ 755 | (x) = name##_RB_PREV(x)) 756 | 757 | #define RB_FOREACH_REVERSE_FROM(x, name, y) \ 758 | for ((x) = (y); \ 759 | ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ 760 | (x) = (y)) 761 | 762 | #define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \ 763 | for ((x) = RB_MAX(name, head); \ 764 | ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ 765 | (x) = (y)) 766 | 767 | #endif /* _SYS_TREE_H_ */ 768 | -------------------------------------------------------------------------------- /critbit-test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This code, like Prof. Bernstein's original code, 3 | * is released into the public domain. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "critbit.h" 16 | 17 | #define RB_COMPACT 18 | #include "critbit-test-rb.h" 19 | #include "critbit-test-tree.h" 20 | #include "critbit-test-data.h" 21 | 22 | #ifndef __unused 23 | #define __unused 24 | #endif 25 | 26 | static const char *elems[] = { 27 | "a", "aa", "b", "bb", "ab", "ba", "aba", "bab", NULL 28 | }; 29 | 30 | struct element { 31 | int pad; 32 | const char *k; 33 | int64_t kint; 34 | RB_ENTRY(element) rbentry; 35 | rb_node(struct element) nrb_link; 36 | }; 37 | 38 | CRITBIT_HEAD_PROTOTYPE(eltree); 39 | CRITBIT_GENERATE_STATIC(eltree, element, str, k); 40 | 41 | CRITBIT_HEAD_PROTOTYPE(elinttree); 42 | CRITBIT_GENERATE_STATIC(elinttree, element, int64, kint); 43 | 44 | static int 45 | rbtree_cmp(struct element *a, struct element *b) 46 | { 47 | return strcmp(a->k, b->k); 48 | } 49 | 50 | static int 51 | rbinttree_cmp(struct element *a, struct element *b) 52 | { 53 | return a->kint - b->kint; 54 | } 55 | 56 | RB_HEAD(rbtree, element); 57 | RB_GENERATE_STATIC(rbtree, element, rbentry, rbtree_cmp); 58 | 59 | RB_HEAD(rbinttree, element); 60 | RB_GENERATE_STATIC(rbinttree, element, rbentry, rbinttree_cmp); 61 | 62 | typedef rbt(struct element) nrb_tree; 63 | rb_gen(static __unused, nrb_, nrb_tree, struct element, nrb_link, rbinttree_cmp); 64 | 65 | static void 66 | std_free(void *arg __unused, void *node) 67 | { 68 | free(node); 69 | } 70 | 71 | static void 72 | no_free(void *arg __unused, void *node __unused) 73 | { 74 | } 75 | 76 | static struct element * 77 | el_alloc(void) 78 | { 79 | return malloc(sizeof(struct element)); 80 | } 81 | 82 | static void 83 | test_contains(void) 84 | { 85 | CRITBIT_HEAD(eltree) tree; 86 | struct element *el; 87 | struct critbit_node *nnode; 88 | int i; 89 | 90 | CRITBIT_INIT(eltree, &tree, std_free, NULL); 91 | 92 | for (i = 0; elems[i]; ++i) { 93 | el = el_alloc(); 94 | el->k = elems[i]; 95 | nnode = malloc(critbit_node_size()); 96 | CRITBIT_INSERT(eltree, &tree, nnode, el); 97 | } 98 | 99 | for (i = 0; elems[i]; ++i) { 100 | el = CRITBIT_GET(eltree, &tree, elems[i]); 101 | if (el == NULL) 102 | abort(); 103 | } 104 | } 105 | 106 | static void 107 | test_delete(void) 108 | { 109 | CRITBIT_HEAD(eltree) tree; 110 | struct element *el; 111 | struct critbit_node *nnode; 112 | int i, j; 113 | 114 | CRITBIT_INIT(eltree, &tree, std_free, NULL); 115 | 116 | for (i = 1; elems[i]; ++i) { 117 | 118 | for (j = 0; j < i; ++j) { 119 | el = el_alloc(); 120 | el->k = elems[j]; 121 | nnode = malloc(critbit_node_size()); 122 | el = CRITBIT_INSERT(eltree, &tree, nnode, el); 123 | if (el != NULL) 124 | abort(); 125 | } 126 | for (j = 0; j < i; ++j) { 127 | if (CRITBIT_GET(eltree, &tree, elems[j]) == NULL) 128 | abort(); 129 | } 130 | for (j = 0; j < i; ++j) { 131 | el = CRITBIT_REMOVE(eltree, &tree, elems[j]); 132 | if (el == NULL) 133 | abort(); 134 | free(el); 135 | } 136 | for (j = 0; j < i; ++j) { 137 | if (CRITBIT_GET(eltree, &tree, elems[j]) != NULL) 138 | abort(); 139 | } 140 | } 141 | } 142 | 143 | const int loopcnt_init = 1000; 144 | const int loopcnt_int_init = 2000; 145 | 146 | static void 147 | benchmark_result(const char *name, intmax_t n, struct timeval *tstart, struct timeval *tend) 148 | { 149 | double t; 150 | 151 | t = tend->tv_sec - tstart->tv_sec; 152 | t += (double)(tend->tv_usec - tstart->tv_usec) / (double)1000000; 153 | printf("%16s: %jd iterations in %lf seconds; %lf iterations/s\n", 154 | name, n, t, (double)n/t); 155 | } 156 | 157 | static void 158 | test_benchmark_critbit_int(void) 159 | { 160 | CRITBIT_HEAD(elinttree) tree; 161 | struct element *el, *xel; 162 | char *xnode, *xnode_saved; 163 | int i, j, sz = critbit_node_size(); 164 | 165 | xnode_saved = xnode = malloc(sz * loopcnt_int_init); 166 | xel = malloc(sizeof(*el) * loopcnt_int_init); 167 | 168 | struct timeval tstart, tend; 169 | gettimeofday(&tstart, NULL); 170 | 171 | for (i = 1; i < loopcnt_int_init; ++i) { 172 | 173 | CRITBIT_INIT(elinttree, &tree, no_free, NULL); 174 | xnode = xnode_saved; 175 | 176 | for (j = 0; j < i; ++j) { 177 | el = &xel[j]; 178 | el->kint = j; 179 | el = CRITBIT_INSERT(elinttree, &tree, 180 | (struct critbit_node *)xnode, el); 181 | xnode += sz; 182 | if (el != NULL) 183 | abort(); 184 | } 185 | for (j = 0; j < i; ++j) { 186 | if (CRITBIT_GET(elinttree, &tree, j) == NULL) 187 | abort(); 188 | if (CRITBIT_GET(elinttree, &tree, j) == NULL) 189 | abort(); 190 | if (CRITBIT_GET(elinttree, &tree, j) == NULL) 191 | abort(); 192 | if (CRITBIT_GET(elinttree, &tree, j) == NULL) 193 | abort(); 194 | } 195 | } 196 | 197 | gettimeofday(&tend, NULL); 198 | 199 | benchmark_result("critbit int", loopcnt_int_init, &tstart, &tend); 200 | } 201 | 202 | static __inline uint32_t 203 | hashint(uintptr_t h) 204 | { 205 | h = (~h) + (h << 18); 206 | h = h ^ (h >> 31); 207 | h = h * 21; 208 | h = h ^ (h >> 11); 209 | h = h + (h << 6); 210 | h = h ^ (h >> 22); 211 | return (h); 212 | } 213 | 214 | static void 215 | test_benchmark_critbit_hash_int(void) 216 | { 217 | CRITBIT_HEAD(elinttree) tree; 218 | struct element *el, *xel; 219 | char *xnode, *xnode_saved; 220 | int i, j, *k, sz = critbit_node_size(); 221 | 222 | xnode_saved = xnode = malloc(sz * loopcnt_int_init); 223 | xel = malloc(sizeof(*el) * loopcnt_int_init); 224 | k = malloc(sizeof(int) * loopcnt_int_init); 225 | 226 | struct timeval tstart, tend; 227 | gettimeofday(&tstart, NULL); 228 | 229 | #define KEY(a) k[(a)] 230 | 231 | for (i = 1; i < loopcnt_int_init; ++i) { 232 | 233 | CRITBIT_INIT(elinttree, &tree, no_free, NULL); 234 | xnode = xnode_saved; 235 | 236 | for (j = 0; j < i; ++j) { 237 | el = &xel[j]; 238 | k[j] = hashint(j); 239 | el->kint = KEY(j); 240 | el = CRITBIT_INSERT(elinttree, &tree, 241 | (struct critbit_node *)xnode, el); 242 | xnode += sz; 243 | if (el != NULL) 244 | abort(); 245 | } 246 | for (j = 0; j < i; ++j) { 247 | if (CRITBIT_GET(elinttree, &tree, KEY(j)) == NULL) 248 | abort(); 249 | if (CRITBIT_GET(elinttree, &tree, KEY(j)) == NULL) 250 | abort(); 251 | if (CRITBIT_GET(elinttree, &tree, KEY(j)) == NULL) 252 | abort(); 253 | if (CRITBIT_GET(elinttree, &tree, KEY(j)) == NULL) 254 | abort(); 255 | } 256 | } 257 | 258 | gettimeofday(&tend, NULL); 259 | 260 | benchmark_result("critbit hash int", loopcnt_int_init, &tstart, &tend); 261 | } 262 | 263 | static void 264 | test_benchmark_rbtree_int(void) 265 | { 266 | struct rbinttree tree; 267 | struct element find, *el, *xel; 268 | int i, j; 269 | 270 | xel = malloc(sizeof(*el) * loopcnt_int_init); 271 | 272 | struct timeval tstart, tend; 273 | gettimeofday(&tstart, NULL); 274 | 275 | for (i = 1; i < loopcnt_int_init; ++i) { 276 | 277 | RB_INIT(&tree); 278 | 279 | for (j = 0; j < i; ++j) { 280 | el = &xel[j]; 281 | el->kint = j; 282 | el = RB_INSERT(rbinttree, &tree, el); 283 | if (el != NULL) 284 | abort(); 285 | } 286 | for (j = 0; j < i; ++j) { 287 | find.kint = j; 288 | if (RB_FIND(rbinttree, &tree, &find) == NULL) 289 | abort(); 290 | find.kint = j; 291 | if (RB_FIND(rbinttree, &tree, &find) == NULL) 292 | abort(); 293 | find.kint = j; 294 | if (RB_FIND(rbinttree, &tree, &find) == NULL) 295 | abort(); 296 | find.kint = j; 297 | if (RB_FIND(rbinttree, &tree, &find) == NULL) 298 | abort(); 299 | } 300 | } 301 | 302 | gettimeofday(&tend, NULL); 303 | 304 | benchmark_result("rbtree int", loopcnt_int_init, &tstart, &tend); 305 | } 306 | 307 | static void 308 | test_benchmark_nrbtree_int(void) 309 | { 310 | nrb_tree tree; 311 | struct element find, *el, *xel; 312 | int i, j; 313 | 314 | xel = malloc(sizeof(*el) * loopcnt_int_init); 315 | 316 | struct timeval tstart, tend; 317 | gettimeofday(&tstart, NULL); 318 | 319 | for (i = 1; i < loopcnt_int_init; ++i) { 320 | 321 | nrb_new(&tree); 322 | 323 | for (j = 0; j < i; ++j) { 324 | el = &xel[j]; 325 | el->kint = j; 326 | nrb_insert(&tree, el); 327 | } 328 | for (j = 0; j < i; ++j) { 329 | find.kint = j; 330 | if (nrb_search(&tree, &find) == NULL) 331 | abort(); 332 | find.kint = j; 333 | if (nrb_search(&tree, &find) == NULL) 334 | abort(); 335 | find.kint = j; 336 | if (nrb_search(&tree, &find) == NULL) 337 | abort(); 338 | find.kint = j; 339 | if (nrb_search(&tree, &find) == NULL) 340 | abort(); 341 | } 342 | } 343 | 344 | gettimeofday(&tend, NULL); 345 | 346 | benchmark_result("nrbtree int", loopcnt_int_init, &tstart, &tend); 347 | } 348 | 349 | static void 350 | test_benchmark_critbit(void) 351 | { 352 | CRITBIT_HEAD(eltree) tree; 353 | struct element *el, *test_data_el; 354 | struct critbit_node *nnode; 355 | int cnt; 356 | int i; 357 | 358 | CRITBIT_INIT(eltree, &tree, no_free, NULL); 359 | 360 | for (cnt = 0; test_data[cnt]; ) { 361 | cnt++; 362 | } 363 | test_data_el = malloc(cnt * sizeof(*test_data_el)); 364 | 365 | int loopcnt = loopcnt_init; 366 | struct timeval tstart, tend; 367 | 368 | gettimeofday(&tstart, NULL); 369 | 370 | again: 371 | for (i = 0; i < cnt; ++i) { 372 | el = &test_data_el[i]; 373 | el->k = test_data[i]; 374 | nnode = malloc(critbit_node_size()); 375 | CRITBIT_INSERT(eltree, &tree, nnode, el); 376 | } 377 | 378 | for (i = cnt - 1; i >= 0; i--) { 379 | el = CRITBIT_GET(eltree, &tree, test_data[i]); 380 | if (el == NULL) 381 | abort(); 382 | } 383 | 384 | for (i = 3; i < cnt; i += 5) { 385 | el = CRITBIT_REMOVE(eltree, &tree, test_data[i]); 386 | if (el == NULL) 387 | abort(); 388 | } 389 | 390 | for (i = 2; i < cnt; i += 3) { 391 | el = CRITBIT_GET(eltree, &tree, test_data[i]); 392 | } 393 | 394 | for (i = 0; i < cnt; i ++) { 395 | el = CRITBIT_REMOVE(eltree, &tree, test_data[i]); 396 | } 397 | 398 | if (loopcnt-- > 0) 399 | goto again; 400 | gettimeofday(&tend, NULL); 401 | 402 | benchmark_result("critbit", loopcnt_init, &tstart, &tend); 403 | } 404 | 405 | static void 406 | test_benchmark_rbtree(void) 407 | { 408 | struct rbtree tree; 409 | struct element find, *el, *test_data_el; 410 | int cnt; 411 | int i; 412 | 413 | RB_INIT(&tree); 414 | 415 | for (cnt = 0; test_data[cnt]; ) { 416 | cnt++; 417 | } 418 | test_data_el = malloc(cnt * sizeof(*test_data_el)); 419 | 420 | int loopcnt = loopcnt_init; 421 | struct timeval tstart, tend; 422 | 423 | gettimeofday(&tstart, NULL); 424 | 425 | again: 426 | for (i = 0; i < cnt; ++i) { 427 | el = &test_data_el[i]; 428 | el->k = test_data[i]; 429 | RB_INSERT(rbtree, &tree, el); 430 | } 431 | 432 | for (i = cnt - 1; i >= 0; i--) { 433 | find.k = test_data[i]; 434 | el = RB_FIND(rbtree, &tree, &find); 435 | if (el == NULL) 436 | abort(); 437 | } 438 | 439 | for (i = 3; i < cnt; i += 5) { 440 | find.k = test_data[i]; 441 | el = RB_FIND(rbtree, &tree, &find); 442 | if (el == NULL) 443 | abort(); 444 | el = RB_REMOVE(rbtree, &tree, el); 445 | } 446 | 447 | for (i = 2; i < cnt; i += 3) { 448 | find.k = test_data[i]; 449 | el = RB_FIND(rbtree, &tree, &find); 450 | } 451 | 452 | for (i = 0; i < cnt; i ++) { 453 | find.k = test_data[i]; 454 | el = RB_FIND(rbtree, &tree, &find); 455 | if (el != NULL) 456 | RB_REMOVE(rbtree, &tree, el); 457 | } 458 | 459 | if (loopcnt-- > 0) 460 | goto again; 461 | gettimeofday(&tend, NULL); 462 | 463 | benchmark_result("rbtree", loopcnt_init, &tstart, &tend); 464 | } 465 | 466 | #if 0 467 | static int 468 | allprefixed_cb(const char *elem, void *arg) { 469 | set *a = (set *) arg; 470 | a->insert(elem); 471 | 472 | return 1; 473 | } 474 | 475 | static void 476 | test_allprefixed() { 477 | critbit0_tree tree = {0}; 478 | 479 | static const char *elems[] = {"a", "aa", "aaz", "abz", "bba", "bbc", "bbd", NULL}; 480 | 481 | for (unsigned i = 0; elems[i]; ++i) critbit0_insert(&tree, elems[i]); 482 | 483 | set a; 484 | 485 | critbit0_allprefixed(&tree, "a", allprefixed_cb, &a); 486 | if (a.size() != 4 || 487 | a.find("a") == a.end() || 488 | a.find("aa") == a.end() || 489 | a.find("aaz") == a.end() || 490 | a.find("abz") == a.end()) { 491 | abort(); 492 | } 493 | a.clear(); 494 | 495 | critbit0_allprefixed(&tree, "aa", allprefixed_cb, &a); 496 | if (a.size() != 2 || 497 | a.find("aa") == a.end() || 498 | a.find("aaz") == a.end()) { 499 | abort(); 500 | } 501 | a.clear(); 502 | 503 | critbit0_clear(&tree); 504 | } 505 | #endif 506 | 507 | int 508 | main(void) 509 | { 510 | test_contains(); 511 | test_delete(); 512 | test_benchmark_critbit_int(); 513 | test_benchmark_critbit_hash_int(); 514 | test_benchmark_rbtree_int(); 515 | test_benchmark_nrbtree_int(); 516 | test_benchmark_critbit(); 517 | test_benchmark_rbtree(); 518 | #if 0 519 | // test_allprefixed(); 520 | #endif 521 | 522 | return 0; 523 | } 524 | -------------------------------------------------------------------------------- /critbit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This code, like Prof. Bernstein's original code, 3 | * is released into the public domain. 4 | */ 5 | 6 | #include 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "critbit.h" 16 | 17 | #ifdef CRITBIT_DEBUG 18 | #define CRITBIT_ASSERT(a) assert(a) 19 | #else 20 | #define CRITBIT_ASSERT(a) (void)0 21 | #endif 22 | 23 | struct critbit_node { 24 | struct critbit_ref *child[2]; 25 | uint32_t byte; 26 | uint8_t otherbits; 27 | }; 28 | 29 | typedef size_t critbit_keylen_t(const uint8_t *a); 30 | 31 | typedef const uint8_t *critbit_keybuf_t(const struct critbit_key *key); 32 | 33 | typedef int critbit_keycmp_t(const uint8_t *a, const uint8_t *b, size_t blen); 34 | 35 | size_t 36 | critbit_node_size(void) 37 | { 38 | return (sizeof(struct critbit_node)); 39 | } 40 | 41 | static __inline void 42 | critbit_node_free(struct critbit_tree *t, struct critbit_node *node) 43 | { 44 | CRITBIT_ASSERT(t->ct_node_free != NULL); 45 | t->ct_node_free(t, node); 46 | } 47 | 48 | static __inline int 49 | critbit_ref_is_internal(struct critbit_ref *ref) 50 | { 51 | return (((intptr_t)ref) & 1); 52 | } 53 | 54 | static __inline struct critbit_node * 55 | critbit_ref_get_node(struct critbit_ref *ref) 56 | { 57 | CRITBIT_ASSERT(critbit_ref_is_internal(ref)); 58 | 59 | return ((struct critbit_node *)(void *)(((uint8_t *)ref) - 1)); 60 | } 61 | 62 | static __inline void 63 | critbit_ref_set_node(struct critbit_ref **ref, struct critbit_node *node) 64 | { 65 | *ref = (struct critbit_ref *)((uint8_t *)node + 1); 66 | CRITBIT_ASSERT(critbit_ref_is_internal(*ref)); 67 | } 68 | 69 | static __inline void 70 | critbit_ref_set_key(struct critbit_ref **ref, const struct critbit_key *key) 71 | { 72 | *ref = (struct critbit_ref *)key; 73 | CRITBIT_ASSERT(!critbit_ref_is_internal(*ref)); 74 | } 75 | 76 | static __inline struct critbit_key * 77 | critbit_ref_get_key(struct critbit_ref *ref) 78 | { 79 | struct critbit_key *key = (struct critbit_key *)ref; 80 | 81 | CRITBIT_ASSERT(!critbit_ref_is_internal(ref)); 82 | 83 | return (key); 84 | } 85 | 86 | static __inline const uint8_t * 87 | critbit_buf_keybuf(const struct critbit_key *key) 88 | { 89 | return ((const uint8_t *)(key)); 90 | } 91 | 92 | static __inline const uint8_t * 93 | critbit_str_keybuf(const struct critbit_key *key) 94 | { 95 | return (*(uint8_t **)(key)); 96 | } 97 | 98 | static __inline size_t 99 | critbit_buf_keylen(struct critbit_tree *t, const uint8_t *a CRITBIT_UNUSED) 100 | { 101 | return (t->ct_keylen); 102 | } 103 | 104 | static __inline size_t 105 | critbit_str_keylen(struct critbit_tree *t CRITBIT_UNUSED, const uint8_t *a) 106 | { 107 | return (strlen((char *)a)); 108 | } 109 | 110 | static __inline int 111 | critbit_buf_keycmp(const uint8_t *a, const uint8_t *b, size_t blen) 112 | { 113 | return (memcmp(a, b, blen)); 114 | } 115 | 116 | static __inline int 117 | critbit_str_keycmp(const uint8_t *a, const uint8_t *b, size_t blen) 118 | { 119 | size_t alen; 120 | int rv; 121 | 122 | alen = strlen((char *)a); 123 | rv = alen - blen; 124 | if (rv != 0) 125 | return (rv); 126 | return (memcmp(a, b, blen)); 127 | } 128 | 129 | void 130 | critbit_init(struct critbit_tree *t, critbit_node_free_t *nfree, 131 | void *freearg, size_t keylen) 132 | { 133 | t->ct_root = NULL; 134 | t->ct_keylen = keylen; 135 | t->ct_node_free = nfree; 136 | t->ct_free_arg = freearg; 137 | } 138 | 139 | static __inline struct critbit_key * 140 | critbit_get_impl(struct critbit_tree *t, const void *key, size_t keylen, 141 | critbit_keycmp_t *keycmp, critbit_keybuf_t *keybuf) 142 | { 143 | const uint8_t *ubytes = key; 144 | struct critbit_node *node; 145 | struct critbit_ref *ref; 146 | uint8_t c; 147 | 148 | ref = t->ct_root; 149 | if (ref == NULL) 150 | return (0); 151 | 152 | while (critbit_ref_is_internal(ref)) { 153 | node = critbit_ref_get_node(ref); 154 | 155 | c = 0; 156 | if (node->byte < keylen) 157 | c = ubytes[node->byte]; 158 | 159 | const int direction = (1 + (node->otherbits | c)) >> 8; 160 | ref = node->child[direction]; 161 | } 162 | 163 | if (keycmp(keybuf(critbit_ref_get_key(ref)), ubytes, keylen) == 0) 164 | return (critbit_ref_get_key(ref)); 165 | 166 | return (NULL); 167 | } 168 | 169 | /* returns most significant bit set to one in an uint8. 170 | the gnuc version is 10% faster on x86_64. */ 171 | static __inline uint8_t ms1b8(uint8_t v) { 172 | uint32_t value = v; 173 | #ifdef __GNUC__ 174 | return value ? 1 << (31 - __builtin_clz(value)) : 0; 175 | #else 176 | value |= value>>1; 177 | value |= value>>2; 178 | value |= value>>4; 179 | return value & ~(value>>1); 180 | #endif 181 | } 182 | 183 | static __inline struct critbit_key * 184 | critbit_insert_impl(struct critbit_tree *t, struct critbit_node *newnode, 185 | const struct critbit_key *key, size_t keylen, critbit_keybuf_t *keybuf) 186 | { 187 | const uint8_t *const ubytes = keybuf(key); 188 | struct critbit_node *q; 189 | struct critbit_ref *p; 190 | const uint8_t *pkey; 191 | uint32_t newbyte; 192 | uint32_t newotherbits; 193 | uint8_t c; 194 | 195 | p = t->ct_root; 196 | if (p == NULL) { 197 | critbit_ref_set_key(&t->ct_root, key); 198 | critbit_node_free(t, newnode); 199 | return (NULL); 200 | } 201 | 202 | while (critbit_ref_is_internal(p)) { 203 | q = critbit_ref_get_node(p); 204 | 205 | c = 0; 206 | if (q->byte < keylen) 207 | c = ubytes[q->byte]; 208 | 209 | const int direction = (1 + (q->otherbits | c)) >> 8; 210 | p = q->child[direction]; 211 | } 212 | 213 | pkey = keybuf(critbit_ref_get_key(p)); 214 | for (newbyte = 0; newbyte < keylen; ++newbyte) { 215 | if (pkey[newbyte] != ubytes[newbyte]) { 216 | newotherbits = pkey[newbyte] ^ ubytes[newbyte]; 217 | goto different_byte_found; 218 | } 219 | } 220 | 221 | if (pkey[newbyte] != 0) { 222 | newotherbits = pkey[newbyte]; 223 | goto different_byte_found; 224 | } 225 | 226 | critbit_node_free(t, newnode); 227 | return (critbit_ref_get_key(p)); 228 | 229 | different_byte_found: 230 | 231 | newotherbits = ms1b8(newotherbits) ^ 255; 232 | const int newdirection = (1 + (newotherbits | pkey[newbyte])) >> 8; 233 | 234 | newnode->byte = newbyte; 235 | newnode->otherbits = newotherbits; 236 | critbit_ref_set_key(&newnode->child[1 - newdirection], key); 237 | 238 | struct critbit_ref **wherep = &t->ct_root; 239 | for (;;) { 240 | p = *wherep; 241 | if (!critbit_ref_is_internal(p)) 242 | break; 243 | q = critbit_ref_get_node(p); 244 | if (q->byte > newbyte) 245 | break; 246 | if (q->byte == newbyte && q->otherbits > newotherbits) 247 | break; 248 | c = 0; 249 | if (q->byte < keylen) 250 | c = ubytes[q->byte]; 251 | const int direction = (1 + (q->otherbits | c)) >> 8; 252 | wherep = q->child + direction; 253 | } 254 | 255 | newnode->child[newdirection] = *wherep; 256 | critbit_ref_set_node(wherep, newnode); 257 | 258 | return (NULL); 259 | } 260 | 261 | static __inline struct critbit_key * 262 | critbit_remove_impl(struct critbit_tree *t, const void *key, size_t keylen, 263 | critbit_keycmp_t *keycmp, critbit_keybuf_t *keybuf) 264 | { 265 | const uint8_t *ubytes = key; 266 | struct critbit_ref *p = t->ct_root; 267 | struct critbit_node *q = NULL; 268 | struct critbit_ref **wherep = &t->ct_root; 269 | struct critbit_ref **whereq = NULL; 270 | int direction = 0; 271 | 272 | if (p == NULL) 273 | return (NULL); 274 | 275 | while (critbit_ref_is_internal(p)) { 276 | whereq = wherep; 277 | q = critbit_ref_get_node(p); 278 | uint8_t c = 0; 279 | if (q->byte < keylen) 280 | c = ubytes[q->byte]; 281 | direction = (1 + (q->otherbits | c)) >> 8; 282 | wherep = q->child + direction; 283 | p = *wherep; 284 | } 285 | 286 | if (keycmp(keybuf(critbit_ref_get_key(p)), ubytes, keylen) != 0) 287 | return (NULL); 288 | 289 | /* Remove p */ 290 | 291 | if (whereq == NULL) { 292 | t->ct_root = NULL; 293 | return (critbit_ref_get_key(p)); 294 | } 295 | 296 | *whereq = q->child[1 - direction]; 297 | critbit_node_free(t, q); 298 | 299 | return (critbit_ref_get_key(p)); 300 | } 301 | 302 | void * 303 | critbit_buf_get(struct critbit_tree *t, const void *key) 304 | { 305 | return (critbit_get_impl(t, key, critbit_buf_keylen(t, key), 306 | critbit_buf_keycmp, critbit_buf_keybuf)); 307 | } 308 | 309 | void * 310 | critbit_buf_insert(struct critbit_tree *t, 311 | struct critbit_node *newnode, const void *key) 312 | { 313 | return (critbit_insert_impl(t, newnode, (const struct critbit_key *)key, 314 | critbit_buf_keylen(t, NULL), critbit_buf_keybuf)); 315 | } 316 | 317 | void * 318 | critbit_buf_remove(struct critbit_tree *t, const void *key) 319 | { 320 | return (critbit_remove_impl(t, key, critbit_buf_keylen(t, key), 321 | critbit_buf_keycmp, critbit_buf_keybuf)); 322 | } 323 | 324 | void * 325 | critbit_str_get(struct critbit_tree *t, const char *key) 326 | { 327 | return (critbit_get_impl(t, key, 328 | critbit_str_keylen(t, (const uint8_t *)key), 329 | critbit_str_keycmp, critbit_str_keybuf)); 330 | } 331 | 332 | void * 333 | critbit_str_insert(struct critbit_tree *t, 334 | struct critbit_node *newnode, const char **key) 335 | { 336 | return (critbit_insert_impl(t, newnode, (const struct critbit_key *)key, 337 | critbit_str_keylen(t, (const uint8_t *)*key), critbit_str_keybuf)); 338 | } 339 | 340 | void * 341 | critbit_str_remove(struct critbit_tree *t, const char *key) 342 | { 343 | return (critbit_remove_impl(t, key, 344 | critbit_str_keylen(t, (const uint8_t *)key), 345 | critbit_str_keycmp, critbit_str_keybuf)); 346 | } 347 | 348 | #if 0 349 | static void 350 | traverse(void *top) 351 | { 352 | uint8_t *p = top; 353 | 354 | if (1 & (intptr_t)p) { 355 | struct critbit_node *q = (void *)(p - 1); 356 | traverse(q->child[0]); 357 | traverse(q->child[1]); 358 | free(q); 359 | } else { 360 | free(p); 361 | } 362 | 363 | } 364 | 365 | void 366 | critbit0_clear(struct critbit_tree *t) 367 | { 368 | if (t->ct_root) 369 | traverse(t->ct_root); 370 | t->ct_root = NULL; 371 | } 372 | 373 | static int 374 | allprefixed_traverse(uint8_t *top, 375 | int(*handle)(const char *, void *), void *arg) 376 | { 377 | if (1 & (intptr_t)top) { 378 | struct critbit_node *q = (void *)(top - 1); 379 | for (int direction = 0; direction < 2; ++direction) 380 | switch (allprefixed_traverse(q->child[direction], handle, arg)) { 381 | case 1: 382 | break; 383 | case 0: 384 | return 0; 385 | default: 386 | return -1; 387 | } 388 | return 1; 389 | } 390 | 391 | return handle((const char *)top, arg); 392 | } 393 | 394 | int 395 | critbit0_allprefixed(struct critbit_tree *t, const char *prefix, 396 | int(*handle)(const char *, void *), void *arg) 397 | { 398 | const uint8_t *ubytes = (const void *)prefix; 399 | const size_t keylen = strlen(prefix); 400 | struct critbit_node *q; 401 | uint8_t *p = t->ct_root; 402 | uint8_t *top = p; 403 | 404 | if (p == NULL) 405 | return 1; 406 | 407 | while (1 & (intptr_t)p) { 408 | struct critbit_node *q = (void *)(p - 1); 409 | uint8_t c = 0; 410 | if (q->byte < keylen) 411 | c = ubytes[q->byte]; 412 | const int direction = (1 + (q->otherbits | c)) >> 8; 413 | p = q->child[direction]; 414 | if (q->byte < keylen) 415 | top = p; 416 | } 417 | 418 | for (size_t i = 0; i < keylen; ++i) { 419 | if (p[i] != ubytes[i]) 420 | return 1; 421 | } 422 | 423 | 424 | return allprefixed_traverse(top, handle, arg); 425 | } 426 | #endif 427 | -------------------------------------------------------------------------------- /critbit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This code, like Prof. Bernstein's original code, 3 | * is released into the public domain. 4 | */ 5 | 6 | #ifndef CRITBIT_H_ 7 | #define CRITBIT_H_ 8 | 9 | #include 10 | 11 | #ifndef CRITBIT_UNUSED 12 | #ifndef __unused 13 | #define CRITBIT_UNUSED 14 | #else 15 | #define CRITBIT_UNUSED __unused 16 | #endif 17 | #endif 18 | 19 | #ifndef __XCONCAT 20 | #define __XCONCAT1(x,y) x ## y 21 | #define __XCONCAT(x,y) __XCONCAT1(x,y) 22 | #endif 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | struct critbit_key; 29 | struct critbit_node; 30 | struct critbit_ref; 31 | struct critbit_tree; 32 | 33 | typedef void critbit_node_free_t(void *arg, void *node); 34 | 35 | struct critbit_tree { 36 | struct critbit_ref *ct_root; 37 | size_t ct_keylen; 38 | void *ct_free_arg; 39 | critbit_node_free_t *ct_node_free; 40 | }; 41 | 42 | void critbit_init(struct critbit_tree *t, critbit_node_free_t *nfree, 43 | void *freearg, size_t keylen); 44 | 45 | int critbit_empty(struct critbit_tree *t); 46 | 47 | size_t critbit_node_size(void); 48 | 49 | void critbit_buf_init(struct critbit_tree *t, critbit_node_free_t *nfree, 50 | void *freearg, size_t keylen); 51 | 52 | void *critbit_buf_get(struct critbit_tree *t, const void *key); 53 | 54 | void *critbit_buf_insert(struct critbit_tree *t, 55 | struct critbit_node *newnode, const void *key); 56 | 57 | void *critbit_buf_remove(struct critbit_tree *t, const void *key); 58 | 59 | void critbit_str_init(struct critbit_tree *t, 60 | critbit_node_free_t *nfree, void *freearg); 61 | 62 | void *critbit_str_get(struct critbit_tree *t, const char *key); 63 | 64 | void *critbit_str_insert(struct critbit_tree *t, 65 | struct critbit_node *newnode, const char **key); 66 | 67 | void *critbit_str_remove(struct critbit_tree *t, const char *key); 68 | 69 | #define CRITBIT_HEAD(name) \ 70 | struct name##_critbit_head 71 | 72 | #define CRITBIT_HEAD_PROTOTYPE(name) \ 73 | CRITBIT_HEAD(name) { \ 74 | struct critbit_tree treehead; \ 75 | } 76 | 77 | #define CRITBIT_PROTOTYPE_INLINE(name, type, keytype) \ 78 | CRITBIT_PROTOTYPE_INTERNAL(name, type, keytype, \ 79 | CRITBIT_UNUSED static __inline) 80 | 81 | #define CRITBIT_GENERATE_INLINE(name, type, keytype, field) \ 82 | CRITBIT_GENERATE_INTERNAL(name, type, keytype, field, \ 83 | CRITBIT_UNUSED static __inline) 84 | 85 | #define CRITBIT_PROTOTYPE_STATIC(name, type, keytype) \ 86 | CRITBIT_PROTOTYPE_INTERNAL(name, type, keytype, CRITBIT_UNUSED static) 87 | 88 | #define CRITBIT_GENERATE_STATIC(name, type, keytype, field) \ 89 | CRITBIT_GENERATE_INTERNAL(name, type, keytype, field, CRITBIT_UNUSED static) 90 | 91 | #define CRITBIT_PROTOTYPE_INTERNAL(name, type, keytype, attr) \ 92 | CRITBIT_HEAD_PROTOTYPE(name); \ 93 | attr size_t name##_critbit_keylen(void); \ 94 | attr struct type *name##_critbit_get(CRITBIT_HEAD(name) *head, \ 95 | CRITBIT_KEYTYPE_##keytype key); \ 96 | attr struct type *name##_critbit_insert(CRITBIT_HEAD(name) *head, \ 97 | struct critbit_node *newnode, struct type *entry); \ 98 | attr struct type *name##_critbit_remove(CRITBIT_HEAD(name) *head, \ 99 | CRITBIT_KEYTYPE_##keytype key); 100 | 101 | #define CRITBIT_GENERATE_INTERNAL(name, type, keytype, field, attr) \ 102 | attr size_t \ 103 | name##_critbit_keylen(void) \ 104 | { \ 105 | /* ignored by critbit_str_* */ \ 106 | return (sizeof(CRITBIT_KEYTYPE_##keytype)); \ 107 | } \ 108 | \ 109 | attr struct type * \ 110 | name##_critbit_get(CRITBIT_HEAD(name) *head, \ 111 | CRITBIT_KEYTYPE_##keytype key) \ 112 | { \ 113 | void *r = CRITBIT_METHOD(keytype, get)(&head->treehead, \ 114 | CRITBIT_KEYREF_##keytype(key)); \ 115 | return (CRITBIT_CAST(type, field, r)); \ 116 | } \ 117 | \ 118 | attr struct type *name##_critbit_insert(CRITBIT_HEAD(name) *head, \ 119 | struct critbit_node *newnode, struct type *entry) \ 120 | { \ 121 | void *r = CRITBIT_METHOD(keytype,insert)(&head->treehead, \ 122 | newnode, &(entry->field)); \ 123 | return (CRITBIT_CAST(type, field, r)); \ 124 | } \ 125 | \ 126 | attr struct type *name##_critbit_remove(CRITBIT_HEAD(name) *head, \ 127 | CRITBIT_KEYTYPE_##keytype key) \ 128 | { \ 129 | void *r = CRITBIT_METHOD(keytype,remove)(&head->treehead, \ 130 | CRITBIT_KEYREF_##keytype(key)); \ 131 | return (CRITBIT_CAST(type, field, r)); \ 132 | } 133 | 134 | #define CRITBIT_METHOD(keytype, method) \ 135 | __XCONCAT(__XCONCAT(critbit_,keytype),_##method) 136 | 137 | #define CRITBIT_CAST(type, field, val) \ 138 | (val == NULL ? NULL : (struct type *)(void *)(((char *)val - \ 139 | offsetof(struct type, field)))) 140 | 141 | #define CRITBIT_INIT(name, head, nfree, freearg) \ 142 | critbit_init(&((head)->treehead), (nfree), (freearg), name##_critbit_keylen()) 143 | 144 | #define critbit_int32 critbit_buf 145 | #define critbit_int64 critbit_buf 146 | #define critbit_intptr critbit_buf 147 | #define critbit_ptr critbit_buf 148 | 149 | #define CRITBIT_KEYREF_buf(a) (a) 150 | #define CRITBIT_KEYREF_str(a) (a) 151 | #define CRITBIT_KEYREF_scalar(a) (&(a)) 152 | #define CRITBIT_KEYREF_int32(a) CRITBIT_KEYREF_scalar(a) 153 | #define CRITBIT_KEYREF_int64(a) CRITBIT_KEYREF_scalar(a) 154 | #define CRITBIT_KEYREF_intptr(a) CRITBIT_KEYREF_scalar(a) 155 | #define CRITBIT_KEYREF_ptr(a) CRITBIT_KEYREF_scalar((intptr_t)(a)) 156 | 157 | #define CRITBIT_KEYTYPE_buf const void * 158 | #define CRITBIT_KEYTYPE_str const char * 159 | #define CRITBIT_KEYTYPE_int32 int32_t 160 | #define CRITBIT_KEYTYPE_int64 int64_t 161 | #define CRITBIT_KEYTYPE_intptr intptr_t 162 | #define CRITBIT_KEYTYPE_ptr const void * 163 | 164 | #define CRITBIT_GET(name, tree, key) \ 165 | name##_critbit_get((tree), (key)) 166 | 167 | #define CRITBIT_INSERT(name, tree, newnode, key) \ 168 | name##_critbit_insert((tree), (newnode), (key)) 169 | 170 | #define CRITBIT_REMOVE(name, tree, key) \ 171 | name##_critbit_remove((tree), (key)) 172 | 173 | #ifdef __cplusplus 174 | } 175 | #endif 176 | 177 | #endif 178 | --------------------------------------------------------------------------------