Exemplo n.º 1
0
/*
 * Converts a packed array to mixed, leaving the packed array in an
 * empty state.  You need ToMixedCopy in cases where the old array
 * needs to remain un-modified (usually if `copy' is true).
 *
 * The returned array is mixed, and is guaranteed not to be isFull().
 * (Note: only unset can call ToMixed when we aren't about to insert.)
 */
MixedArray* PackedArray::ToMixed(ArrayData* old) {
  auto const oldSize = old->m_size;
  auto const ad      = ToMixedHeader(old, oldSize + 1);
  auto const mask    = ad->m_tableMask;
  auto dstData       = ad->data();
  auto dstHash       = ad->hashTab();
  auto const srcData = packedData(old);

  auto i = uint32_t{0};
  for (; i < oldSize; ++i) {
    dstData->setIntKey(i);
    tvCopy(srcData[i], dstData->data);
    *dstHash = i;
    ++dstData;
    ++dstHash;
  }
  for (; i <= mask; ++i) {
    *dstHash++ = MixedArray::Empty;
  }

  old->m_size = 0;

  assert(ad->checkInvariants());
  assert(!ad->isFull());
  return ad;
}
Exemplo n.º 2
0
MixedArray* StructArray::ToMixed(StructArray* old) {
  auto const oldSize = old->size();
  auto const ad      = ToMixedHeader(oldSize + 1);
  auto const srcData = old->data();
  auto shape         = old->shape();

  memset(ad->hashTab(), static_cast<uint8_t>(MixedArray::Empty),
    sizeof(int32_t) * ad->hashSize());

  for (auto i = 0; i < oldSize; ++i) {
    auto key = const_cast<StringData*>(shape->keyForOffset(i));
    auto& e = ad->addKeyAndGetElem(key);
    tvCopy(srcData[i], e.data);
  }

  old->m_size = 0;
  ad->m_pos = old->m_pos;
  if (debug) {
    // For debug builds, set m_pos to 0 as well to make the
    // asserts in checkInvariants() happy.
    old->m_pos = 0;
  }
  assert(ad->checkInvariants());
  assert(!ad->isFull());
  assert(ad->hasExactlyOneRef());
  return ad;
}
Exemplo n.º 3
0
/*
 * Convert to mixed, reserving space for at least `neededSize' elems.
 * The `neededSize' should include old->size(), but may be equal to
 * it.
 *
 * Unlike the other ToMixed functions, the returned array already has
 * a reference count of 1.
 */
MixedArray* PackedArray::ToMixedCopyReserve(const ArrayData* old,
                                           size_t neededSize) {
  assert(neededSize >= old->m_size);
  auto const ad      = ToMixedHeader(old, neededSize);
  ad->m_count = 1;
  auto const oldSize = old->m_size;
  auto const mask    = ad->m_tableMask;
  auto dstData       = ad->data();
  auto dstHash       = ad->hashTab();
  auto const srcData = packedData(old);

  auto i = uint32_t{0};
  for (; i < oldSize; ++i) {
    dstData->setIntKey(i);
    tvDupFlattenVars(&srcData[i], &dstData->data, old);
    *dstHash = i;
    ++dstData;
    ++dstHash;
  }
  for (; i <= mask; ++i) {
    *dstHash++ = MixedArray::Empty;
  }

  assert(ad->checkInvariants());
  return ad;
}
Exemplo n.º 4
0
MixedArray* StructArray::ToMixedCopy(const StructArray* old) {
  auto const oldSize = old->size();
  auto const ad      = ToMixedHeader(oldSize + 1);
  auto const srcData = old->data();
  auto shape         = old->shape();

  memset(ad->hashTab(), static_cast<uint8_t>(MixedArray::Empty),
    sizeof(int32_t) * ad->hashSize());

  for (auto i = 0; i < oldSize; ++i) {
    auto key = const_cast<StringData*>(shape->keyForOffset(i));
    auto& e = ad->addKeyAndGetElem(key);
    tvDupFlattenVars(&srcData[i], &e.data, old);
  }

  ad->m_pos = old->m_pos;
  assert(ad->checkInvariants());
  assert(!ad->isFull());
  assert(ad->hasExactlyOneRef());
  return ad;
}