void c4_FormatS::Set(int index_, const c4_Bytes &buf_) {
  int m = buf_.Size();
  if (--m >= 0) {
    d4_assert(buf_.Contents()[m] == 0);
    if (m == 0) {
      SetOne(index_, c4_Bytes()); // don't store data for empty strings
      return ;
    }
  }

  SetOne(index_, buf_);
}
示例#2
0
    inline const MonomLex& MonomLex::operator=(const MonomLex& anotherMonom)
    {
        if (this == &anotherMonom)
        {
            return *this;
        }

        if (!anotherMonom.ListHead)
        {
            SetOne();
        }
        else
        {
            TotalDegree = anotherMonom.TotalDegree;

            VarsListNode *iteratorAnother = anotherMonom.ListHead,
                         **iterator = &ListHead;
            while (*iterator && iteratorAnother)
            {
                (*iterator)->Value = iteratorAnother->Value;
                iterator = &((*iterator)->Next);
                iteratorAnother = iteratorAnother->Next;
            } 

            if (*iterator)
            {
                VarsListNode *nodeToDelete = (*iterator)->Next;
                *iterator = 0;
                while (nodeToDelete)
                {
                    iteratorAnother = nodeToDelete;
                    nodeToDelete = nodeToDelete->Next;
                    delete iteratorAnother;
                }
            }
            else while (iteratorAnother)
            {
                *iterator = new VarsListNode();
                (*iterator)->Value = iteratorAnother->Value;

                iterator = &((*iterator)->Next);
                iteratorAnother = iteratorAnother->Next;
            }
        }
        return *this;
    }
示例#3
0
    inline void MonomLex::SetQuotientOf(const MonomLex& monomA, const MonomLex& monomB)
    {
        SetOne();
        VarsListNode **iterator = &ListHead,
                     *iteratorA = monomA.ListHead,
                     *iteratorB = monomB.ListHead;

        while (iteratorA && iteratorB)
        {
            if (iteratorA->Value == iteratorB->Value)
            {
                iteratorA = iteratorA->Next;
                iteratorB = iteratorB->Next;
            }
            else
            {
                ++TotalDegree;
                *iterator = new VarsListNode();
                (*iterator)->Value = iteratorA->Value;
                iterator = &((*iterator)->Next);
                if (iteratorA->Value < iteratorB->Value)
                {
                    iteratorA = iteratorA->Next;
                }
            }
        }
        
        while (iteratorA)
        {
            ++TotalDegree;
            *iterator = new VarsListNode();
            (*iterator)->Value = iteratorA->Value;
            iterator = &((*iterator)->Next);
            iteratorA = iteratorA->Next;
        }
    }
示例#4
0
 inline MonomLex::~MonomLex()
 {
     SetOne();
 }
