// 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); } }
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; } } }