1 #ifndef CARMA_DBMS_COLUMN_H
2 #define CARMA_DBMS_COLUMN_H
30 template <
typename T >
31 class Column :
public ::std::vector< T > {
53 std::string
getName()
const {
return name_;}
59 bool hasNulls()
const {
return ! nullIndices_.empty();}
72 this->push_back(nullValue_);
73 nullIndices_.push_back(this->size()-1);
82 nullValue_ = nullValue;
83 for(::
size_t i = 0; i < nullIndices_.size(); i++) {
84 (*this)[nullIndices_[i]] = nullValue_;
100 std::ostringstream ss;
101 unsigned int nullPos = 0;
103 for (::
size_t i=0; i<this->size(); i++) {
104 if(nullPos < nullIndices_.size() && i == nullIndices_[nullPos]) {
128 if(index >= this->size()) {
129 std::ostringstream emsg;
130 emsg <<
"Requested index " << index <<
" is >= number of elements "
131 <<
"which is " << this->size();
135 std::vector< unsigned >::const_iterator iter;
136 for(iter=nullIndices_.begin(); iter!=nullIndices_.end(); iter++) {
139 }
else if (*iter > index) {
155 for(::
size_t i=0; i<this->size(); i++) {
170 return sum()/(this->size()-nullIndices_.size());
180 for(
int i=0; i<this->size(); i++) {
186 for(
int i=0; i<this->size(); i++) {
188 max = std::max((*
this)[i],max);
201 for(
int i=0; i<this->size(); i++) {
207 for(
int i=0; i<this->size(); i++) {
209 min = std::min((*
this)[i],min);
226 std::vector< unsigned >::const_iterator niter = nullIndices_.begin();
227 bool elementIsNull =
false;
228 bool hasNulls = !nullIndices_.empty();
229 for(iter = this->begin(); iter != this->end(); iter++) {
232 while(niter != nullIndices_.end() && *niter < count) {
236 elementIsNull = (
hasNulls) ? (*niter == count) :
false;
237 if(!elementIsNull && (*iter == value)) {
254 bool includeNull =
true )
const;
258 std::vector< unsigned > nullIndices_;
264 class ValueMajorIndexMinorOrderingPred {
269 explicit ValueMajorIndexMinorOrderingPred(
const Column & c );
271 bool operator()(
const size_t rhsIndex,
272 const size_t lhsIndex )
const;
296 template <
typename T,
typename U>
299 std::ostringstream emsg;
300 if(keyColumn.size() != valueColumn.size()) {
301 emsg <<
"The key column has " << keyColumn.size() <<
" elements "
302 <<
"while the value column has " << valueColumn.size()
303 <<
" elements. This method can only be run on columns of the "
309 emsg <<
"The key column has NULL values. Both columns must not "
315 emsg <<
"The value column has NULL values. Both columns must not "
321 emsg <<
"Some of the key column's values are not distinct. In order "
322 <<
"for the mapping to work, all of this column's elements "
329 std::map<T,U> mapping;
330 for ( ; iter != keyColumn.end(); iter++) {
331 mapping[*iter] = *niter;
352 template <
typename T> std::ostream&
operator<<
359 template <
typename T >
369 template <
typename T >
373 const size_t rhsIndex,
374 const size_t lhsIndex )
const
376 if ( c_[ rhsIndex ] == c_[ lhsIndex ] )
377 return (rhsIndex < lhsIndex);
379 return (c_[ rhsIndex ] < c_[ lhsIndex ]);
383 template <
typename T >
386 const ::std::string & name,
387 const bool includeNull )
const
389 const size_t mySize = this->size();
393 ::std::vector< unsigned > localNullIndices = nullIndices_;
394 if ( localNullIndices.empty() == false ) {
395 stable_sort( localNullIndices.begin(), localNullIndices.end() );
397 ::std::vector< unsigned >::iterator eraseBegin =
398 unique( localNullIndices.begin(), localNullIndices.end() );
400 if ( eraseBegin != localNullIndices.end() )
401 localNullIndices.erase( eraseBegin, localNullIndices.end() );
405 ::std::vector< unsigned > nonNullIndices;
407 if ( localNullIndices.size() < mySize )
408 nonNullIndices.reserve( mySize - localNullIndices.size() );
410 ::std::vector< unsigned >::const_iterator k =
411 localNullIndices.begin();
413 const ::std::vector< unsigned >::const_iterator kEnd =
414 localNullIndices.end();
416 for (
unsigned i = 0; i < mySize; ++i ) {
417 if ( (k != kEnd) && (i == *k) )
420 nonNullIndices.push_back( i );
424 if ( nonNullIndices.empty() == false ) {
428 const ValueMajorIndexMinorOrderingPred orderingPred( *
this );
430 stable_sort( nonNullIndices.begin(),
431 nonNullIndices.end(),
437 ::std::vector< unsigned > firstIndexForNonNullValue;
438 firstIndexForNonNullValue.reserve( nonNullIndices.size() );
440 ::std::vector< unsigned >::const_iterator j =
441 nonNullIndices.begin();
443 const ::std::vector< unsigned >::const_iterator jEnd =
444 nonNullIndices.end();
447 firstIndexForNonNullValue.push_back( *j );
448 ::std::vector< unsigned >::const_iterator k = j;
451 for ( ; j != jEnd; ++j ) {
452 if ( ((*
this)[*j]) == ((*
this)[*k]) )
456 firstIndexForNonNullValue.push_back( *j );
460 nonNullIndices.swap( firstIndexForNonNullValue );
464 stable_sort( nonNullIndices.begin(), nonNullIndices.end() );
470 const size_t distinctCount =
471 ((includeNull && (localNullIndices.empty() ==
false)) ? 1 : 0) +
472 nonNullIndices.size();
474 if ( distinctCount != 0 ) {
475 distinct.reserve( distinctCount );
477 const ::std::vector< unsigned >::const_iterator kBegin =
478 localNullIndices.begin();
480 const ::std::vector< unsigned >::const_iterator kEnd =
481 localNullIndices.end();
483 ::std::vector< unsigned >::const_iterator k = kBegin;
485 ::std::vector< unsigned >::const_iterator j =
486 nonNullIndices.begin();
488 const ::std::vector< unsigned >::const_iterator jEnd =
489 nonNullIndices.end();
491 for (
unsigned i = 0; i < mySize; ++i ) {
492 if ( (k != kEnd) && (i == *k) ) {
493 if ( includeNull && (k == kBegin) )
496 }
else if ( (j != jEnd) && (i == *j) ) {
498 distinct.push_back( (*
this)[i] );
507 #endif // CARMA_DBMS_COLUMN_H
template to mimic a db column.
an exception indicating that an object is in an illegal state for the operation that was called on or...
void setNullValue(const T &nullValue)
Set the value of NULL values.
void push_back_null()
add a NULL element to the end of the column
Exception class for errors.
virtual ~Column()
destructor, derived classes may want to override
bool hasNulls() const
return true if the column contains NULL values
Column(const std::string &name)
constuctor
int indexOf(const T &value) const
find the first occurence of a specified value
IllegalArgumentException class.
T sum() const
sum all non-null column values FIXME probably need a way to guard against doing this for strings ...
T max() const
get the maximum non-null column values
std::vector< unsigned > getNullIndices() const
get the indices for NULL values.
std::map< T, U > columnsToMap(const carma::dbms::Column< T > &keyColumn, const carma::dbms::Column< U > &valueColumn)
T getNullValue() const
get the NULL data value
#define CARMA_EXCEPTION(x, y)
Trick to get the file name and line number passed to the exception handler.
T mean() const
get the average of the non-null column values
std::string toString() const
return a string representation of the column
Column getDistinctValues(const ::std::string &name="Distinct Values", bool includeNull=true) const
get distinct values of a column
T min() const
get the minumum non-null column value
bool isElementNull(unsigned index) const
is the specified element null?
std::string getName() const
get the column name