void c4_Column::SetupSegments() { d4_assert(_segments.GetSize() == 0); d4_assert(_gap == 0); d4_assert(_slack == 0); // The last entry in the _segments array is either a partial block // or a null pointer, so calling "fSegIndex(_size)" is always allowed. int n = fSegIndex(_size) + 1; _segments.SetSize(n); // treat last block differently if it is a partial entry int last = n; if (fSegRest(_size)) --last; // this block is partial, size is 1 .. kSegMax-1 else --n; // the last block is left as a null pointer int id = - 1; if (_position < 0) { // special aside id, figure out the real position d4_assert(_persist != 0); id = ~_position; _position = _persist->LookupAside(id); d4_assert(_position >= 0); } if (IsMapped()) { // setup for mapped files is quick, just fill in the pointers d4_assert(_position > 1); d4_assert(_position + (n - 1) *kSegMax <= Strategy()._dataSize); const t4_byte *map = Strategy()._mapStart + _position; for (int i = 0; i < n; ++i) { _segments.SetAt(i, (t4_byte*)map); // loses const map += kSegMax; } } else { int chunk = kSegMax; t4_i32 pos = _position; // allocate buffers, load them if necessary for (int i = 0; i < n; ++i) { if (i == last) chunk = fSegRest(_size); t4_byte *p = d4_new t4_byte[chunk]; _segments.SetAt(i, p); if (_position > 0) { d4_dbgdef(int n = )Strategy().DataRead(pos, p, chunk); d4_assert(n == chunk); pos += chunk; } } }
// debugging version to verify that the internal data is consistent void c4_Column::Validate()const { d4_assert(0 <= _slack && _slack < kSegMax); if (_segments.GetSize() == 0) { return; } // ok, not initialized d4_assert(_gap <= _size); int n = fSegIndex(_size + _slack); d4_assert(n == _segments.GetSize() - 1); t4_byte *p = (t4_byte *)_segments.GetAt(n); if (fSegRest(_size + _slack) == 0) { d4_assert(p == 0); } else { d4_assert(p != 0); } while (--n >= 0) { t4_byte *p = (t4_byte *)_segments.GetAt(n); d4_assert(p != 0); } }
//@func How many contiguous bytes are there at a specified position. int c4_Column::AvailAt(t4_i32 offset_)const { d4_assert(offset_ <= _size); d4_assert(_gap <= _size); t4_i32 limit = _gap; if (offset_ >= _gap) { offset_ += _slack; limit = _size + _slack; } int count = kSegMax - fSegRest(offset_); if (offset_ + count > limit) count = (int)(limit - offset_); // either some real data or it must be at the very end of all data d4_assert(0 < count && count <= kSegMax || count == 0 && offset_ == _size + _slack); return count; }