Exemple #1
0
/** Move attached rows to somewhere else in same storage
 *
 * There is a lot of trickery going on here.  The whole point of this
 * code is that moving rows between (compatible!) subviews should not
 * use copying when potentially large memo's and subviews are involved.
 * In that case, the best solution is really to move pointers, not data.
 */
void c4_View::RelocateRows(int from_, int count_, c4_View& dest_, int pos_)
{
  if (count_ < 0)
    count_ = GetSize() - from_;
  if (pos_ < 0)
    pos_ = dest_.GetSize();

  d4_assert(0 <= from_ && from_ <= GetSize());
  d4_assert(0 <= count_ && from_ + count_ <= GetSize());
  d4_assert(0 <= pos_ && pos_ <= dest_.GetSize());

  if (count_ > 0) {
      // the destination must not be inside the source rows
    d4_assert(&dest_ != this || from_ > pos_ || pos_ >= from_ + count_);

      // this test is slow, so do it only as a debug check
    d4_assert(IsCompatibleWith(dest_));

      // make space, swap rows, drop originals
    c4_Row empty;
    dest_.InsertAt(pos_, empty, count_);

      // careful if insert moves origin
    if (&dest_ == this && pos_ <= from_)
      from_ += count_;

    for (int i = 0; i < count_; ++i)
      ((c4_HandlerSeq*) _seq)->ExchangeEntries(from_ + i,
				*(c4_HandlerSeq*) dest_._seq, pos_ + i);

    RemoveAt(from_, count_);
  }
}
Exemple #2
0
bool PyViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
  const c4_Property &prop = _template.NthProperty(col_);
  if (_byPos) {
    PWOSequence item(_data[row_]);
    PyRowRef::setFromPython(_tempRow, prop, item[col_]);
    return prop(_tempRow).GetData(buf_);
  }
  PyObject *item = _data[row_];
  if (PyInstance_Check(item)) {
    PyObject *attr = PyObject_GetAttrString(item, (char*)prop.Name());
    PyRowRef::setFromPython(_tempRow, prop, attr);
    return prop(_tempRow).GetData(buf_);
  }
  if (PyDict_Check(item)) {
    PyObject *attr = PyDict_GetItemString(item, (char*)prop.Name());
    PyRowRef::setFromPython(_tempRow, prop, attr);
    return prop(_tempRow).GetData(buf_);
  }
  if (_template.NumProperties() == 1) {
    PyRowRef::setFromPython(_tempRow, prop, _data[row_]);
    return prop(_tempRow).GetData(buf_);
  }
  Fail(PyExc_ValueError, "Object has no usable attributes");
  return false;
  // create a row with just this single property value
  // this detour handles dicts and objects, because makeRow does
  /*  c4_Row one;
  PyView v (prop); // nasty, stack-based temp to get at makeRow
  v.makeRow(one, _data[row_]);
  return prop (one).GetData(buf_); */
}
bool c4_RemapWithViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
  const c4_Property &map = _argView.NthProperty(0);
  d4_assert(map.Type() == 'I');

  row_ = ((const c4_IntProp &)map)(_argView[row_]);

  return _parent.GetItem(row_, col_, buf_);
}
Exemple #4
0
void c4_Differ::AddEntry(t4_i32 off_, t4_i32 len_, const c4_Bytes &data_) {
  int n = _temp.GetSize();
  _temp.SetSize(n + 1);
  c4_RowRef r = _temp[n];

  pKeep(r) = (t4_i32)off_;
  pResize(r) = (t4_i32)len_;
  pBytes(r).SetData(data_);
}
void CResizer::Verify() {
  int i;

  A(_refSize == _unattached.GetSize());
  A(_refSize == _attached.GetSize());

  for (i = 0; i < _refSize; ++i) {
    A(_refData[i] == _prop(_unattached[i]));
    A(_refData[i] == _prop(_attached[i]));
  }
}
bool c4_ConcatViewer::SetItem(int row_, int col_, const c4_Bytes &buf_) {
  c4_View v = _parent;

  if (row_ >= _parent.GetSize()) {
    v = _argView;
    row_ -= _parent.GetSize();
    col_ = v.FindProperty(_parent.NthProperty(col_).GetId());
    d4_assert(col_ >= 0);
  }

  v.SetItem(row_, col_, buf_);
  return true;
}
int CResizer::Del(int pos_, int cnt_) {
  A(pos_ + cnt_ <= _refSize);

  _refSize -= cnt_;
  memmove(_refData + pos_, _refData + pos_ + cnt_, _refSize - pos_);

  _unattached.RemoveAt(pos_, cnt_);
  _attached.RemoveAt(pos_, cnt_);

  Verify();

  return _refSize;
}
bool c4_ConcatViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
  c4_View v = _parent;

  if (row_ >= _parent.GetSize()) {
    v = _argView;
    row_ -= _parent.GetSize();
    col_ = v.FindProperty(_parent.NthProperty(col_).GetId());

    if (col_ < 0)
      return false;
  }

  return v.GetItem(row_, col_, buf_);
}
/// Compare two views lexicographically (rows 0..N-1).
int c4_View::Compare(const c4_View &view_)const {
  if (_seq == view_._seq)
    return 0;

  int na = GetSize();
  int nb = view_.GetSize();
  int i;

  for (i = 0; i < na && i < nb; ++i)
    if (GetAt(i) != view_.GetAt(i))
      return GetAt(i) < view_.GetAt(i) ?  - 1:  + 1;

  return na == nb ? 0 : i < na ?  + 1:  - 1;
}
bool c4_ProductViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
  c4_View v = _parent;

  if (col_ < v.NumProperties()) {
    row_ /= _argView.GetSize();
  } else {
    v = _argView;
    row_ %= _argView.GetSize();
    col_ = v.FindProperty(_template.NthProperty(col_).GetId());

    d4_assert(col_ >= 0);
  }

  return v.GetItem(row_, col_, buf_);
}
Exemple #11
0
bool c4_View::IsCompatibleWith(const c4_View& dest_) const
{
    // can't determine table without handlers (and can't be a table)
  if (NumProperties() == 0 || dest_.NumProperties() == 0)
    return false;

  c4_Sequence* s1 = _seq;
  c4_Sequence* s2 = dest_._seq;
  c4_HandlerSeq* h1 = (c4_HandlerSeq*) s1->HandlerContext(0);
  c4_HandlerSeq* h2 = (c4_HandlerSeq*) s2->HandlerContext(0);

    // both must be real handler views, not derived ones
  if (h1 != s1 || h2 != s2)
    return false;

    // both must not contain any temporary handlers
  if (s1->NumHandlers() != h1->NumFields() ||
      s2->NumHandlers() != h2->NumFields())
    return false;

    // both must be in the same storage
  if (h1->Persist() == 0 || h1->Persist() != h2->Persist())
    return false;

    // both must have the same structure (is this expensive?)
  c4_String d1 = h1->Definition().Description(true);
  c4_String d2 = h1->Definition().Description(true);
  return d1 == d2; // ignores all names
}
Exemple #12
0
c4_View c4_GroupByViewer::GetTemplate()
{
  c4_View v = _keys.Clone();
  v.AddProperty(_result);

  return v;
}
Exemple #13
0
int MkView::asIndex(c4_View &view, Tcl_Obj *obj_, bool mayExceed_) {
  int size = view.GetSize();
  int index;

  if (Tcl_GetIntFromObj(interp, obj_, &index) != TCL_OK) {
    const char *step = Tcl_GetStringFromObj(obj_, 0);
    if (step != 0 && strcmp(step, "end") == 0) {
      index = !mayExceed_ ? size - 1: size;
      Tcl_ResetResult(interp); // clear error
      _error = TCL_OK;
    } else {
      index =  - 1;
    }
  }

  if (mayExceed_) {
    if (index > size)
      Fail("view index is too large");
    else if (index < 0)
      Fail("view index is negative");
  } else if (index < 0 || index >= size)
    Fail("view index is out of range");

  return index;
}
Exemple #14
0
void c4_Differ::ApplyDiff(int id_, c4_Column &col_)const {
  d4_assert(0 <= id_ && id_ < _diffs.GetSize());

  c4_View diff = pDiff(_diffs[id_]);
  t4_i32 offset = 0;

  for (int n = 0; n < diff.GetSize(); ++n) {
    c4_RowRef row(diff[n]);
    offset += pKeep(row);

    c4_Bytes data;
    pBytes(row).GetData(data);

    // the following code is a lot like c4_MemoRef::Modify
    const t4_i32 change = pResize(row);
    if (change < 0)
      col_.Shrink(offset,  - change);
    else if (change > 0)
      col_.Grow(offset, change);

    col_.StoreBytes(offset, data);
    offset += data.Size();
  }

  if (offset > col_.ColSize())
    col_.Shrink(offset, offset - col_.ColSize());
}
Exemple #15
0
bool c4_SliceViewer::SetItem(int row_, int col_, const c4_Bytes& buf_)
{
  row_ = _first + _step * (_step > 0 ? row_ : row_ - GetSize() + 1);

  _parent.SetItem(row_, col_, buf_);
  return true;
}
Exemple #16
0
bool c4_JoinViewer::GetItem(int row_, int col_, c4_Bytes& buf_)
{
  c4_View v = _parent;

  int o = 0;
  int r = _offset.GetAt(row_);

  if (r < 0)
  {
    o = ~r;
    if (o == 0)
      return false; // if this is a null row in an outer join
    r -= o;
  }

  if (col_ >= v.NumProperties())
  {
    v = _argView;
    r = _o;

    col_ = v.FindProperty(_template.NthProperty(col_));
    if (col_ < 0)
      return false; // if second view doesn't have all properties
  }

  return v.GetItem(r, col_, buf_);
}
Exemple #17
0
c4_Storage::c4_Storage(const c4_View &root_) {
  if (root_.Persist() != 0)
  // only restore if view was indeed persistent
    *(c4_View*)this = root_;
  else
  // if this was not possible, start with a fresh empty storage
    Initialize(*d4_new c4_Strategy, true, 0);
}
Exemple #18
0
void c4_Differ::CreateDiff(int id_, c4_Column &col_) {
  _temp.SetSize(0);
#if 0
  t4_i32 offset = 0;
  t4_i32 savedOff = 0;
  t4_i32 savedLen = 0;

  c4_Strategy *strat = col_.Persist() != 0 ? &col_.Strategy(): 0;

  c4_ColIter iter(col_, 0, col_.ColSize());
  while (iter.Next()) {
    const t4_byte *p = iter.BufLoad();
    if (strat != 0 && strat->_mapStart != 0 && p >= strat->_mapStart && p -
      strat->_mapStart < strat->_dataSize) {
      t4_i32 nextOff = p - strat->_mapStart;
      if (savedLen == 0)
        savedOff = nextOff;
      if (nextOff == savedOff + savedLen) {
        savedLen += iter.BufLen();
        continue;
      }

      if (savedLen > 0)
        AddEntry(savedOff, savedLen, c4_Bytes());

      savedOff = nextOff;
      savedLen = iter.BufLen();
    } else {
      AddEntry(savedOff, savedLen, c4_Bytes(p, iter.BufLen()));
      savedLen = 0;
    }

    offset += iter.BufLen();
  }

  c4_View diff = pDiff(_diffs[id_]);
  if (_temp.GetSize() != diff.GetSize() || _temp != diff)
#else 
    c4_Bytes t1;
  const t4_byte *p = col_.FetchBytes(0, col_.ColSize(), t1, false);
  AddEntry(0, 0, c4_Bytes(p, col_.ColSize()));
#endif 
  pDiff(_diffs[id_]) = _temp;

  pOrig(_diffs[id_]) = col_.Position();
}
int c4_SliceViewer::GetSize() {
  int n = _limit >= 0 ? _limit : _parent.GetSize();
  if (n < _first)
    n = _first;

  int k = _step < 0 ?  - _step: _step;
  return (n - _first + k - 1) / k;
}
Exemple #20
0
void c4_Differ::GetRoot(c4_Bytes &buffer_) {
  int last = _diffs.GetSize() - 1;
  if (last >= 0) {
    c4_Bytes temp;
    c4_View diff = pDiff(_diffs[last]);
    if (diff.GetSize() > 0)
      pBytes(diff[0]).GetData(buffer_);
  }
}
c4_JoinViewer::c4_JoinViewer(c4_Sequence &seq_, const c4_View &keys_, const
  c4_View &view_, bool outer_): _parent(&seq_), _argView(view_.SortOn(keys_)) {
  // why not in GetTemplate, since we don't need to know this...
  _template = _parent.Clone();
  for (int l = 0; l < _argView.NumProperties(); ++l)
    _template.AddProperty(_argView.NthProperty(l));

  c4_View sorted = _parent.SortOn(keys_).Project(keys_);
  c4_View temp = _argView.Project(keys_);

  _base.SetSize(0, 5);
  _offset.SetSize(0, 5);

  int j = 0, n = 0;

  for (int i = 0; i < sorted.GetSize(); ++i) {
    int orig = _parent.GetIndexOf(sorted[i]);
    d4_assert(orig >= 0);

    if (i > 0 && sorted[i] == sorted[i - 1]) {
      // if last key was same, repeat the same join
      int last = _offset.GetSize() - n;
      for (int k = 0; k < n; ++k) {
        _base.Add(orig);
        _offset.Add(_offset.GetAt(last + k));
      }
    } else
     { // no, this is a new combination
      bool match = false;

      // advance until the temp view entry is >= this sorted entry
      while (j < temp.GetSize())
      if (sorted[i] <= temp[j]) {
        match = sorted[i] == temp[j];
        break;
      } else
        ++j;

      n = 0;

      if (match) {
        do {
          _base.Add(orig);
          _offset.Add(j);
          ++n;
        } while (++j < temp.GetSize() && temp[j] == temp[j - 1]);
      } else if (outer_) {
        // no match, add an entry anyway if this is an outer join
        _base.Add(orig);
        _offset.Add(~(t4_i32)0); // special null entry
        ++n;
      }
    }
  }
}
bool c4_SliceViewer::InsertRows(int pos_, c4_Cursor value_, int count_) {
  if (_step != 1)
    return false;

  pos_ = _first + _step *(_step > 0 ? pos_ : pos_ - GetSize() + 1);
  if (_limit >= 0)
    _limit += count_;

  _parent.InsertAt(pos_,  *value_, count_);
  return true;
}
bool c4_SliceViewer::RemoveRows(int pos_, int count_) {
  if (_step != 1)
    return false;

  pos_ = _first + _step *(_step > 0 ? pos_ : pos_ - GetSize() + 1);
  if (_limit >= 0)
    _limit -= count_;

  _parent.RemoveAt(pos_, count_);
  return true;
}
bool c4_PairViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
  c4_View v = _parent;

  if (col_ >= v.NumProperties()) {
    v = _argView;
    col_ = v.FindProperty(_template.NthProperty(col_).GetId());
    d4_assert(col_ >= 0);
  }

  return v.GetItem(row_, col_, buf_);
}
/// Insert copies of all rows of the specified view
void c4_View::InsertAt(int index_, const c4_View &view_) {
  int n = view_.GetSize();
  if (n > 0) {
    c4_Row empty;

    InsertAt(index_, empty, n);

    for (int i = 0; i < n; ++i)
      SetAt(index_ + i, view_[i]);
  }
}
Exemple #26
0
bool c4_GroupByViewer::GetItem(int row_, int col_, c4_Bytes& buf_)
{
  if (col_ < _keys.NumProperties())
    return _sorted.GetItem(_map.GetAt(row_), col_, buf_);

  d4_assert(col_ == _keys.NumProperties());
  
  t4_i32 count;
  switch (_result.Type())
  {
    case 'I': count = _map.GetAt(row_ + 1) - _map.GetAt(row_);
          buf_ = c4_Bytes (&count, sizeof count, true);
          break;
    case 'V': _temp = _sorted.Slice(_map.GetAt(row_), _map.GetAt(row_ + 1))
                .ProjectWithout(_keys);
          buf_ = c4_Bytes (&_temp, sizeof _temp, true);
          break;
    default:  d4_assert(0);
  }

  return true;
}
int CResizer::Ins(int pos_, int cnt_) {
  A(pos_ <= _refSize);
  A(_refSize + cnt_ < kMaxData);

  memmove(_refData + pos_ + cnt_, _refData + pos_, _refSize - pos_);
  _refSize += cnt_;

  c4_Row row;
  _unattached.InsertAt(pos_, row, cnt_);
  _attached.InsertAt(pos_, row, cnt_);

  for (int i = pos_; i < pos_ + cnt_; ++i) {
    _refData[i] = ++_seed;
    _prop(_unattached[i]) = _seed;
    _prop(_attached[i]) = _seed;

    if (_seed >= 123)
      _seed = 0;
  }

  Verify();

  return _refSize;
}
Exemple #28
0
bool PyViewer::SetItem(int row_, int col_, const c4_Bytes &buf_) {
  const c4_Property &prop = _template.NthProperty(col_);
  c4_Row one;
  prop(one).SetData(buf_);

  PyRowRef r(one); // careful, stack-based temp
  PyObject *item = r.asPython(prop);

  if (_byPos) {
    PWOSequence item(_data[row_]);
    item[col_] = item;
  } else if (PyDict_Check((PyObject*)_data))
    PyDict_SetItemString(_data, (char*)prop.Name(), item);
  else
    PyObject_SetAttrString(_data, (char*)prop.Name(), item);

  Py_DECREF(item);
  return true;
}
bool c4_JoinPropViewer::GetItem(int row_, int col_, c4_Bytes &buf_) {
  c4_View v = _parent;
  int r = _base.GetAt(row_);

  if (col_ >= _subPos)
  if (col_ >= _subPos + _subWidth) {
    col_ -= _subWidth - 1;
  } else {
    v = _sub(_parent[r]);
    r = _offset.GetAt(row_);
    if (r < 0)
      return false;
    // if this is a null row in an outer join

    col_ = v.FindProperty(_template.NthProperty(col_).GetId());
    if (col_ < 0)
      return false;
    // if subview doesn't have all properties
  }

  return v.GetItem(r, col_, buf_);
}
Exemple #30
0
static void ViewDisplay(const c4_View& v_, int l_ =0)
{
  c4_String types;
  bool hasData = false, hasSubs = false;

    // display header info and collect all data types
  printf("%*s VIEW %5d rows =", l_, "", v_.GetSize());
  for (int n = 0; n < v_.NumProperties(); ++n)
  {
    c4_Property prop = v_.NthProperty(n);
    char t = prop.Type();

    printf(" %s:%c", (const char*) prop.Name(), t);
    
    types += t;
  
    if (t == 'V')
      hasSubs = true;
    else
      hasData = true;
  }
  printf("\n");

  for (int j = 0; j < v_.GetSize(); ++j)
  {
    if (hasData)  // data properties are all shown on the same line
    {
      printf("%*s %4d:", l_, "", j);
      c4_RowRef r = v_[j];
      c4_Bytes data;

      for (int k = 0; k < types.GetLength(); ++k)
      {
        c4_Property p = v_.NthProperty(k);

        switch (types[k])
        {
        case 'I':
          printf(" %ld", (long) ((c4_IntProp&) p) (r));
          break;

#if !q4_TINY
        case 'F':
          printf(" %g", (double) ((c4_FloatProp&) p) (r));
          break;

        case 'D':
          printf(" %.12g", (double) ((c4_DoubleProp&) p) (r));
          break;
#endif

        case 'S':
          printf(" '%s'", (const char*) ((c4_StringProp&) p) (r));
          break;

        case 'M': // backward compatibility
        case 'B':
          (p (r)).GetData(data);
          printf(" (%db)", data.Size());
          break;

        default:
          if (types[k] != 'V')
            printf(" (%c?)", types[k]);
        }
      }

      printf("\n");
    }

    if (hasSubs)  // subviews are then shown, each as a separate block
    {
      for (int k = 0; k < types.GetLength(); ++k)
      {
        if (types[k] == 'V')
        {
          c4_Property prop = v_.NthProperty(k);

          printf("%*s %4d: subview '%s'\n", l_, "", j,
              (const char*) prop.Name());

          c4_ViewProp& vp = (c4_ViewProp&) prop;
          
          ViewDisplay(vp (v_[j]), l_ + 2);
        }
      }
    }
  }
}