17ec681f3Smrg/* 27ec681f3Smrg * Copyright 2013 Christoph Bumiller 37ec681f3Smrg * 47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 57ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 67ec681f3Smrg * to deal in the Software without restriction, including without limitation 77ec681f3Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub 87ec681f3Smrg * license, and/or sell copies of the Software, and to permit persons to whom 97ec681f3Smrg * the Software is furnished to do so, subject to the following conditions: 107ec681f3Smrg * 117ec681f3Smrg * The above copyright notice and this permission notice (including the next 127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 137ec681f3Smrg * Software. 147ec681f3Smrg * 157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 187ec681f3Smrg * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 197ec681f3Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 207ec681f3Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 217ec681f3Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 227ec681f3Smrg 237ec681f3Smrg#include "nine_helpers.h" 247ec681f3Smrg 257ec681f3Smrgstatic struct nine_range * 267ec681f3Smrgnine_range_pool_more(struct nine_range_pool *pool) 277ec681f3Smrg{ 287ec681f3Smrg struct nine_range *r = MALLOC(64 * sizeof(struct nine_range)); 297ec681f3Smrg int i; 307ec681f3Smrg assert(!pool->free); 317ec681f3Smrg 327ec681f3Smrg if (pool->num_slabs == pool->num_slabs_max) { 337ec681f3Smrg unsigned p = pool->num_slabs_max; 347ec681f3Smrg unsigned n = pool->num_slabs_max * 2; 357ec681f3Smrg if (!n) 367ec681f3Smrg n = 4; 377ec681f3Smrg pool->slabs = REALLOC(pool->slabs, 387ec681f3Smrg p * sizeof(struct nine_range *), 397ec681f3Smrg n * sizeof(struct nine_range *)); 407ec681f3Smrg pool->num_slabs_max = n; 417ec681f3Smrg } 427ec681f3Smrg pool->free = pool->slabs[pool->num_slabs++] = r; 437ec681f3Smrg 447ec681f3Smrg for (i = 0; i < 63; ++i, r = r->next) 457ec681f3Smrg r->next = (struct nine_range *) 467ec681f3Smrg ((uint8_t *)r + sizeof(struct nine_range)); 477ec681f3Smrg r->next = NULL; 487ec681f3Smrg 497ec681f3Smrg return pool->free; 507ec681f3Smrg} 517ec681f3Smrg 527ec681f3Smrgstatic inline struct nine_range * 537ec681f3Smrgnine_range_pool_get(struct nine_range_pool *pool, int16_t bgn, int16_t end) 547ec681f3Smrg{ 557ec681f3Smrg struct nine_range *r = pool->free; 567ec681f3Smrg if (!r) 577ec681f3Smrg r = nine_range_pool_more(pool); 587ec681f3Smrg assert(r); 597ec681f3Smrg pool->free = r->next; 607ec681f3Smrg r->bgn = bgn; 617ec681f3Smrg r->end = end; 627ec681f3Smrg return r; 637ec681f3Smrg} 647ec681f3Smrg 657ec681f3Smrgstatic inline void 667ec681f3Smrgnine_ranges_coalesce(struct nine_range *r, struct nine_range_pool *pool) 677ec681f3Smrg{ 687ec681f3Smrg struct nine_range *n; 697ec681f3Smrg 707ec681f3Smrg while (r->next && r->end >= r->next->bgn) { 717ec681f3Smrg n = r->next->next; 727ec681f3Smrg r->end = (r->end >= r->next->end) ? r->end : r->next->end; 737ec681f3Smrg nine_range_pool_put(pool, r->next); 747ec681f3Smrg r->next = n; 757ec681f3Smrg } 767ec681f3Smrg} 777ec681f3Smrg 787ec681f3Smrgvoid 797ec681f3Smrgnine_ranges_insert(struct nine_range **head, int16_t bgn, int16_t end, 807ec681f3Smrg struct nine_range_pool *pool) 817ec681f3Smrg{ 827ec681f3Smrg struct nine_range *r, **pn = head; 837ec681f3Smrg 847ec681f3Smrg for (r = *head; r && bgn > r->end; pn = &r->next, r = r->next); 857ec681f3Smrg 867ec681f3Smrg if (!r || end < r->bgn) { 877ec681f3Smrg *pn = nine_range_pool_get(pool, bgn, end); 887ec681f3Smrg (*pn)->next = r; 897ec681f3Smrg } else 907ec681f3Smrg if (bgn < r->bgn) { 917ec681f3Smrg r->bgn = bgn; 927ec681f3Smrg if (end > r->end) 937ec681f3Smrg r->end = end; 947ec681f3Smrg nine_ranges_coalesce(r, pool); 957ec681f3Smrg } else 967ec681f3Smrg if (end > r->end) { 977ec681f3Smrg r->end = end; 987ec681f3Smrg nine_ranges_coalesce(r, pool); 997ec681f3Smrg } 1007ec681f3Smrg} 101