// // aegis - project change supervisor // Copyright (C) 2004-2008 Peter Miller // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see // . // #include // for assert #include #include void symtab_ty::split() { // // double the modulus // // This is subtle. If we only increase the modulus by one, the // load always hovers around 80%, so we have to do a split for // every insert. I.e. the malloc burden os O(n) for the lifetime of // the symtab. BUT if we double the modulus, the length of time // until the next split also doubles, making the probablity of a // split halve, and sigma(2**-n)=1, so the malloc burden becomes O(1) // for the lifetime of the symtab. // str_hash_ty new_hash_modulus = hash_modulus * 2; str_hash_ty new_hash_mask = new_hash_modulus - 1; row_t **new_hash_table = new row_t * [new_hash_modulus]; // // now redistribute the list elements // for (str_hash_ty idx = 0; idx < hash_modulus; ++idx) { new_hash_table[idx] = 0; new_hash_table[idx + hash_modulus] = 0; row_t *p = hash_table[idx]; while (p) { row_t *p2 = p; p = p2->overflow; p2->overflow = 0; // // It is important to preserve the order of the links because // they can be push-down stacks, and to simply add them to the // head of the list will reverse the order of the stack! // assert((p2->key.get_hash() & hash_mask) == idx); str_hash_ty idx2 = p2->key.get_hash() & new_hash_mask; row_t **ipp = &new_hash_table[idx2]; for (; *ipp; ipp = &(*ipp)->overflow) ; *ipp = p2; } } delete [] hash_table; hash_table = new_hash_table; hash_modulus = new_hash_modulus; hash_mask = new_hash_mask; }