Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

IdKey.cxx

Go to the documentation of this file.
00001 // $Header: /nfs/slac/g/glast/ground/cvs/xmlUtil/src/id/IdKey.cxx,v 1.5 2002/01/03 21:05:38 jrb Exp $
00002 
00003 #include "xmlUtil/id/IdKey.h"
00004 #include <cassert>
00005 
00006 namespace {
00007   static const unsigned int maxVal = 254;
00008   static const unsigned int moveLeft = 256;
00009 }
00010 
00011 namespace xmlUtil {
00012   IdKey::IdKey(const Identifier id) {
00013     fillFrom(id);
00014   }
00015 
00016   IdKey::IdKey(const std::deque<unsigned int> id) {
00017     fillFrom(id);
00018   }
00019 
00020   // Compress each field to a byte.  Use the range 1-255 because
00021   // 0 is reserved; it means "absent".  If any field in the
00022   // input id has a value > 254 we're in trouble
00023   template<class Container>
00024   void IdKey::fillFrom(const Container& con) {
00025 
00026     typename Container::const_iterator start  = con.begin();
00027     typename Container::const_iterator stop  = con.end();
00028 
00029     const unsigned int inSize = con.size();
00030 
00031     m_key.reserve((inSize + 3) / 4);
00032     unsigned int out = 0;
00033     unsigned int iByte = 0;
00034 
00035     typename Container::const_iterator inIt = start;
00036 
00037     for (; inIt != stop; ++inIt) {
00038       unsigned int cur = *inIt + 1;
00039 
00040       if (cur > maxVal) {
00041         // not allowed
00042         assert(maxVal > cur);
00043       }
00044       out *= moveLeft;  
00045       out += cur; 
00046       iByte++; 
00047       if (iByte == 4) {  // store the word; re-init for next word
00048         m_key.push_back(out);
00049         out = 0;
00050         iByte = 0;
00051       }
00052     }
00053 
00054     if (iByte) {
00055       while (iByte < 4) {
00056         out *= moveLeft;
00057         iByte++;
00058       }
00059       m_key.push_back(out);
00060     }
00061   }
00062 
00063   // For sorting purposes, this must behave like < (less-than)
00064   // Internally keys are essentially vectors of unsigned ints.
00065   // Compare them component-wise.  Return 
00066   //     * when corresponding components differ       or
00067   //     * when one key is shorter than the other (shorter is less-than)
00068   bool IdKey::ltkey::operator()(IdKey key1, IdKey key2) const {
00069 
00070     IdKey::KeyIt it1 = key1.m_key.begin();
00071     IdKey::KeyIt it2 = key2.m_key.begin();
00072 
00073     while (it1 != key1.m_key.end()) {
00074       if (it2 == key2.m_key.end()) return false;
00075       if (*it1 != *it2) return (*it1 < *it2);
00076       ++it1; ++it2;
00077     }
00078 
00079     // If we got here the first key has been exhausted.
00080     return (it2 != key2.m_key.end());
00081   }
00082 
00083   IdKey::~IdKey() {m_key.clear(); m_key.resize(0);}
00084 }
00085   
00086     

Generated on Wed Oct 16 14:02:47 2002 by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001