/****************************************************************************** ** This file is part of profile-qt ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are met: ** ** Redistributions of source code must retain the above copyright notice, ** this list of conditions and the following disclaimer. Redistributions in ** binary form must reproduce the above copyright notice, this list of ** conditions and the following disclaimer in the documentation and/or ** other materials provided with the distribution. ** ** Neither the name of Nokia Corporation nor the names of its contributors ** may be used to endorse or promote products derived from this software ** without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; ** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, ** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR ** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************/ #include "profiled_config.h" #include #include #include #include #include #include "symtab.h" /* ========================================================================= * * symtab_t -- methods * ========================================================================= */ /* ------------------------------------------------------------------------- * * symtab_insert * ------------------------------------------------------------------------- */ void * symtab_insert(symtab_t *self, const void *key) { size_t l = 0; size_t h = self->st_count; while( l < h ) { size_t i = (l + h) / 2; void *p = self->st_elem[i]; int r = strcmp(self->st_key(p), key); if( r < 0 ) { l = i + 1; continue; } if( r > 0 ) { h = i + 0; continue; } return p; } if( self->st_count == self->st_alloc ) { if( self->st_alloc < 16 ) { self->st_alloc = 16; } else { self->st_alloc = self->st_alloc * 3 / 2; } self->st_elem = realloc(self->st_elem, self->st_alloc * sizeof *self->st_elem); } for( h = self->st_count++; h > l; --h ) { self->st_elem[h] = self->st_elem[h-1]; } return self->st_elem[l] = self->st_new(key); } /* ------------------------------------------------------------------------- * * symtab_lookup * ------------------------------------------------------------------------- */ void * symtab_lookup(const symtab_t *self, const void *key) { size_t l = 0; size_t h = self->st_count; while( l < h ) { size_t i = (l + h) / 2; void *p = self->st_elem[i]; int r = strcmp(self->st_key(p), key); if( r < 0 ) { l = i + 1; continue; } if( r > 0 ) { h = i + 0; continue; } return p; } return 0; } /* ------------------------------------------------------------------------- * * symtab_remove * ------------------------------------------------------------------------- */ void symtab_remove(symtab_t *self, const void *key) { size_t l = 0; size_t h = self->st_count; while( l < h ) { size_t i = (l + h) / 2; void *p = self->st_elem[i]; int r = strcmp(self->st_key(p), key); if( r < 0 ) { l = i + 1; continue; } if( r > 0 ) { h = i + 0; continue; } self->st_del(p); for( h = --self->st_count; i < h; ++i ) { self->st_elem[i] = self->st_elem[i+1]; } break; } } /* ------------------------------------------------------------------------- * * symtab_clear * ------------------------------------------------------------------------- */ void symtab_clear(symtab_t *self) { if( self->st_del != 0 ) { for( size_t i = 0; i < self->st_count; ++i ) { self->st_del(self->st_elem[i]); } } self->st_count = 0; } /* ------------------------------------------------------------------------- * * symtab_ctor * ------------------------------------------------------------------------- */ void symtab_ctor(symtab_t *self, symtab_new_fn new, symtab_del_fn del, symtab_key_fn key) { self->st_count = 0; self->st_alloc = 0; self->st_elem = 0; self->st_new = new; self->st_key = key; self->st_del = del; } /* ------------------------------------------------------------------------- * * symtab_dtor * ------------------------------------------------------------------------- */ void symtab_dtor(symtab_t *self) { symtab_clear(self); free(self->st_elem); } /* ------------------------------------------------------------------------- * * symtab_create * ------------------------------------------------------------------------- */ symtab_t * symtab_create(symtab_new_fn new, symtab_del_fn del, symtab_key_fn key) { symtab_t *self = calloc(1, sizeof *self); symtab_ctor(self, new, del, key); return self; } /* ------------------------------------------------------------------------- * * symtab_delete * ------------------------------------------------------------------------- */ void symtab_delete(symtab_t *self) { if( self != 0 ) { symtab_dtor(self); free(self); } } /* ------------------------------------------------------------------------- * * symtab_delete_cb * ------------------------------------------------------------------------- */ void symtab_delete_cb(void *self) { symtab_delete(self); }