libStatGen Software  1
PackedVector.h
00001 /*
00002  *  Copyright (C) 2010  Regents of the University of Michigan
00003  *
00004  *   This program is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   This program is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00018 #ifndef __PACKEDVECTOR_H
00019 #define __PACKEDVECTOR_H
00020 
00021 
00022 // STL:
00023 #include <ostream>
00024 #include <sstream>
00025 #include <string>
00026 
00027 #include "Generic.h"
00028 
00029 
00030 //
00031 // This file implements a packed vector template based on the
00032 // getter/setter code used in MemoryMapArray.h
00033 //
00034 
00035 
00036 template <
00037 uint32_t accessorFunc(std::vector<uint8_t> &base, uint32_t index),
00038 void setterFunc(std::vector<uint8_t> &base, uint32_t index, uint32_t value),
00039 size_t elementCount2BytesFunc(uint32_t elementCount)
00040 >
00041 class PackedVector
00042 {
00043 protected:
00044     std::vector<uint8_t> m_data;
00045     size_t              m_elementCount;
00046     double              m_growthRateMultiplier;
00047     double              m_growthRateAdder;
00048 public:
00049     PackedVector() :
00050         m_elementCount(0),
00051         m_growthRateMultiplier(1.20),
00052         m_growthRateAdder(128) {;}
00053 
00054     // accessing
00055     inline uint32_t operator[](uint32_t i)
00056     {
00057         return accessorFunc(m_data, i);
00058     }
00059     inline void set(uint32_t i, uint32_t v)
00060     {
00061         setterFunc(m_data, i, v);
00062     }
00063 
00064     size_t getElementCount() const
00065     {
00066         return m_elementCount;
00067     }
00068 
00069     double getUtilization() {
00070         return elementCount2BytesFunc(m_elementCount) / (double) m_data.capacity();
00071     }
00072 
00073     void reserve(uint32_t reserveElements) {
00074         m_data.reserve(elementCount2BytesFunc(reserveElements));
00075     }
00076 
00077     size_t size() {return m_elementCount;}
00078 
00079     void resize(uint32_t newSize) {
00080         m_elementCount = newSize;
00081         m_data.resize(elementCount2BytesFunc(m_elementCount));
00082     }
00083 
00084     // it's a bit of a challenge to optimize this...
00085     void push_back(uint32_t value) {
00086         m_elementCount++;
00087         if(elementCount2BytesFunc(m_elementCount) >= m_data.size()) {
00088 
00089             if( (elementCount2BytesFunc(m_elementCount)) > m_data.capacity())
00090             {
00091                 size_t newCapacity = (size_t) (m_data.capacity() * m_growthRateMultiplier);
00092 
00093                 // for small capacities, small fractional multipliers don't work,
00094                 // so we check and do a linear increase in those cases:
00095                 if(newCapacity == m_data.capacity()) {
00096                     newCapacity = (size_t) (m_data.capacity() + m_growthRateAdder);
00097                 }
00098 
00099                 m_data.reserve(newCapacity);
00100             }
00101 
00102         }
00103         m_data.resize(elementCount2BytesFunc(m_elementCount));
00104         set(m_elementCount-1, value);
00105     }
00106 };
00107 
00108 typedef PackedVector<
00109 PackedAccess_1Bit,
00110 PackedAssign_1Bit,
00111 Packed1BitElementCount2Bytes
00112 > PackedVectorBool_t;
00113 
00114 typedef PackedVector<
00115 PackedAccess_2Bit,
00116 PackedAssign_2Bit,
00117 Packed2BitElementCount2Bytes
00118 > PackedVector2Bit_t;
00119 
00120 typedef PackedVector<
00121 PackedAccess_4Bit,
00122 PackedAssign_4Bit,
00123 Packed4BitElementCount2Bytes
00124 > PackedVector4Bit_t;
00125 
00126 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends