libStatGen Software 1
PackedVector.h
1/*
2 * Copyright (C) 2010 Regents of the University of Michigan
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef __PACKEDVECTOR_H
19#define __PACKEDVECTOR_H
20
21
22// STL:
23#include <ostream>
24#include <sstream>
25#include <string>
26
27#include "Generic.h"
28
29
30//
31// This file implements a packed vector template based on the
32// getter/setter code used in MemoryMapArray.h
33//
34
35
36template <
37uint32_t accessorFunc(std::vector<uint8_t> &base, uint32_t index),
38void setterFunc(std::vector<uint8_t> &base, uint32_t index, uint32_t value),
39size_t elementCount2BytesFunc(uint32_t elementCount)
40>
42{
43protected:
44 std::vector<uint8_t> m_data;
45 size_t m_elementCount;
46 double m_growthRateMultiplier;
47 double m_growthRateAdder;
48public:
49 PackedVector() :
50 m_elementCount(0),
51 m_growthRateMultiplier(1.20),
52 m_growthRateAdder(128) {;}
53
54 // accessing
55 inline uint32_t operator[](uint32_t i)
56 {
57 return accessorFunc(m_data, i);
58 }
59 inline void set(uint32_t i, uint32_t v)
60 {
61 setterFunc(m_data, i, v);
62 }
63
64 size_t getElementCount() const
65 {
66 return m_elementCount;
67 }
68
69 double getUtilization() {
70 return elementCount2BytesFunc(m_elementCount) / (double) m_data.capacity();
71 }
72
73 void reserve(uint32_t reserveElements) {
74 m_data.reserve(elementCount2BytesFunc(reserveElements));
75 }
76
77 size_t size() {return m_elementCount;}
78
79 void resize(uint32_t newSize) {
80 m_elementCount = newSize;
81 m_data.resize(elementCount2BytesFunc(m_elementCount));
82 }
83
84 // it's a bit of a challenge to optimize this...
85 void push_back(uint32_t value) {
86 m_elementCount++;
87 if(elementCount2BytesFunc(m_elementCount) >= m_data.size()) {
88
89 if( (elementCount2BytesFunc(m_elementCount)) > m_data.capacity())
90 {
91 size_t newCapacity = (size_t) (m_data.capacity() * m_growthRateMultiplier);
92
93 // for small capacities, small fractional multipliers don't work,
94 // so we check and do a linear increase in those cases:
95 if(newCapacity == m_data.capacity()) {
96 newCapacity = (size_t) (m_data.capacity() + m_growthRateAdder);
97 }
98
99 m_data.reserve(newCapacity);
100 }
101
102 }
103 m_data.resize(elementCount2BytesFunc(m_elementCount));
104 set(m_elementCount-1, value);
105 }
106};
107
108typedef PackedVector<
109PackedAccess_1Bit,
110PackedAssign_1Bit,
111Packed1BitElementCount2Bytes
113
114typedef PackedVector<
115PackedAccess_2Bit,
116PackedAssign_2Bit,
117Packed2BitElementCount2Bytes
119
120typedef PackedVector<
121PackedAccess_4Bit,
122PackedAssign_4Bit,
123Packed4BitElementCount2Bytes
125
126#endif