#ifndef __FAST_ARRAY_H__ #define __FAST_ARRAY_H__ #include "rings.h" #include "options.h" template < typename Ring > struct Mapping { typedef typename Ring::T T; std::vector<T> data; Mapping() {} Mapping(const Mapping& x) : data(x.data) {} Mapping(size_t size = 0) : data(size, 0) {} inline size_t size() const { return data.size(); } inline T operator[] (size_t i) const { return data[i]; } inline void assign(size_t i, T val) { data[i] = val; } inline void combine(T beta, const Mapping& b) { size_t _size = size(); for (size_t i = 0; i < _size; i++) data[i] = Ring::plus(data[i], Ring::multiply(beta, b.data[i])); } }; #if OPTIMIZED_MAPPINGS template < size_t i, size_t shift > struct Consts { static const uint64_t clone = (Consts<i-1, shift>::clone << shift) | 1; static const uint64_t mask = (Consts<i-1, shift>::mask << shift) | 3; }; template < size_t shift > struct Consts<0, shift> { static const uint64_t clone = 0; static const uint64_t mask = 0; }; template < bool isZ4 > struct FastArray { typedef int T; enum { valuesPerWord = 16 }; enum { words = (MAX_EDGES + valuesPerWord - 1) / valuesPerWord }; enum { shift = 4 }; static const uint64_t clone = Consts<valuesPerWord, shift>::clone; static const uint64_t mask = Consts<valuesPerWord, shift>::mask; size_t size_; uint64_t data[words]; FastArray() {} FastArray(const FastArray& x) : size_(x.size_) { memcpy(data, x.data, sizeof(data)); } FastArray(size_t size = 0) : size_(size) { assert(size <= MAX_EDGES); memset(data, 0, sizeof(data)); } inline size_t size() const { return size_; } inline T operator[] (size_t i) const { return (data[i >> 4] >> ((i & 0xF) << 2)) & 3; } inline void assign(size_t i, T val) { size_t w = i >> 4; size_t off = i & 0xF; data[w] &= ~(((uint64_t)3) << (off << 2)); data[w] |= (((uint64_t)val) << (off << 2)); } inline void combine(T beta, const FastArray& b) { for (size_t i = 0; i < words; i++) { if (isZ4) data[i] = (data[i] + ((beta * b.data[i]) & mask)) & mask; else data[i] = data[i] ^ ((clone * beta) & b.data[i]); } } }; template <> struct Mapping< Ring::Z4<int> > : public FastArray<true> { Mapping(const Mapping& x) : FastArray(x) {} Mapping(size_t s = 0) : FastArray(s) {} }; template <> struct Mapping< Ring::Z2_2<int> > : public FastArray<false> { Mapping(const Mapping& x) : FastArray(x) {} Mapping(size_t s = 0) : FastArray(s) {} }; #endif #endif