3
// Copyright (C) 2004 Navel Ltd.
5
// This library is free software; you can redistribute it and/or
6
// modify it under the terms of the GNU Lesser General Public
7
// License as published by the Free Software Foundation; either
8
// version 2.1 of the License, or (at your option) any later version.
10
// This library is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
// Lesser General Public License for more details.
15
// You should have received a copy of the GNU Lesser General Public
16
// License along with this library; if not, write to the Free Software
17
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26
#include "ExternalSort.h"
29
Tools::IndexOutOfBoundsException::IndexOutOfBoundsException( int i )
32
s << "Invalid index " << i;
36
std::string Tools::IndexOutOfBoundsException::what()
38
return "IndexOutOfBoundsException: " + m_error;
41
Tools::IllegalArgumentException::IllegalArgumentException( std::string s ) : m_error( s )
45
std::string Tools::IllegalArgumentException::what()
47
return "IllegalArgumentException: " + m_error;
50
Tools::IllegalStateException::IllegalStateException( std::string s ) : m_error( s )
54
std::string Tools::IllegalStateException::what()
56
return "IllegalStateException: " + m_error + "\n"; //Please contact " + PACKAGE_BUGREPORT;
59
Tools::EndOfStreamException::EndOfStreamException( std::string s ) : m_error( s )
63
std::string Tools::EndOfStreamException::what()
65
return "EndOfStreamException: " + m_error;
68
Tools::ResourceLockedException::ResourceLockedException( std::string s ) : m_error( s )
72
std::string Tools::ResourceLockedException::what()
74
return "ResourceLockedException: " + m_error;
77
Tools::InvalidPageException::InvalidPageException( long id )
80
s << "Unknown page id " << id;
84
std::string Tools::InvalidPageException::what()
86
return "InvalidPageException: " + m_error;
89
Tools::NotSupportedException::NotSupportedException( std::string s ) : m_error( s )
93
std::string Tools::NotSupportedException::what()
95
return "NotSupportedException: " + m_error;
98
Tools::ParseErrorException::ParseErrorException( std::string s ) : m_error( s )
102
std::string Tools::ParseErrorException::what()
104
return "ParseErrorException: " + m_error;
107
Tools::Variant::Variant() : m_varType( VT_EMPTY )
111
Tools::PropertySet::PropertySet( const byte* data )
113
loadFromByteArray( data );
116
void Tools::PropertySet::loadFromByteArray( const byte* ptr )
118
m_propertySet.clear();
120
unsigned long numberOfProperties;
121
memcpy( &numberOfProperties, ptr, sizeof( unsigned long ) );
122
ptr += sizeof( unsigned long );
126
for ( unsigned long cIndex = 0; cIndex < numberOfProperties; cIndex++ )
128
std::string s( reinterpret_cast<const char*>( ptr ) );
130
memcpy( &( v.m_varType ), ptr, sizeof( VariantType ) );
131
ptr += sizeof( VariantType );
133
switch ( v.m_varType )
137
memcpy( &l, ptr, sizeof( long ) );
138
ptr += sizeof( long );
143
memcpy( &ll, ptr, sizeof( long long ) );
144
ptr += sizeof( long long );
149
memcpy( &b, ptr, sizeof( byte ) );
150
ptr += sizeof( byte );
155
memcpy( &s, ptr, sizeof( short ) );
156
ptr += sizeof( short );
161
memcpy( &f, ptr, sizeof( float ) );
162
ptr += sizeof( float );
167
memcpy( &d, ptr, sizeof( double ) );
168
ptr += sizeof( double );
173
memcpy( &c, ptr, sizeof( char ) );
174
ptr += sizeof( char );
179
memcpy( &us, ptr, sizeof( unsigned short ) );
180
ptr += sizeof( unsigned short );
185
memcpy( &ul, ptr, sizeof( unsigned long ) );
186
ptr += sizeof( unsigned long );
190
unsigned long long ull;
191
memcpy( &ull, ptr, sizeof( unsigned long long ) );
192
ptr += sizeof( unsigned long long );
193
v.m_val.ullVal = ull;
197
memcpy( &i, ptr, sizeof( int ) );
198
ptr += sizeof( int );
203
memcpy( &ui, ptr, sizeof( unsigned int ) );
204
ptr += sizeof( unsigned int );
205
v.m_val.uintVal = ui;
209
memcpy( &bl, ptr, sizeof( byte ) );
210
ptr += sizeof( byte );
211
v.m_val.blVal = bl != 0;
214
throw IllegalStateException(
215
"Tools::PropertySet::PropertySet: Deserialization problem."
219
m_propertySet.insert( std::pair<std::string, Variant>( s, v ) );
223
unsigned long Tools::PropertySet::getByteArraySize()
225
unsigned long size = sizeof( unsigned long );
226
std::map<std::string, Variant>::iterator it;
228
for ( it = m_propertySet.begin(); it != m_propertySet.end(); it++ )
230
switch (( *it ).second.m_varType )
233
size += sizeof( long );
236
size += sizeof( long long );
239
size += sizeof( byte );
242
size += sizeof( short );
245
size += sizeof( float );
248
size += sizeof( double );
251
size += sizeof( char );
254
size += sizeof( unsigned short );
257
size += sizeof( unsigned long );
260
size += sizeof( unsigned long long );
263
size += sizeof( int );
266
size += sizeof( unsigned int );
269
size += sizeof( byte );
272
throw NotSupportedException(
273
"Tools::PropertySet::getSize: Unknown type."
276
size += ( *it ).first.size() + 1 + sizeof( VariantType );
282
void Tools::PropertySet::storeToByteArray( byte** data, unsigned long& length )
284
length = getByteArraySize();
285
*data = new byte[length];
288
unsigned long numberOfProperties = m_propertySet.size();
289
memcpy( ptr, &numberOfProperties, sizeof( unsigned long ) );
290
ptr += sizeof( unsigned long );
292
std::map<std::string, Variant>::iterator it;
294
for ( it = m_propertySet.begin(); it != m_propertySet.end(); it++ )
296
unsigned long strSize = ( *it ).first.size();
297
memcpy( ptr, ( *it ).first.c_str(), strSize );
302
memcpy( ptr, &(( *it ).second.m_varType ), sizeof( VariantType ) );
303
ptr += sizeof( VariantType );
305
switch (( *it ).second.m_varType )
308
memcpy( ptr, &(( *it ).second.m_val.lVal ), sizeof( long ) );
309
ptr += sizeof( long );
312
memcpy( ptr, &(( *it ).second.m_val.llVal ), sizeof( long long ) );
313
ptr += sizeof( long long );
316
memcpy( ptr, &(( *it ).second.m_val.bVal ), sizeof( byte ) );
317
ptr += sizeof( byte );
320
memcpy( ptr, &(( *it ).second.m_val.iVal ), sizeof( short ) );
321
ptr += sizeof( short );
324
memcpy( ptr, &(( *it ).second.m_val.fltVal ), sizeof( float ) );
325
ptr += sizeof( float );
328
memcpy( ptr, &(( *it ).second.m_val.dblVal ), sizeof( double ) );
329
ptr += sizeof( double );
332
memcpy( ptr, &(( *it ).second.m_val.cVal ), sizeof( char ) );
333
ptr += sizeof( char );
336
memcpy( ptr, &(( *it ).second.m_val.uiVal ), sizeof( unsigned short ) );
337
ptr += sizeof( unsigned short );
340
memcpy( ptr, &(( *it ).second.m_val.ulVal ), sizeof( unsigned long ) );
341
ptr += sizeof( unsigned long );
344
memcpy( ptr, &(( *it ).second.m_val.ullVal ), sizeof( unsigned long long ) );
345
ptr += sizeof( unsigned long long );
348
memcpy( ptr, &(( *it ).second.m_val.intVal ), sizeof( int ) );
349
ptr += sizeof( int );
352
memcpy( ptr, &(( *it ).second.m_val.uintVal ), sizeof( unsigned int ) );
353
ptr += sizeof( unsigned int );
357
bl = ( *it ).second.m_val.blVal;
358
memcpy( ptr, &bl, sizeof( byte ) );
359
ptr += sizeof( byte );
362
throw NotSupportedException(
363
"Tools::PropertySet::getData: Cannot serialize a variant of this type."
368
assert( ptr == ( *data ) + length );
371
Tools::Variant Tools::PropertySet::getProperty( std::string property )
373
std::map<std::string, Variant>::iterator it = m_propertySet.find( property );
374
if ( it != m_propertySet.end() ) return ( *it ).second;
375
else return Variant();
378
void Tools::PropertySet::setProperty( std::string property, Variant& v )
380
m_propertySet.insert( std::pair<std::string, Variant>( property, v ) );
383
void Tools::PropertySet::removeProperty( std::string property )
385
std::map<std::string, Variant>::iterator it = m_propertySet.find( property );
386
if ( it != m_propertySet.end() ) m_propertySet.erase( it );
389
Tools::IObjectStream* Tools::externalSort( IObjectStream& source, unsigned long bufferSize )
391
return new ExternalSort( source, bufferSize );
395
Tools::IObjectStream* Tools::externalSort( IObjectStream& source, IObjectComparator& comp, unsigned long bufferSize )
397
return new ExternalSort( source, comp, bufferSize );
400
Tools::Interval::Interval() : m_type( IT_RIGHTOPEN ), m_low( 0.0 ), m_high( 0.0 )
404
Tools::Interval::Interval( IntervalType t, double l, double h ) : m_type( t ), m_low( l ), m_high( h )
409
Tools::Interval::Interval( double l, double h ) : m_type( IT_RIGHTOPEN ), m_low( l ), m_high( h )
414
Tools::Interval::Interval( const Interval& iv )
421
Tools::IInterval& Tools::Interval::operator=( const IInterval & iv )
425
m_low = iv.getLowerBound();
426
m_high = iv.getUpperBound();
427
m_type = iv.getIntervalType();
433
Tools::Interval& Tools::Interval::operator=( const Interval & iv )
435
*this = *( static_cast<const IInterval*>( &iv ) );
439
bool Tools::Interval::operator==( const Interval& iv ) const
442
m_type == iv.m_type &&
443
m_low >= iv.m_low - std::numeric_limits<double>::epsilon() &&
444
m_low <= iv.m_low + std::numeric_limits<double>::epsilon() &&
445
m_high >= iv.m_high - std::numeric_limits<double>::epsilon() &&
446
m_high <= iv.m_high + std::numeric_limits<double>::epsilon() )
452
bool Tools::Interval::operator!=( const Interval& iv ) const
454
return !( *this == iv );
457
double Tools::Interval::getLowerBound() const
462
double Tools::Interval::getUpperBound() const
467
void Tools::Interval::setBounds( double l, double h )
475
bool Tools::Interval::intersectsInterval( const IInterval& i ) const
477
return intersectsInterval( i.getIntervalType(), i.getLowerBound(), i.getUpperBound() );
480
bool Tools::Interval::intersectsInterval( IntervalType type, const double low, const double high ) const
482
if ( m_high < m_low )
483
throw IllegalStateException(
484
"Tools::Interval::intersectsInterval: high boundary is smaller than low boundary."
487
if ( m_low > high || m_high < low ) return false;
488
if (( m_low > low && m_low < high ) || ( m_high > low && m_high < high ) ) return true;
495
if ( type == IT_CLOSED || type == IT_LEFTOPEN ) return true;
498
else if ( m_high == low )
500
if ( type == IT_CLOSED || type == IT_RIGHTOPEN ) return true;
505
if ( m_low == high || m_high == low ) return false;
510
if ( type == IT_CLOSED || type == IT_LEFTOPEN ) return true;
513
else if ( m_high == low )
523
else if ( m_high == low )
525
if ( type == IT_CLOSED || type == IT_RIGHTOPEN ) return true;
534
bool Tools::Interval::containsInterval( const IInterval& i ) const
536
if ( m_high < m_low )
537
throw IllegalStateException(
538
"Tools::Interval::containsInterval: high boundary is smaller than low boundary."
541
double low = i.getLowerBound();
542
double high = i.getUpperBound();
543
IntervalType type = i.getIntervalType();
545
if ( m_low < low && m_high > high ) return true;
546
if ( m_low > low || m_high < high ) return false;
553
if (( m_low == low && m_high == high && type != IT_OPEN ) ||
554
( m_low == low && ( type == IT_CLOSED || type == IT_RIGHTOPEN ) ) ||
555
( m_high == high && ( type == IT_CLOSED || type == IT_LEFTOPEN ) ) )
559
if ( m_high == high && ( type == IT_CLOSED || type == IT_LEFTOPEN ) )
563
if ( m_low == low && ( type == IT_CLOSED || type == IT_RIGHTOPEN ) )
571
Tools::IntervalType Tools::Interval::getIntervalType() const
577
void Tools::uncompressRLE(
578
unsigned long blockSize,
579
byte* in, unsigned long lin,
580
byte** out, unsigned long& lout )
582
if ( lin == 0 ) { *out = 0; lout = 0; return; }
584
byte *data = 0, *pdata = 0, *pin;
585
byte* cv = new byte[blockSize];
586
byte* pv = new byte[blockSize];
588
unsigned long bufferLength = 2 * lin;
591
std::memcpy( cv, pin, blockSize );
592
pv[0] = ~cv[0]; // force next character to be different.
593
assert( pv[0] != cv[0] );
594
data = new byte[bufferLength];
597
while ( pin < in + lin )
599
std::memcpy( cv, pin, blockSize );
602
assert( pin <= in + lin );
605
bufferLength - static_cast<unsigned long>( pdata - data ) <=
612
tmp = new byte[2 * bufferLength];
622
std::memcpy( tmp, data, bufferLength );
623
pdata = tmp + ( pdata - data );
630
std::memcpy( pdata, cv, blockSize );
633
if ( memcmp( cv, pv, blockSize ) == 0 && pin < in + lin )
635
std::memcpy( &rl, pin, sizeof( byte ) );
636
pin += sizeof( byte );
637
assert( pin <= in + lin );
639
bufferLength - static_cast<unsigned long>( pdata - data ) <=
643
unsigned long l = std::max( bufferLength, rl * blockSize );
648
tmp = new byte[2 * l];
658
std::memcpy( tmp, data, bufferLength );
659
pdata = tmp + ( pdata - data );
663
bufferLength = 2 * l;
668
std::memcpy( pdata, cv, blockSize );
672
std::memcpy( cv, pin, blockSize );
674
assert( pv[0] != cv[0] );
676
else std::memcpy( pv, cv, blockSize );
683
*out = new byte[lout];
693
std::memcpy( *out, data, lout );
699
#if HAVE_GETTIMEOFDAY
700
Tools::ResourceUsage::ResourceUsage()
705
void Tools::ResourceUsage::start()
707
struct timezone dummy;
709
if ( getrusage( RUSAGE_SELF, &m_tmpRU ) != 0 )
710
throw IllegalStateException(
711
"Tools::ResourceUsage::start: getrusage failed."
714
if ( gettimeofday( &m_tmpTV, &dummy ) != 0 )
715
throw IllegalStateException(
716
"Tools::ResourceUsage::start: gettimeofday failed."
719
// maximum resident set size
720
m_peakMemory = std::max( m_peakMemory, m_tmpRU.ru_maxrss );
723
m_totalMemory = std::max( m_totalMemory, m_tmpRU.ru_ixrss + m_tmpRU.ru_idrss + m_tmpRU.ru_isrss + m_tmpRU.ru_maxrss );
726
void Tools::ResourceUsage::stop()
728
struct timezone dummy;
733
if ( getrusage( RUSAGE_SELF, &ru ) != 0 )
734
throw IllegalStateException(
735
"Tools::ResourceUsage::stop: getrusage failed."
738
if ( gettimeofday( &tv, &dummy ) != 0 )
739
throw IllegalStateException(
740
"Tools::ResourceUsage::stop: gettimeofday failed."
744
subtractTimeval( dif, tv, m_tmpTV );
745
addTimeval( m_totalTime, dif );
748
subtractTimeval( dif, ru.ru_stime, m_tmpRU.ru_stime );
749
addTimeval( m_systemTime, dif );
752
subtractTimeval( dif, ru.ru_utime, m_tmpRU.ru_utime );
753
addTimeval( m_userTime, dif );
756
m_readIO += ru.ru_inblock - m_tmpRU.ru_inblock;
757
m_writeIO += ru.ru_oublock - m_tmpRU.ru_oublock;
759
// maximum resident set size
760
m_peakMemory = std::max( m_peakMemory, ru.ru_maxrss );
763
m_totalMemory = std::max( m_totalMemory, ru.ru_ixrss + ru.ru_idrss + ru.ru_isrss + ru.ru_maxrss );
766
m_pageFaults += ru.ru_majflt - m_tmpRU.ru_majflt;
769
void Tools::ResourceUsage::reset()
776
m_totalTime.tv_sec = 0;
777
m_totalTime.tv_usec = 0;
778
m_userTime.tv_sec = 0;
779
m_userTime.tv_usec = 0;
780
m_systemTime.tv_sec = 0;
781
m_systemTime.tv_usec = 0;
784
double Tools::ResourceUsage::combineTime( const struct timeval& t )
787
static_cast<double>( t.tv_sec ) +
788
static_cast<double>( t.tv_usec ) / 1000000.0;
791
void Tools::ResourceUsage::addTimeval( struct timeval& result, const struct timeval& a )
793
result.tv_sec += a.tv_sec;
794
result.tv_usec += a.tv_usec;
796
if ( result.tv_usec > 1000000 )
798
long div = result.tv_usec / 1000000;
799
result.tv_sec += div;
800
result.tv_usec -= div * 1000000;
804
void Tools::ResourceUsage::subtractTimeval( struct timeval& result, const struct timeval& a, const struct timeval& b )
806
result.tv_sec = a.tv_sec - b.tv_sec;
807
result.tv_usec = a.tv_usec - b.tv_usec;
809
if ( result.tv_usec < 0 )
812
result.tv_usec += 1000000;
816
double Tools::ResourceUsage::getTotalTime()
818
return combineTime( m_totalTime );
821
double Tools::ResourceUsage::getUserTime()
823
return combineTime( m_userTime );
826
double Tools::ResourceUsage::getSystemTime()
828
return combineTime( m_systemTime );
831
long Tools::ResourceUsage::getPageFaults()
836
long Tools::ResourceUsage::getReadIO()
841
long Tools::ResourceUsage::getWriteIO()
846
long Tools::ResourceUsage::getPeakResidentMemoryUsage()
851
long Tools::ResourceUsage::getTotalMemoryUsage()
853
return m_totalMemory;
858
Tools::CycleCounter::CycleCounter() : m_totalCycles( 0 ), m_bRunning( false )
862
double Tools::CycleCounter::getCPUMHz()
864
unsigned long long v1 = rdtsc();
866
unsigned long long v2 = rdtsc();
867
return (( v2 - v1 ) / 1e7 );
870
double Tools::CycleCounter::getCyclesPerSecond()
872
unsigned long long v1 = rdtsc();
874
unsigned long long v2 = rdtsc();
875
return (( v2 - v1 ) / 10 );
878
inline unsigned long long Tools::CycleCounter::rdtsc()
880
unsigned long long ret;
881
__asm__ __volatile__( "rdtsc": "=A"( ret ): );
885
void Tools::CycleCounter::start()
889
m_tmpCycles = rdtsc();
894
void Tools::CycleCounter::stop()
898
unsigned long long t = rdtsc();
899
m_totalCycles += t - m_tmpCycles;
904
void Tools::CycleCounter::reset()
910
double Tools::CycleCounter::getTotalCycles()
912
return m_totalCycles;
917
Tools::SharedLock::SharedLock( pthread_rwlock_t* pLock )
920
pthread_rwlock_rdlock( m_pLock );
923
Tools::SharedLock::~SharedLock()
925
pthread_rwlock_unlock( m_pLock );
928
Tools::ExclusiveLock::ExclusiveLock( pthread_rwlock_t* pLock )
931
pthread_rwlock_wrlock( m_pLock );
934
Tools::ExclusiveLock::~ExclusiveLock()
936
pthread_rwlock_unlock( m_pLock );
940
Tools::StringTokenizer::StringTokenizer( const std::string& str, const std::string& delimiters )
943
// Skip delimiters at beginning.
944
std::string::size_type lastPos = str.find_first_not_of( delimiters, 0 );
945
// Find first "non-delimiter".
946
std::string::size_type pos = str.find_first_of( delimiters, lastPos );
948
while ( std::string::npos != pos || std::string::npos != lastPos )
950
// Found a token, add it to the vector.
951
m_token.push_back( str.substr( lastPos, pos - lastPos ) );
952
// Skip delimiters. Note the "not_of"
953
lastPos = str.find_first_not_of( delimiters, pos );
954
// Find next "non-delimiter"
955
pos = str.find_first_of( delimiters, lastPos );
959
std::string Tools::StringTokenizer::getNextToken()
961
return m_token.at( m_index++ );
964
bool Tools::StringTokenizer::hasMoreTokens()
966
return ( m_index < m_token.size() );
969
void Tools::StringTokenizer::reset()
974
std::string Tools::trimLeft( const std::string& source, const std::string& t )
976
std::string str = source;
977
return str.erase( 0, source.find_first_not_of( t ) );
980
std::string Tools::trimRight( const std::string& source, const std::string& t )
982
std::string str = source;
983
return str.erase( str.find_last_not_of( t ) + 1 );
986
std::string Tools::trim( const std::string& source, const std::string& t )
988
std::string str = source;
989
return trimLeft( trimRight( str, t ), t );
992
char Tools::toLower( char c )
995
// MSVC doesn't seem to have std::tolower(char)
997
return std::tolower( c, loc );
999
return std::tolower( c );
1003
char Tools::toUpper( char c )
1006
// MSVC doesn't seem to have std::toupper(char)
1008
return std::toupper( c, loc );
1010
return std::toupper( c );
1014
std::string Tools::toUpperCase( const std::string& s )
1017
transform( t.begin(), t.end(), t.begin(), Tools::toUpper );
1021
std::string Tools::toLowerCase( const std::string& s )
1024
transform( t.begin(), t.end(), t.begin(), Tools::toLower );
1028
unsigned long long choose( unsigned long a, unsigned long k )
1030
unsigned long long cnm = 1, n = a, m = k;
1031
unsigned long long i, f;
1033
if ( m * 2 > n ) m = n - m;
1034
for ( i = 1 ; i <= m; n--, i++ )
1036
if (( f = n ) % i == 0 ) f /= i;
1043
Tools::Architecture Tools::System::getArchitecture()
1045
union {double f; unsigned long i[2];} convert;
1048
// Note: Old versions of the Gnu g++ compiler may make an error here,
1049
// compile with the option -fenum-int-equiv to fix the problem
1050
if ( convert.i[1] == 0x3FF00000 ) return ARCH_LITTLEENDIAN;
1051
else if ( convert.i[0] == 0x3FF00000 ) return ARCH_BIGENDIAN;
1052
else return ARCH_NONIEEE;
1055
std::ostream& Tools::operator<<( std::ostream& os, const Tools::PropertySet& p )
1057
std::map<std::string, Variant>::const_iterator it;
1059
for ( it = p.m_propertySet.begin(); it != p.m_propertySet.end(); it++ )
1061
if ( it != p.m_propertySet.begin() ) os << ", ";
1063
switch (( *it ).second.m_varType )
1066
os << ( *it ).first << ": " << ( *it ).second.m_val.lVal;
1069
os << ( *it ).first << ": " << ( *it ).second.m_val.llVal;
1072
os << ( *it ).first << ": " << ( *it ).second.m_val.bVal;
1075
os << ( *it ).first << ": " << ( *it ).second.m_val.iVal;
1078
os << ( *it ).first << ": " << ( *it ).second.m_val.fltVal;
1081
os << ( *it ).first << ": " << ( *it ).second.m_val.dblVal;
1084
os << ( *it ).first << ": " << ( *it ).second.m_val.cVal;
1087
os << ( *it ).first << ": " << ( *it ).second.m_val.uiVal;
1090
os << ( *it ).first << ": " << ( *it ).second.m_val.ulVal;
1093
os << ( *it ).first << ": " << ( *it ).second.m_val.ullVal;
1096
os << ( *it ).first << ": " << ( *it ).second.m_val.intVal;
1099
os << ( *it ).first << ": " << ( *it ).second.m_val.uintVal;
1102
os << ( *it ).first << ": " << ( *it ).second.m_val.blVal;
1105
os << ( *it ).first << ": " << ( *it ).second.m_val.pcVal;
1108
os << ( *it ).first << ": ?";
1111
os << ( *it ).first << ": empty";
1114
os << ( *it ).first << ": unknown";
1121
std::ostream& Tools::operator<<( std::ostream& os, const Tools::Interval& iv )
1123
os << iv.m_type << " " << iv.m_low << " " << iv.m_high;
1127
std::ostream& Tools::operator<<( std::ostream& os, const Tools::UniversalHash& h )
1131
for ( unsigned long i = 0; i < h.m_k; i++ )
1132
os << " " << h.m_a[i];