MurmurHash SharedDataHolder<PathMatcher>::hash() const { IECore::MurmurHash result; HashStack stack; PathMatcher m = readable(); for( PathMatcher::RawIterator it = m.begin(), eIt = m.end(); it != eIt; ++it ) { // The iterator is recursive, so we use a stack to keep // track of where we are. Resize the stack to match our // current depth. The required size has the +1 because // we need a stack entry for the root item. size_t requiredStackSize = it->size() + 1; if( requiredStackSize > stack.size() ) { // Going a level deeper. stack.push( HashNodes() ); assert( stack.size() == requiredStackSize ); } else if( requiredStackSize < stack.size() ) { // Returning from recursion to the child nodes. // Output the hashes for the children we visited // and stored on the stack previously. popHashNodes( stack, requiredStackSize, result ); } stack.top().push_back( HashNode( it->size() ? it->back().c_str() : "", it.exactMatch() ) ); } popHashNodes( stack, 0, result ); return result; }
void PathMatcherData::save( SaveContext *context ) const { Data::save( context ); IndexedIOPtr container = context->container( staticTypeName(), g_ioVersion ); std::vector<InternedString> strings; std::vector<unsigned int> pathLengths; std::vector<unsigned char> exactMatches; for( PathMatcher::RawIterator it = readable().begin(), eIt = readable().end(); it != eIt; ++it ) { pathLengths.push_back( it->size() ); if( it->size() ) { strings.push_back( it->back() ); } exactMatches.push_back( it.exactMatch() ); } container->write( "strings", strings.data(), strings.size() ); container->write( "pathLengths", pathLengths.data(), pathLengths.size() ); container->write( "exactMatches", exactMatches.data(), exactMatches.size() ); }