summaryrefslogtreecommitdiff
path: root/core/vector.hpp
blob: b6c7ccb5ca9653b34df0edbe27e9d3eb9263fb53 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#ifndef ZnnjWYk20gszrSSZENMjL1hM9gI
#define ZnnjWYk20gszrSSZENMjL1hM9gI

#include <inttypes.h>
#include <iostream>
#include <assert.h>
#include <boost/static_assert.hpp>
#include <boost/mpl/if.hpp>
#include <string>

#include "bit_access.hpp"
#include "mempool.hpp"
#include "scalar.hpp"
#include "string_helpers.hpp"
#include "template_helpers.hpp"



namespace VectorImpl {

using std::string;
using namespace boost::mpl;

template<
  typename RawPayload,
  uint32_t width = 8 * sizeof(RawPayload), 
  typename Writable = true_> // true_ or false_
class Vector {
public:
  typedef uint64_t ptr_t;
  typedef typename if_<Writable,
		       RawPayload,
		       const RawPayload>::type Payload;

  Vector(const string name, const ptr_t size) :
    mem((size * width + 7) / 8, name),
    barrierRead("barrier_read_" + name),
    barrierWrite("barrier_write_" + name),
    size(size) 
  {}
  //  Vector(Vector&&) = default;

  // direct access
  Payload & operator() (const ptr_t id) const {
    BOOST_STATIC_ASSERT((width >= 8));
    assert(id < size);
    return *((RawPayload*) (((char*) mem()) + (width / 8) * id));
  }

  // reader and writer
  Payload get(const ptr_t id) const {
    assert(id < size);
    if (width < 8) {
      return (uint8_t) bit_extract(mem(), width, id);
    }else{
      return *((RawPayload*) (((char*) mem()) + (width / 8) * id));
    }
  }

  void set(const ptr_t id, const RawPayload value) const {
    if (!Writable::value) DO_NOT_CALL;
    assert(id < size);
    if (width < 8) {
      bit_insert(mem(), (uint8_t) width, id, value);
    }else{
      *((RawPayload*) (((char*) mem()) + (width / 8) * id)) = value;
    }

  }

  void sync() const {
    if (Writable::value) {
      mem.sync();
      barrierRead.sync();
      barrierWrite.sync();
    }
  }

  void advise(const ptr_t base, const ptr_t length, int adv) {
    mem.advise(base * (width / 8), length * (width / 8), adv);
  }

  // associated memory container
  MemPool mem;

  // associated r/w-barrier
  // WARN: these barriers are not checked/updated in Vector but only
  //       by iterators/ranges using them; Vector checks only against
  //       the given size and nothing more
  Scalar<ptr_t> barrierRead, barrierWrite;

  // maximal number of elements
  const ptr_t size;

  // garantuee that size = 2^n
  STATIC_ASSERT_IS_POWER_OF_TWO(width);

private:
  Vector();
};

} // namespace VectorImpl

using VectorImpl::Vector;

#endif // ZnnjWYk20gszrSSZENMjL1hM9gI
contact: Jan Huwald // Impressum