| 167 | } |
| 168 | |
| 169 | void CompoundObject::hash( MurmurHash &h ) const |
| 170 | { |
| 171 | Object::hash( h ); |
| 172 | |
| 173 | // the ObjectMap is sorted by InternedString::operator <, |
| 174 | // which just compares addresses of the underlying interned object. |
| 175 | // this isn't stable between multiple processes. |
| 176 | std::vector<ObjectMap::const_iterator> iterators; |
| 177 | iterators.reserve( m_members.size() ); |
| 178 | for( ObjectMap::const_iterator it=m_members.begin(); it!=m_members.end(); it++ ) |
| 179 | { |
| 180 | iterators.push_back( it ); |
| 181 | } |
| 182 | |
| 183 | // so we have to sort again based on the string values |
| 184 | // themselves. |
| 185 | sort( iterators.begin(), iterators.end(), comp ); |
| 186 | |
| 187 | // and then hash everything in the stable order. |
| 188 | std::vector<ObjectMap::const_iterator>::const_iterator it; |
| 189 | for( it=iterators.begin(); it!=iterators.end(); it++ ) |
| 190 | { |
| 191 | if ( !((*it)->second) ) |
| 192 | { |
| 193 | throw Exception( "Cannot compute hash from a CompoundObject will NULL data pointers!" ); |
| 194 | } |
| 195 | h.append( (*it)->first.value() ); |
| 196 | (*it)->second->hash( h ); |
| 197 | } |
| 198 | } |
| 199 | |
| 200 | CompoundObject *CompoundObject::defaultInstance() |
| 201 | { |