00001 /* 00002 * Copyright (C) 2005 Maarten Keijzer 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of version 2 of the GNU General Public License as 00006 * published by the Free Software Foundation. 00007 * 00008 * This program is distributed in the hope that it will be useful, 00009 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 * GNU General Public License for more details. 00012 * 00013 * You should have received a copy of the GNU General Public License 00014 * along with this program; if not, write to the Free Software 00015 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00016 */ 00017 #include "Sym.h" 00018 00019 using namespace std; 00020 namespace detail { 00021 00022 class SymArgsImpl { 00023 public: 00024 std::vector<Sym> owned_args; 00025 }; 00026 00027 size_t SymArgs::len() const { 00028 return vec().size(); 00029 } 00030 00031 SymArgs::SymArgs() : pimpl( new SymArgsImpl ) { 00032 args_ptr = &pimpl->owned_args; 00033 } 00034 00035 SymArgs::SymArgs(const std::vector<Sym>& v) : pimpl(0) { 00036 args_ptr = &v; 00037 } 00038 00039 SymArgs::~SymArgs() { 00040 delete pimpl; 00041 } 00042 00043 SymArgs::SymArgs(const SymArgs& args) : pimpl(0), args_ptr(args.args_ptr) { 00044 if (args.pimpl && args.args_ptr == &args.pimpl->owned_args) { 00045 pimpl = new SymArgsImpl(*args.pimpl); 00046 args_ptr = &pimpl->owned_args; 00047 } 00048 } 00049 00050 const SymArgs& SymArgs::operator=(const SymArgs& args) { 00051 if (args.pimpl && args.args_ptr == &args.pimpl->owned_args) { 00052 pimpl = new SymArgsImpl(*args.pimpl); 00053 args_ptr = &pimpl->owned_args; 00054 } else { 00055 args_ptr = args.args_ptr; 00056 } 00057 00058 return *this; 00059 } 00060 00061 void SymArgs::fixate() const { 00062 assert(pimpl == 0); 00063 pimpl = new SymArgsImpl; 00064 pimpl->owned_args = *args_ptr; 00065 args_ptr = &pimpl->owned_args; 00066 } 00067 00068 // For Tackett's hashcode 00069 #define PRIMET 21523 00070 #define HASHMOD 277218551 00071 00072 const int nprimes = 4; 00073 const unsigned long primes[] = {3221225473ul, 201326611ul, 1610612741ul, 805306457ul}; 00074 00075 int SymKey::calc_hash() const { 00076 unsigned long hash = unsigned(token); 00077 hash *= PRIMET; 00078 00079 const std::vector<Sym>& v = args.vec(); 00080 for (unsigned i = 0; i < v.size(); ++i) { 00081 hash += ( (v[i].address() >> 3) * primes[i%nprimes]) % HASHMOD; 00082 } 00083 00084 return hash;// % HASHMOD; 00085 } 00086 00087 bool SymKey::operator==(const SymKey& other) const { 00088 if (token != other.token) return false; 00089 return args.vec() == other.args.vec(); 00090 } 00091 00092 /* Just to store this info somewhere: 00093 * 00094 * Address Based Hash Function Implementation 00095 * uint32 address_hash(char* addr) 00096 * { 00097 * register uint32 key; 00098 * key = (uint32) addr; 00099 * return (key >> 3) * 2654435761; 00100 * } 00101 */ 00102 00103 SymValue::SymValue() : refcount(0), size(0), depth(0), uniqueNodeStats(0) {} 00104 00105 SymValue::~SymValue() { delete uniqueNodeStats; } 00106 00107 00108 00109 } // namespace detail
1.4.7