Ejemplo n.º 1
0
APCHandle* APCString::MakeShared(
    DataType type, StringData* data, size_t& size) {
  auto const len = data->size();
  auto const cap = roundUpPackedCap(static_cast<uint32_t>(len));
  auto const apcStr = new (cap + 1) APCString(type);
  auto const capCode = packedCapToCode(cap);
  size = cap + 1 + sizeof(APCString);

  apcStr->m_data.m_data        = reinterpret_cast<char*>(apcStr + 1);
  apcStr->m_data.m_capAndCount = capCode; // count=0
  apcStr->m_data.m_len         = len; // don't store hash

  apcStr->m_data.m_data[len] = 0;
  auto const mcret = memcpy(apcStr->m_data.m_data, data->data(), len);
  auto const ret   = reinterpret_cast<APCString*>(mcret) - 1;
  // Recalculating ret from mcret avoids a spill.

  ret->m_data.preCompute();

  assert(ret == apcStr);
  assert(apcStr->m_data.m_hash != 0);
  assert(ret->m_data.m_data[len] == 0);
  assert(ret->m_data.m_count == 0);
  assert(ret->m_data.isFlat());
  assert(ret->m_data.checkSane());
  return ret->getHandle();
}
Ejemplo n.º 2
0
APCHandle::Pair
APCString::MakeSharedString(DataType type, StringData* data) {
  auto const len = data->size();
  auto const cap = roundUpPackedCap(static_cast<uint32_t>(len));
  auto const capCode = packedCapToCode(cap);
  auto apcStr = new (cap + 1) APCString(type);
  auto size = cap + 1 + sizeof(APCString);

  apcStr->m_str.m_data        = reinterpret_cast<char*>(apcStr + 1);
  apcStr->m_str.m_capAndCount = HeaderKind::String << 24 | capCode; // count=0
  apcStr->m_str.m_len         = len; // don't store hash

  apcStr->m_str.m_data[len] = 0;
  assert(apcStr == reinterpret_cast<APCString*>(apcStr->m_str.m_data) - 1);
  auto const mcret = memcpy(apcStr->m_str.m_data, data->data(), len);
  apcStr = reinterpret_cast<APCString*>(mcret) - 1;
  // Recalculating apcStr from mcret avoids a spill.

  apcStr->m_str.preCompute();

  assert(apcStr->m_str.m_hash != 0);
  assert(apcStr->m_str.m_data[len] == 0);
  assert(apcStr->m_str.m_count == 0);
  assert(apcStr->m_str.isFlat());
  assert(apcStr->m_str.checkSane());
  return {apcStr->getHandle(), size};
}
Ejemplo n.º 3
0
// create either a static or an uncounted string.
// Diffrence between static and uncounted is in the lifetime
// of the string. Static are alive for the lifetime of the process.
// Uncounted are not ref counted but will be deleted at some point.
StringData* StringData::MakeShared(StringSlice sl, bool trueStatic) {
  if (UNLIKELY(sl.len > StringData::MaxSize)) {
    throw_string_too_large(sl.len);
  }

  auto const encodable = roundUpPackedCap(sl.len);
  auto const need = encodable + kCapOverhead;
  auto const sd = static_cast<StringData*>(
    trueStatic ? low_malloc(need) : malloc(need)
  );
  auto const data = reinterpret_cast<char*>(sd + 1);
  auto const capCode = packedCapToCode(encodable);

  sd->m_data        = data;
  sd->m_capAndCount = HeaderKind::String << 24 | capCode; // count=0
  sd->m_lenAndHash  = sl.len; // hash=0

  data[sl.len] = 0;
  auto const mcret = memcpy(data, sl.ptr, sl.len);
  auto const ret   = reinterpret_cast<StringData*>(mcret) - 1;
  // Recalculating ret from mcret avoids a spill.

  assert(ret->m_hash == 0);
  assert(ret->m_count == 0);
  if (trueStatic) {
    ret->setStatic();
  } else {
    ret->setUncounted();
  }

  assert(ret == sd);
  assert(ret->isFlat());
  assert(trueStatic ? ret->isStatic() : ret->isUncounted());
  assert(ret->checkSane());
  return ret;
}