# SymImpl.cpp

    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