void c4_FormatB::Commit(c4_SaveContext &ar_) {
  int rows = _memos.GetSize();
  d4_assert(rows > 0);

  bool full = _recalc || ar_.Serializing();

  if (!full)
  for (int i = 0; i < rows; ++i) {
    c4_Column *col = (c4_Column*)_memos.GetAt(i);
    if (col != 0) {
      full = true;
      break;
    }
  }
  d4_assert(_recalc || _sizeCol.RowCount() == rows);

  if (full) {
    _memoCol.SetBuffer(0);
    _sizeCol.SetBuffer(0);
    _sizeCol.SetAccessWidth(0);
    _sizeCol.SetRowCount(rows);

    int skip = 0;

    c4_Column *saved = ar_.SetWalkBuffer(&_memoCol);

    for (int r = 0; r < rows; ++r) {
      ++skip;

      t4_i32 start;
      c4_Column *col;
      int len = ItemLenOffCol(r, start, col);

      bool oldMemo = col !=  &_data;
      bool newMemo = ShouldBeMemo(len);

      if (!oldMemo && newMemo) {
        col = GetNthMemoCol(r, true);
        d4_assert(col !=  &_data);
        //? start = 0;
      }

      c4_Bytes temp;

      if (newMemo) {
        // it now is a memo, inlined data will be empty
        ar_.StoreValue(skip - 1);
        skip = 0;
        ar_.CommitColumn(*col);
      } else if (!oldMemo) {
        // it was no memo, done if it hasn't become one
        _sizeCol.SetInt(r, len);
        continue;
      } else {
        // it was a memo, but it no longer is
        d4_assert(start == 0);
        if (len > 0) {
          _sizeCol.SetInt(r, len);
          col->FetchBytes(start, len, temp, true);
          delete (c4_Column*)_memos.GetAt(r); // 28-11-2001: fix mem leak
          _memos.SetAt(r, 0); // 02-11-2001: fix for use after commit
        }
      }

      SetOne(r, temp, true); // bypass current memo pointer
    }

    ar_.SetWalkBuffer(saved);
  }

  ar_.CommitColumn(_data);

  if (_data.ColSize() > 0) {
    _sizeCol.FixSize(true);
    ar_.CommitColumn(_sizeCol);
    //_sizeCol.FixSize(false);
  }

  ar_.CommitColumn(_memoCol);

  // need a way to find out when the data has been committed (on 2nd pass)
  // both _sizeCol and _memoCol will be clean again when it has
  // but be careful because dirty flag is only useful if size is nonzero
  if (_recalc && !ar_.Serializing())
    _recalc = _sizeCol.ColSize() > 0 && _sizeCol.IsDirty() || _memoCol.ColSize()
      > 0 && _memoCol.IsDirty();
}
void c4_FormatB::Set(int index_, const c4_Bytes &buf_) {
  SetOne(index_, buf_);
}
void c4_FormatB::OldDefine(char type_, c4_Persist &pers_) {
  int rows = Owner().NumRows();

  c4_ColOfInts sizes(_data.Persist());

  if (type_ == 'M') {
    InitOffsets(sizes);

    c4_ColOfInts szVec(_data.Persist());
    pers_.FetchOldLocation(szVec);
    szVec.SetRowCount(rows);

    c4_ColOfInts posVec(_data.Persist());
    pers_.FetchOldLocation(posVec);
    posVec.SetRowCount(rows);

    for (int r = 0; r < rows; ++r) {
      t4_i32 sz = szVec.GetInt(r);
      if (sz > 0) {
        c4_Column *mc = d4_new c4_Column(_data.Persist());
        d4_assert(mc != 0);
        _memos.SetAt(r, mc);

        mc->SetLocation(posVec.GetInt(r), sz);
      }
    }
  } else {
    pers_.FetchOldLocation(_data);

    if (type_ == 'B') {
      pers_.FetchOldLocation(sizes);

#if !q4_OLD_IS_ALWAYS_V2

      // WARNING - HUGE HACK AHEAD - THIS IS NOT 100% FULLPROOF!
      //
      // The above is correct for MK versions 2.0 and up, but *NOT*
      // for MK 1.8.6 datafiles, which store sizes first (OUCH!!!).
      // This means that there is not a 100% safe way to auto-convert
      // both 1.8.6 and 2.0 files - since there is no way to detect
      // unambiguously which version a datafile is.  All we can do,
      // is to carefully check both vectors, and *hope* that only one
      // of them is valid as sizes vector.  This problem applies to
      // the 'B' (bytes) property type only, and only pre 2.0 files.
      //
      // To build a version which *always* converts assuming 1.8.6,
      // add flag "-Dq4_OLD_IS_PRE_V2" to the compiler command line.
      // Conversely, "-Dq4_OLD_IS_ALWAYS_V2" forces 2.0 conversion.

      if (rows > 0) {
        t4_i32 s1 = sizes.ColSize();
        t4_i32 s2 = _data.ColSize();

#if !q4_OLD_IS_PRE_V2
        // if the size vector is clearly impossible, swap vectors
        bool fix = c4_ColOfInts::CalcAccessWidth(rows, s1) < 0;

        // if the other vector might be valid as well, check further
        if (!fix && c4_ColOfInts::CalcAccessWidth(rows, s2) >= 0) {
          sizes.SetRowCount(rows);
          t4_i32 total = 0;
          for (int i = 0; i < rows; ++i) {
            t4_i32 w = sizes.GetInt(i);
            if (w < 0 || total > s2) {
              total =  - 1;
              break;
            }
            total += w;
          }

          // if the sizes don't add up, swap vectors
          fix = total != s2;
        }

        if (fix)
#endif 
         {
          t4_i32 p1 = sizes.Position();
          t4_i32 p2 = _data.Position();
          _data.SetLocation(p1, s1);
          sizes.SetLocation(p2, s2);
        }
      }
#endif 
      InitOffsets(sizes);
    } else {
      d4_assert(type_ == 'S');

      sizes.SetRowCount(rows);

      t4_i32 pos = 0;
      t4_i32 lastEnd = 0;
      int k = 0;

      c4_ColIter iter(_data, 0, _data.ColSize());
      while (iter.Next()) {
        const t4_byte *p = iter.BufLoad();
        for (int j = 0; j < iter.BufLen(); ++j)
        if (!p[j]) {
          sizes.SetInt(k++, pos + j + 1-lastEnd);
          lastEnd = pos + j + 1;
        }

        pos += iter.BufLen();
      }

      d4_assert(pos == _data.ColSize());

      if (lastEnd < pos) {
        // last entry had no zero byte
        _data.InsertData(pos++, 1, true);
        sizes.SetInt(k, pos - lastEnd);
      }

      InitOffsets(sizes);

      // get rid of entries with just a null byte
      for (int r = 0; r < rows; ++r)
        if (c4_FormatB::ItemSize(r) == 1)
          SetOne(r, c4_Bytes());
    }
  }
}