1// column.h --
2// $Id: column.h 1230 2007-03-09 15:58:53Z jcw $
3// This is part of Metakit, see http://www.equi4.com/metakit.html
4
5/** @file
6 * Definition of the column classes
7 */
8
9#ifndef __COLUMN_H__
10#define __COLUMN_H__
11
12/////////////////////////////////////////////////////////////////////////////
13// Declarations in this file
14
15class c4_Column; // a column in a table
16class c4_ColIter; // an iterator over column data
17class c4_ColCache; // manages a cache for columns
18
19class c4_Persist; // not defined here
20class c4_Strategy; // not defined here
21
22/////////////////////////////////////////////////////////////////////////////
23
24class c4_Column {
25    c4_PtrArray _segments;
26    t4_i32 _position;
27    t4_i32 _size;
28    c4_Persist *_persist;
29    t4_i32 _gap;
30    int _slack;
31    bool _dirty;
32
33  public:
34    c4_Column(c4_Persist *persist_);
35    //: Constructs a column using the specified persistence manager.
36    ~c4_Column();
37
38    void SetBuffer(t4_i32);
39    //: Allocate a new buffer of the specified size.
40
41    c4_Persist *Persist()const;
42    //: Returns persistence manager for this column, or zero.
43    c4_Strategy &Strategy()const;
44    //: Returns the associated strategy pointer.
45    t4_i32 Position()const;
46    //: Special access for the DUMP program.
47    t4_i32 ColSize()const;
48    //: Returns the number of bytes as stored on disk.
49    bool IsDirty()const;
50    //: Returns true if contents needs to be saved.
51
52    void SetLocation(t4_i32, t4_i32);
53    //: Sets the position and size of this column on file.
54    void PullLocation(const t4_byte * &ptr_);
55    //: Extract position and size of this column.
56
57    int AvailAt(t4_i32 offset_)const;
58    //: Returns number of bytes we can access at once.
59    const t4_byte *LoadNow(t4_i32);
60    //: Makes sure the data is loaded into memory.
61    t4_byte *CopyNow(t4_i32);
62    //: Makes sure a copy of the data is in memory.
63    void Grow(t4_i32, t4_i32);
64    //: Grows the buffer by inserting space.
65    void Shrink(t4_i32, t4_i32);
66    //: Shrinks the buffer by removing space.
67    void SaveNow(c4_Strategy &, t4_i32 pos_);
68    //: Save the buffer to file.
69
70    const t4_byte *FetchBytes(t4_i32 pos_, int len_, c4_Bytes &buffer_, bool
71      forceCopy_);
72    //: Returns pointer to data, use buffer only if non-contiguous.
73    void StoreBytes(t4_i32 pos_, const c4_Bytes &buffer_);
74    //: Stores a copy of the buffer in the column.
75
76    bool RequiresMap()const;
77    void ReleaseAllSegments();
78
79    static t4_i32 PullValue(const t4_byte * &ptr_);
80    static void PushValue(t4_byte * &ptr_, t4_i32 v_);
81
82    void InsertData(t4_i32 index_, t4_i32 count_, bool clear_);
83    void RemoveData(t4_i32 index_, t4_i32 count_);
84    void RemoveGap();
85
86    enum {
87        kSegBits = 12, kSegMax = 1 << kSegBits, kSegMask = kSegMax - 1
88    };
89
90  private:
91    static int fSegIndex(t4_i32 offset_);
92    static t4_i32 fSegOffset(int index_);
93    static int fSegRest(t4_i32 offset_);
94
95    bool UsesMap(const t4_byte*)const;
96    bool IsMapped()const;
97
98    void ReleaseSegment(int);
99    void SetupSegments();
100    void Validate()const;
101    void FinishSlack();
102
103    void MoveGapUp(t4_i32 pos_);
104    void MoveGapDown(t4_i32 pos_);
105    void MoveGapTo(t4_i32 pos_);
106
107    t4_byte *CopyData(t4_i32, t4_i32, int);
108};
109
110/////////////////////////////////////////////////////////////////////////////
111
112class c4_ColOfInts: public c4_Column {
113  public:
114    c4_ColOfInts(c4_Persist *persist_, int width_ = sizeof(t4_i32));
115
116    int RowCount()const;
117    void SetRowCount(int numRows_);
118
119    void FlipBytes();
120
121    int ItemSize(int index_);
122    const void *Get(int index_, int &length_);
123    void Set(int index_, const c4_Bytes &buf_);
124
125    t4_i32 GetInt(int index_);
126    void SetInt(int index_, t4_i32 value_);
127
128    void Insert(int index_, const c4_Bytes &buf_, int count_);
129    void Remove(int index_, int count_);
130
131    static int CalcAccessWidth(int numRows_, t4_i32 colSize_);
132
133    void SetAccessWidth(int bits_);
134    void FixSize(bool fudge_);
135    void ForceFlip();
136
137    static int DoCompare(const c4_Bytes &b1_, const c4_Bytes &b2_);
138
139  private:
140    typedef void(c4_ColOfInts:: *tGetter)(int);
141    typedef bool(c4_ColOfInts:: *tSetter)(int, const t4_byte*);
142
143    void Get_0b(int index_);
144    void Get_1b(int index_);
145    void Get_2b(int index_);
146    void Get_4b(int index_);
147    void Get_8i(int index_);
148    void Get_16i(int index_);
149    void Get_16r(int index_);
150    void Get_32i(int index_);
151    void Get_32r(int index_);
152    void Get_64i(int index_);
153    void Get_64r(int index_);
154
155    bool Set_0b(int index_, const t4_byte *item_);
156    bool Set_1b(int index_, const t4_byte *item_);
157    bool Set_2b(int index_, const t4_byte *item_);
158    bool Set_4b(int index_, const t4_byte *item_);
159    bool Set_8i(int index_, const t4_byte *item_);
160    bool Set_16i(int index_, const t4_byte *item_);
161    bool Set_16r(int index_, const t4_byte *item_);
162    bool Set_32i(int index_, const t4_byte *item_);
163    bool Set_32r(int index_, const t4_byte *item_);
164    bool Set_64i(int index_, const t4_byte *item_);
165    bool Set_64r(int index_, const t4_byte *item_);
166
167    void ResizeData(int index_, int count_, bool clear_ = false);
168
169    tGetter _getter;
170    tSetter _setter;
171
172    union {
173        t4_byte _item[8]; // holds temp result (careful with alignment!)
174        double _aligner; // needed for SPARC
175    };
176
177    int _currWidth; // number of bits used for one entry (0..64)
178    int _dataWidth; // number of bytes used for passing a value along
179    int _numRows;
180    bool _mustFlip;
181};
182
183/////////////////////////////////////////////////////////////////////////////
184
185class c4_ColIter {
186    c4_Column &_column;
187    t4_i32 _limit;
188    t4_i32 _pos;
189    int _len;
190    const t4_byte *_ptr;
191
192  public:
193    c4_ColIter(c4_Column &col_, t4_i32 offset_, t4_i32 limit_);
194    //  ~c4_ColIter ();
195
196    bool Next();
197    bool Next(int max_);
198
199    const t4_byte *BufLoad()const;
200    t4_byte *BufSave();
201    int BufLen()const;
202};
203
204/////////////////////////////////////////////////////////////////////////////
205
206#if q4_INLINE
207#include "column.inl"
208#endif
209
210/////////////////////////////////////////////////////////////////////////////
211
212#endif
213