summaryrefslogtreecommitdiffstats
path: root/akregator/src/mk4storage/metakit/src/column.h
blob: 96d1622ef24b1c2b192edcaa6b0f21418f9f7c9e (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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
// column.h --
// $Id$
// This is part of Metakit, see http://www.equi4.com/metakit/

/** @file
 * Definition of the column classes
 */

#ifndef __COLUMN_H__
#define __COLUMN_H__

/////////////////////////////////////////////////////////////////////////////
// Declarations in this file

  class c4_Column;          // a column in a table
  class c4_ColIter;         // an iterator over column data
  class c4_ColCache;          // manages a cache for columns

  class c4_Persist;         // not defined here
  class c4_Strategy;          // not defined here

/////////////////////////////////////////////////////////////////////////////

class c4_Column
{
  c4_PtrArray _segments;
  t4_i32 _position;
  t4_i32 _size;
  c4_Persist* _persist;
  t4_i32 _gap;
  int _slack;
  bool _dirty;
  
public:
  c4_Column (c4_Persist* persist_);
    //: Constructs a column using the specified persistence manager.
  ~c4_Column ();

  void SetBuffer(t4_i32);
    //: Allocate a new buffer of the specified size.

  c4_Persist* Persist() const;
    //: Returns persistence manager for this column, or zero.
  c4_Strategy& Strategy() const;
    //: Returns the associated strategy pointer.
  t4_i32 Position() const;
    //: Special access for the DUMP program.
  t4_i32 ColSize() const;
    //: Returns the number of bytes as stored on disk.
  bool IsDirty() const;
    //: Returns true if contents needs to be saved.

  void SetLocation(t4_i32, t4_i32);
    //: Sets the position and size of this column on file.
  void PullLocation(const t4_byte*& ptr_);
    //: Extract position and size of this column.

  int AvailAt(t4_i32 offset_) const;
    //: Returns number of bytes we can access at once.
  const t4_byte* LoadNow(t4_i32);
    //: Makes sure the data is loaded into memory.
  t4_byte* CopyNow(t4_i32);
    //: Makes sure a copy of the data is in memory.
  void Grow(t4_i32, t4_i32);
    //: Grows the buffer by inserting space.
  void Shrink(t4_i32, t4_i32);
    //: Shrinks the buffer by removing space.
  void SaveNow(c4_Strategy&, t4_i32 pos_);
    //: Save the buffer to file.

  const t4_byte* FetchBytes(t4_i32 pos_, int len_, c4_Bytes& buffer_, bool forceCopy_);
    //: Returns pointer to data, use buffer only if non-contiguous.
  void StoreBytes(t4_i32 pos_, const c4_Bytes& buffer_);
    //: Stores a copy of the buffer in the column.

  bool RequiresMap() const;
  void ReleaseAllSegments();

  static t4_i32 PullValue(const t4_byte*& ptr_);
  static void PushValue(t4_byte*& ptr_, t4_i32 v_);

  void InsertData(t4_i32 index_, t4_i32 count_, bool clear_);
  void RemoveData(t4_i32 index_, t4_i32 count_);
  void RemoveGap();

  enum { kSegBits = 12, kSegMax = 1 << kSegBits, kSegMask = kSegMax - 1 };

private:
  static int fSegIndex(t4_i32 offset_);
  static t4_i32 fSegOffset(int index_);
  static int fSegRest(t4_i32 offset_);

  bool UsesMap(const t4_byte*) const;
  bool IsMapped() const;

  void ReleaseSegment(int);
  void SetupSegments();
  void Validate() const;
  void FinishSlack();

  void MoveGapUp(t4_i32 pos_);
  void MoveGapDown(t4_i32 pos_);
  void MoveGapTo(t4_i32 pos_);

  t4_byte* CopyData(t4_i32, t4_i32, int);
};

/////////////////////////////////////////////////////////////////////////////

class c4_ColOfInts : public c4_Column
{
public:
  c4_ColOfInts (c4_Persist* persist_, int width_ =sizeof (t4_i32));

  int RowCount() const;
  void SetRowCount(int numRows_);

  void FlipBytes();
  
  int ItemSize(int index_);
  const void* Get(int index_, int& length_);
  void Set(int index_, const c4_Bytes& buf_);
  
  t4_i32 GetInt(int index_);
  void SetInt(int index_, t4_i32 value_);

  void Insert(int index_, const c4_Bytes& buf_, int count_);
  void Remove(int index_, int count_);

  static int CalcAccessWidth(int numRows_, t4_i32 colSize_);

  void SetAccessWidth(int bits_);
  void FixSize(bool fudge_);
  void ForceFlip();

  static int DoCompare(const c4_Bytes& b1_, const c4_Bytes& b2_);

private:
  typedef void (c4_ColOfInts::*tGetter) (int);
  typedef bool (c4_ColOfInts::*tSetter) (int, const t4_byte*);

  void Get_0b(int index_);
  void Get_1b(int index_);
  void Get_2b(int index_);
  void Get_4b(int index_);
  void Get_8i(int index_);
  void Get_16i(int index_);
  void Get_16r(int index_);
  void Get_32i(int index_);
  void Get_32r(int index_);
  void Get_64i(int index_);
  void Get_64r(int index_);

  bool Set_0b(int index_, const t4_byte* item_);
  bool Set_1b(int index_, const t4_byte* item_);
  bool Set_2b(int index_, const t4_byte* item_);
  bool Set_4b(int index_, const t4_byte* item_);
  bool Set_8i(int index_, const t4_byte* item_);
  bool Set_16i(int index_, const t4_byte* item_);
  bool Set_16r(int index_, const t4_byte* item_);
  bool Set_32i(int index_, const t4_byte* item_);
  bool Set_32r(int index_, const t4_byte* item_);
  bool Set_64i(int index_, const t4_byte* item_);
  bool Set_64r(int index_, const t4_byte* item_);

  void ResizeData(int index_, int count_, bool clear_ =false);

  tGetter _getter;
  tSetter _setter;

  union {
  t4_byte _item[8]; // holds temp result (careful with tqalignment!)
  double _aligner;  // needed for SPARC
  };

  int _currWidth;   // number of bits used for one entry (0..64)
  int _dataWidth;   // number of bytes used for passing a value along
  int _numRows;
  bool _mustFlip;
};

/////////////////////////////////////////////////////////////////////////////

class c4_ColIter
{
  c4_Column& _column;
  t4_i32 _limit;
  t4_i32 _pos;
  int _len;
  const t4_byte* _ptr;

public:
  c4_ColIter (c4_Column& col_, t4_i32 offset_, t4_i32 limit_);
//  ~c4_ColIter ();

  bool Next();
  bool Next(int max_);

  const t4_byte* BufLoad() const;
  t4_byte* BufSave();
  int BufLen() const;
};

/////////////////////////////////////////////////////////////////////////////

#if q4_INLINE
#include "column.inl"
#endif

/////////////////////////////////////////////////////////////////////////////

#endif