00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef moses_PackedArray_h
00023 #define moses_PackedArray_h
00024
00025 #include <vector>
00026 #include <cmath>
00027 #include <cstring>
00028 #include <cstdio>
00029
00030 #include "ThrowingFwrite.h"
00031
00032 namespace Moses
00033 {
00034
00035 template <typename T = size_t, typename D = unsigned char>
00036 class PackedArray
00037 {
00038 protected:
00039 static size_t m_dataBits;
00040
00041 size_t m_size;
00042 size_t m_storageSize;
00043 D* m_storage;
00044
00045 public:
00046 PackedArray() {
00047 m_size = 0;
00048 m_storageSize = 0;
00049 m_storage = new D[0];
00050 }
00051
00052 PackedArray(size_t size, size_t bits) : m_size(size) {
00053 m_storageSize = ceil(float(bits * size) / float(m_dataBits));
00054 m_storage = new D[m_storageSize];
00055 }
00056
00057 PackedArray(const PackedArray<T, D> &c) {
00058 m_size = c.m_size;
00059
00060 m_storageSize = c.m_storageSize;
00061 m_storage = new D[m_storageSize];
00062
00063 std::memcpy(m_storage, c.m_storage, m_storageSize * sizeof(D));
00064 }
00065
00066 virtual ~PackedArray() {
00067 delete [] m_storage;
00068 m_size = 0;
00069 m_storageSize = 0;
00070 m_storage = 0;
00071 }
00072
00073 T Get(size_t i, size_t bits) const {
00074 T out = 0;
00075
00076 size_t bitstart = (i * bits);
00077 size_t bitpos = bitstart;
00078
00079 size_t zero = ((1ul << (bits)) - 1);
00080
00081 while(bitpos - bitstart < bits) {
00082 size_t pos = bitpos / m_dataBits;
00083 size_t off = bitpos % m_dataBits;
00084
00085 out |= (T(m_storage[pos]) << (bitpos - bitstart)) >> off;
00086
00087 bitpos += (m_dataBits - off);
00088 }
00089
00090 out &= zero;
00091 return out;
00092 }
00093
00094 void Set(size_t i, T v, size_t bits) {
00095 size_t bitstart = (i * bits);
00096 size_t bitpos = bitstart;
00097
00098 while(bitpos - bitstart < bits) {
00099 size_t pos = bitpos / m_dataBits;
00100 size_t off = bitpos % m_dataBits;
00101
00102 size_t rest = bits - (bitpos - bitstart);
00103 D zero = ~((1ul << (rest + off)) - 1) | ((1ul << off) - 1);
00104
00105 m_storage[pos] &= zero;
00106 m_storage[pos] |= v << off;
00107 v = v >> (m_dataBits - off);
00108 bitpos += (m_dataBits - off);
00109 }
00110 }
00111
00112 virtual D*& GetStorage() {
00113 return m_storage;
00114 }
00115
00116 virtual size_t GetStorageSize() const {
00117 return m_storageSize;
00118 }
00119
00120 virtual size_t Size() const {
00121 return m_size;
00122 }
00123
00124 virtual size_t Load(std::FILE* in) {
00125 size_t a1 = std::ftell(in);
00126
00127 size_t read = 0;
00128 read += std::fread(&m_size, sizeof(m_size), 1, in);
00129 read += std::fread(&m_storageSize, sizeof(m_storageSize), 1, in);
00130 delete [] m_storage;
00131 m_storage = new D[m_storageSize];
00132 read += std::fread(m_storage, sizeof(D), m_storageSize, in);
00133
00134 size_t a2 = std::ftell(in);
00135 return a2 - a1;
00136 }
00137
00138 virtual size_t Save(std::FILE* out) {
00139 size_t a1 = std::ftell(out);
00140
00141 ThrowingFwrite(&m_size, sizeof(m_size), 1, out);
00142 ThrowingFwrite(&m_storageSize, sizeof(m_storageSize), 1, out);
00143 ThrowingFwrite(m_storage, sizeof(D), m_storageSize, out);
00144
00145 size_t a2 = std::ftell(out);
00146 return a2 - a1;
00147 }
00148
00149 };
00150
00151 template <typename T, typename D>
00152 size_t PackedArray<T, D>::m_dataBits = sizeof(D)*8;
00153
00154
00155
00156 template <typename T = size_t, typename D = unsigned char>
00157 class PairedPackedArray : public PackedArray<T,D>
00158 {
00159 public:
00160 PairedPackedArray() : PackedArray<T,D>() {}
00161
00162 PairedPackedArray(size_t size, size_t bits1, size_t bits2)
00163 : PackedArray<T, D>(size, bits1 + bits2) { }
00164
00165 void Set(size_t i, T a, T b, size_t bits1, size_t bits2) {
00166 T c = 0;
00167 c = a | (b << bits1);
00168 PackedArray<T,D>::Set(i, c, bits1 + bits2);
00169 }
00170
00171 void Set(size_t i, std::pair<T,T> p, size_t bits1, size_t bits2) {
00172 T c = 0;
00173 c = p.second | (p.first << bits1);
00174 PackedArray<T, D>::Set(i, c);
00175 }
00176
00177 std::pair<T, T> Get(size_t i, size_t bits1, size_t bits2) {
00178 T v = PackedArray<T, D>::Get(i, bits1 + bits2);
00179 T a = v & ((1 << bits1) - 1);
00180 T b = v >> bits1;
00181 return std::pair<T, T>(a, b);
00182 }
00183 };
00184
00185 }
00186
00187 #endif