DateTimeNumericFieldElement::DateTimeNumericFieldElement(
    Document& document,
    FieldOwner& fieldOwner,
    const Range& range,
    const Range& hardLimits,
    const String& placeholder,
    const DateTimeNumericFieldElement::Step& step)
    : DateTimeFieldElement(document, fieldOwner),
      m_placeholder(placeholder),
      m_range(range),
      m_hardLimits(hardLimits),
      m_step(step),
      m_value(0),
      m_hasValue(false) {
  DCHECK_NE(m_step.step, 0);
  DCHECK_LE(m_range.minimum, m_range.maximum);
  DCHECK_LE(m_hardLimits.minimum, m_hardLimits.maximum);

  // We show a direction-neutral string such as "--" as a placeholder. It
  // should follow the direction of numeric values.
  if (localeForOwner().isRTL()) {
    CharDirection dir = direction(formatValue(this->maximum())[0]);
    if (dir == LeftToRight || dir == EuropeanNumber || dir == ArabicNumber) {
      setInlineStyleProperty(CSSPropertyUnicodeBidi, CSSValueBidiOverride);
      setInlineStyleProperty(CSSPropertyDirection, CSSValueLtr);
    }
  }
}
示例#2
0
IOBuf IOBuf::cloneCoalescedAsValue() const {
  if (!isChained()) {
    return cloneOneAsValue();
  }
  // Coalesce into newBuf
  const uint64_t newLength = computeChainDataLength();
  const uint64_t newHeadroom = headroom();
  const uint64_t newTailroom = prev()->tailroom();
  const uint64_t newCapacity = newLength + newHeadroom + newTailroom;
  IOBuf newBuf{CREATE, newCapacity};
  newBuf.advance(newHeadroom);

  auto current = this;
  do {
    if (current->length() > 0) {
      DCHECK_NOTNULL(current->data());
      DCHECK_LE(current->length(), newBuf.tailroom());
      memcpy(newBuf.writableTail(), current->data(), current->length());
      newBuf.append(current->length());
    }
    current = current->next();
  } while (current != this);

  DCHECK_EQ(newLength, newBuf.length());
  DCHECK_EQ(newHeadroom, newBuf.headroom());
  DCHECK_LE(newTailroom, newBuf.tailroom());

  return newBuf;
}
示例#3
0
    int FieldTrial::AppendGroup(const std::string& name,
        Probability group_probability)
    {
        DCHECK_LE(group_probability, divisor_);
        DCHECK_GE(group_probability, 0);

        if(enable_benchmarking_ || !enable_field_trial_)
        {
            group_probability = 0;
        }

        accumulated_group_probability_ += group_probability;

        DCHECK_LE(accumulated_group_probability_, divisor_);
        if(group_==kNotFinalized && accumulated_group_probability_>random_)
        {
            // This is the group that crossed the random line, so we do the assignment.
            group_ = next_group_number_;
            if(name.empty())
            {
                StringAppendF(&group_name_, "%d", group_);
            }
            else
            {
                group_name_ = name;
            }
            FieldTrialList::NotifyFieldTrialGroupSelection(name_, group_name_);
        }
        return next_group_number_++;
    }
DeleteFromTextNodeCommand::DeleteFromTextNodeCommand(Text* node,
                                                     unsigned offset,
                                                     unsigned count)
    : SimpleEditCommand(node->document()),
      m_node(node),
      m_offset(offset),
      m_count(count) {
  DCHECK(m_node);
  DCHECK_LE(m_offset, m_node->length());
  DCHECK_LE(m_offset + m_count, m_node->length());
}
示例#5
0
    CHARRANGE Range::ToCHARRANGE() const
    {
        CHARRANGE r = { -1, -1 };
        if(!IsValid())
        {
            return r;
        }

        const LONG kLONGMax = std::numeric_limits<LONG>::max();
        DCHECK_LE(static_cast<LONG>(start()), kLONGMax);
        DCHECK_LE(static_cast<LONG>(end()), kLONGMax);
        r.cpMin = start();
        r.cpMax = end();
        return r;
    }
示例#6
0
    bool SplitStringIntoKeyValuePairs(
        const std::string& line,
        char key_value_delimiter,
        char key_value_pair_delimiter,
        std::vector<std::pair<std::string, std::string> >* kv_pairs)
    {
        kv_pairs->clear();

        std::vector<std::string> pairs;
        SplitString(line, key_value_pair_delimiter, &pairs);

        bool success = true;
        for(size_t i=0; i<pairs.size(); ++i)
        {
            // 空键值对. SplitStringIntoKeyValues不识别空行, 继续下一个键值对.
            if(pairs[i].empty())
            {
                continue;
            }

            std::string key;
            std::vector<std::string> value;
            if(!SplitStringIntoKeyValues(pairs[i],
                key_value_delimiter, &key, &value))
            {
                // 这里不返回, 允许键不关联值; 仅标记切分失败.
                success = false;
            }
            DCHECK_LE(value.size(), 1U);
            kv_pairs->push_back(make_pair(key, value.empty()?"":value[0]));
        }
        return success;
    }
示例#7
0
文件: AsyncIO.cpp 项目: JasonCC/folly
Range<AsyncIO::Op**> AsyncIO::doWait(size_t minRequests, size_t maxRequests) {
  io_event events[pending_];
  int count;
  do {
    // Wait forever
    count = io_getevents(ctx_, minRequests, maxRequests, events, nullptr);
  } while (count == -EINTR);
  checkKernelError(count, "AsyncIO: io_getevents failed");
  DCHECK_GE(count, minRequests);  // the man page says so
  DCHECK_LE(count, pending_);

  completed_.clear();
  if (count == 0) {
    return folly::Range<Op**>();
  }

  for (size_t i = 0; i < count; ++i) {
    DCHECK(events[i].obj);
    Op* op = boost::intrusive::get_parent_from_member(
        events[i].obj, &AsyncIOOp::iocb_);
    --pending_;
    op->complete(events[i].res);
    completed_.push_back(op);
  }

  return folly::Range<Op**>(&completed_.front(), count);
}
示例#8
0
void MarkupFormatter::appendCharactersReplacingEntities(StringBuilder& result, const String& source, unsigned offset, unsigned length, EntityMask entityMask)
{
    DEFINE_STATIC_LOCAL(const CString, ampReference, ("&amp;"));
    DEFINE_STATIC_LOCAL(const CString, ltReference, ("&lt;"));
    DEFINE_STATIC_LOCAL(const CString, gtReference, ("&gt;"));
    DEFINE_STATIC_LOCAL(const CString, quotReference, ("&quot;"));
    DEFINE_STATIC_LOCAL(const CString, nbspReference, ("&nbsp;"));
    DEFINE_STATIC_LOCAL(const CString, tabReference, ("&#9;"));
    DEFINE_STATIC_LOCAL(const CString, lineFeedReference, ("&#10;"));
    DEFINE_STATIC_LOCAL(const CString, carriageReturnReference, ("&#13;"));

    static const EntityDescription entityMaps[] = {
        { '&', ampReference, EntityAmp },
        { '<', ltReference, EntityLt },
        { '>', gtReference, EntityGt },
        { '"', quotReference, EntityQuot },
        { noBreakSpaceCharacter, nbspReference, EntityNbsp },
        { '\t', tabReference, EntityTab },
        { '\n', lineFeedReference, EntityLineFeed },
        { '\r', carriageReturnReference, EntityCarriageReturn },
    };

    if (!(offset + length))
        return;

    DCHECK_LE(offset + length, source.length());
    if (source.is8Bit())
        appendCharactersReplacingEntitiesInternal(result, source.characters8() + offset, length, entityMaps, WTF_ARRAY_LENGTH(entityMaps), entityMask);
    else
        appendCharactersReplacingEntitiesInternal(result, source.characters16() + offset, length, entityMaps, WTF_ARRAY_LENGTH(entityMaps), entityMask);
}
示例#9
0
ScriptProcessorHandler::ScriptProcessorHandler(AudioNode& node,
                                               float sampleRate,
                                               size_t bufferSize,
                                               unsigned numberOfInputChannels,
                                               unsigned numberOfOutputChannels)
    : AudioHandler(NodeTypeJavaScript, node, sampleRate),
      m_doubleBufferIndex(0),
      m_bufferSize(bufferSize),
      m_bufferReadWriteIndex(0),
      m_numberOfInputChannels(numberOfInputChannels),
      m_numberOfOutputChannels(numberOfOutputChannels),
      m_internalInputBus(AudioBus::create(numberOfInputChannels,
                                          AudioUtilities::kRenderQuantumFrames,
                                          false)) {
  // Regardless of the allowed buffer sizes, we still need to process at the
  // granularity of the AudioNode.
  if (m_bufferSize < AudioUtilities::kRenderQuantumFrames)
    m_bufferSize = AudioUtilities::kRenderQuantumFrames;

  DCHECK_LE(numberOfInputChannels, BaseAudioContext::maxNumberOfChannels());

  addInput();
  addOutput(numberOfOutputChannels);

  m_channelCount = numberOfInputChannels;
  setInternalChannelCountMode(Explicit);

  initialize();
}
示例#10
0
void StereoPannerHandler::process(size_t framesToProcess) {
  AudioBus* outputBus = output(0).bus();

  if (!isInitialized() || !input(0).isConnected() || !m_stereoPanner.get()) {
    outputBus->zero();
    return;
  }

  AudioBus* inputBus = input(0).bus();
  if (!inputBus) {
    outputBus->zero();
    return;
  }

  if (m_pan->hasSampleAccurateValues()) {
    // Apply sample-accurate panning specified by AudioParam automation.
    DCHECK_LE(framesToProcess, m_sampleAccuratePanValues.size());
    if (framesToProcess <= m_sampleAccuratePanValues.size()) {
      float* panValues = m_sampleAccuratePanValues.data();
      m_pan->calculateSampleAccurateValues(panValues, framesToProcess);
      m_stereoPanner->panWithSampleAccurateValues(inputBus, outputBus,
                                                  panValues, framesToProcess);
    }
  } else {
    m_stereoPanner->panToTargetValue(inputBus, outputBus, m_pan->value(),
                                     framesToProcess);
  }
}
示例#11
0
 /**
  * @brief Make a TypedValue of this Type.
  *
  * @param value_ptr An untyped pointer to the data which will be represented
  *        as a TypedValue.
  * @param value_size The size of the data at value_ptr in bytes. This may be
  *        omitted for numeric types, but must be explicitly specified for any
  *        other type. For Char and VarChar, this should include the
  *        terminating null character, if any.
  * @return A TypedValue representing the data at value_ptr.
  **/
 inline TypedValue makeValue(const void* value_ptr,
                             const std::size_t value_size = 0) const {
   DCHECK(value_ptr != nullptr);
   switch (type_id_) {
     case kInt:
       return TypedValue(*static_cast<const int*>(value_ptr));
     case kLong:
       return TypedValue(*static_cast<const std::int64_t*>(value_ptr));
     case kFloat:
       return TypedValue(*static_cast<const float*>(value_ptr));
     case kDouble:
       return TypedValue(*static_cast<const double*>(value_ptr));
     case kDatetime:
       return TypedValue(*static_cast<const DatetimeLit*>(value_ptr));
     case kDatetimeInterval:
       return TypedValue(*static_cast<const DatetimeIntervalLit*>(value_ptr));
     case kYearMonthInterval:
       return TypedValue(*static_cast<const YearMonthIntervalLit*>(value_ptr));
     case kNullType: {
       LOG(FATAL) << "Calling makeValue() to make a non-null value for "
                  << "NullType, which is impossible.";
     }
     default:
       DCHECK_NE(value_size, 0u);
       DCHECK_LE(value_size, maximum_byte_length_);
       return TypedValue(type_id_, value_ptr, value_size);
   }
 }
示例#12
0
 void PopHeader() {
     DCHECK(!empty());
     const Header* h = _header_queue.top();
     const size_t entry_size = HeaderSize(*h);
     DCHECK_LE(entry_size, size());
     const uint64_t id = _add_times - _header_queue.size();
     RemoveHeaderFromIndexes(*h, id);
     _size -= entry_size;
     _header_queue.pop();
 }
示例#13
0
 int GetIndexOfName(const std::string& name) {
     DCHECK(_need_indexes);
     const uint64_t* v = _name_index.seek(name);
     if (!v) {
         return 0;
     }
     DCHECK_LE(_add_times - *v, _header_queue.size());
     // The latest added entry has the smallest index
     return _start_index + (_add_times - *v) - 1;
 }
示例#14
0
 int GetIndexOfHeader(const Header& h) {
     DCHECK(_need_indexes);
     const uint64_t* v = _header_index.seek(h);
     if (!v) {
         return 0;
     }
     DCHECK_LE(_add_times - *v, _header_queue.size());
     // The latest added entry has the smallest index
     return _start_index + (_add_times - *v) - 1;
 }
示例#15
0
    int RandInt(int min, int max)
    {
        DCHECK(min <= max);

        uint64 range = static_cast<uint64>(max) - min + 1;
        int result = min + static_cast<int>(RandGenerator(range));
        DCHECK_GE(result, min);
        DCHECK_LE(result, max);
        return result;
    }
InsertIntoTextNodeCommand::InsertIntoTextNodeCommand(Text* node,
                                                     unsigned offset,
                                                     const String& text)
    : SimpleEditCommand(node->document()),
      m_node(node),
      m_offset(offset),
      m_text(text) {
  DCHECK(m_node);
  DCHECK_LE(m_offset, m_node->length());
  DCHECK(!m_text.isEmpty());
}
void TextIteratorTextState::emitText(Node* textNode, LayoutText* layoutObject, int textStartOffset, int textEndOffset)
{
    DCHECK(textNode);
    m_text = m_emitsOriginalText ? layoutObject->originalText() : layoutObject->text();
    DCHECK(!m_text.isEmpty());
    DCHECK_LE(0, textStartOffset);
    DCHECK_LT(textStartOffset, static_cast<int>(m_text.length()));
    DCHECK_LE(0, textEndOffset);
    DCHECK_LE(textEndOffset, static_cast<int>(m_text.length()));
    DCHECK_LE(textStartOffset, textEndOffset);

    m_positionNode = textNode;
    m_positionOffsetBaseNode = nullptr;
    m_positionStartOffset = textStartOffset;
    m_positionEndOffset = textEndOffset;
    m_singleCharacterBuffer = 0;
    m_textLength = textEndOffset - textStartOffset;
    m_lastCharacter = m_text[textEndOffset - 1];

    m_hasEmitted = true;
}
示例#18
0
文件: status.cpp 项目: TRI0N/wwiv
const char* WStatus::GetLastDate(int days_ago) const {
  DCHECK_GE(days_ago, 0);
  DCHECK_LE(days_ago, 2);
  switch (days_ago) {
  case 0:
    return m_pStatusRecord->date1;
  case 1:
    return m_pStatusRecord->date2;
  case 2:
    return m_pStatusRecord->date3;
  default:
    return m_pStatusRecord->date1;
  }
}
示例#19
0
inline AudioNodeOutput::AudioNodeOutput(AudioHandler* handler,
                                        unsigned numberOfChannels)
    : m_handler(*handler),
      m_numberOfChannels(numberOfChannels),
      m_desiredNumberOfChannels(numberOfChannels),
      m_isInPlace(false),
      m_isEnabled(true),
      m_didCallDispose(false),
      m_renderingFanOutCount(0),
      m_renderingParamFanOutCount(0) {
  DCHECK_LE(numberOfChannels, BaseAudioContext::maxNumberOfChannels());

  m_internalBus =
      AudioBus::create(numberOfChannels, AudioUtilities::kRenderQuantumFrames);
}
示例#20
0
void AudioNodeOutput::setNumberOfChannels(unsigned numberOfChannels) {
  DCHECK_LE(numberOfChannels, BaseAudioContext::maxNumberOfChannels());
  ASSERT(deferredTaskHandler().isGraphOwner());

  m_desiredNumberOfChannels = numberOfChannels;

  if (deferredTaskHandler().isAudioThread()) {
    // If we're in the audio thread then we can take care of it right away (we
    // should be at the very start or end of a rendering quantum).
    updateNumberOfChannels();
  } else {
    DCHECK(!m_didCallDispose);
    // Let the context take care of it in the audio thread in the pre and post
    // render tasks.
    deferredTaskHandler().markAudioNodeOutputDirty(this);
  }
}
示例#21
0
char* Pickle::BeginWrite(size_t length)
{
    // uint32对齐位置开始写.
    size_t offset = AlignInt(header_->payload_size, sizeof(uint32));

    size_t new_size = offset + length;
    size_t needed_size = header_size_ + new_size;
    if(needed_size>capacity_ && !Resize(std::max(capacity_*2, needed_size)))
    {
        return NULL;
    }

#ifdef ARCH_CPU_64_BITS
    DCHECK_LE(length, std::numeric_limits<uint32>::max());
#endif

    header_->payload_size = static_cast<uint32>(new_size);
    return payload() + offset;
}
示例#22
0
void TruncateUTF8ToByteSize(const std::string& input,
                            const size_t byte_size,
                            std::string* output)
{
    DCHECK(output);
    if(byte_size > input.length())
    {
        *output = input;
        return;
    }
    DCHECK_LE(byte_size, static_cast<uint32>(kint32max));
    // 注意: 由于CBU8_NEXT使用的是int32.
    int32 truncation_length = static_cast<int32>(byte_size);
    int32 char_index = truncation_length - 1;
    const char* data = input.data();

    // 使用CBU8, 从阶段点由后向前移动查找合法的UTF8字符. 一旦找到
    // 一个UTF8字符, 截断到该字符作为输出.
    while(char_index >= 0)
    {
        int32 prev = char_index;
        uint32 code_point = 0;
        CBU8_NEXT(data, char_index, truncation_length, code_point);
        if(!base::IsValidCharacter(code_point) ||
            !base::IsValidCodepoint(code_point))
        {
            char_index = prev - 1;
        }
        else
        {
            break;
        }
    }

    if(char_index >= 0)
    {
        *output = input.substr(0, char_index);
    }
    else
    {
        output->clear();
    }
}
示例#23
0
KeyframeEffectModelBase::KeyframeVector
KeyframeEffectModelBase::normalizedKeyframes(const KeyframeVector& keyframes) {
  double lastOffset = 0;
  KeyframeVector result;
  result.reserveCapacity(keyframes.size());

  for (const auto& keyframe : keyframes) {
    double offset = keyframe->offset();
    if (!isNull(offset)) {
      DCHECK_GE(offset, 0);
      DCHECK_LE(offset, 1);
      DCHECK_GE(offset, lastOffset);
      lastOffset = offset;
    }
    result.push_back(keyframe->clone());
  }

  if (result.isEmpty())
    return result;

  if (isNull(result.back()->offset()))
    result.back()->setOffset(1);

  if (result.size() > 1 && isNull(result[0]->offset()))
    result.front()->setOffset(0);

  size_t lastIndex = 0;
  lastOffset = result.front()->offset();
  for (size_t i = 1; i < result.size(); ++i) {
    double offset = result[i]->offset();
    if (!isNull(offset)) {
      for (size_t j = 1; j < i - lastIndex; ++j)
        result[lastIndex + j]->setOffset(
            lastOffset + (offset - lastOffset) * j / (i - lastIndex));
      lastIndex = i;
      lastOffset = offset;
    }
  }

  return result;
}
示例#24
0
文件: AsyncIO.cpp 项目: JasonCC/folly
Range<AsyncIO::Op**> AsyncIO::pollCompleted() {
  CHECK(ctx_);
  CHECK_NE(pollFd_, -1) << "pollCompleted() only allowed on pollable object";
  uint64_t numEvents;
  // This sets the eventFd counter to 0, see
  // http://www.kernel.org/doc/man-pages/online/pages/man2/eventfd.2.html
  ssize_t rc;
  do {
    rc = ::read(pollFd_, &numEvents, 8);
  } while (rc == -1 && errno == EINTR);
  if (UNLIKELY(rc == -1 && errno == EAGAIN)) {
    return Range<Op**>();  // nothing completed
  }
  checkUnixError(rc, "AsyncIO: read from event fd failed");
  DCHECK_EQ(rc, 8);

  DCHECK_GT(numEvents, 0);
  DCHECK_LE(numEvents, pending_);

  // Don't reap more than numEvents, as we've just reset the counter to 0.
  return doWait(numEvents, numEvents);
}
示例#25
0
文件: AsyncIO.cpp 项目: GYGit/folly
Range<AsyncIO::Op**> AsyncIO::doWait(size_t minRequests, size_t maxRequests) {
  io_event events[maxRequests];

  size_t count = 0;
  do {
    int ret;
    do {
      // GOTCHA: io_getevents() may returns less than min_nr results if
      // interrupted after some events have been read (if before, -EINTR
      // is returned).
      ret = io_getevents(ctx_,
                         minRequests - count,
                         maxRequests - count,
                         events + count,
                         /* timeout */ nullptr);  // wait forever
    } while (ret == -EINTR);
    // Check as may not be able to recover without leaking events.
    CHECK_GE(ret, 0)
      << "AsyncIO: io_getevents failed with error " << errnoStr(-ret);
    count += ret;
  } while (count < minRequests);
  DCHECK_LE(count, maxRequests);

  completed_.clear();
  if (count == 0) {
    return folly::Range<Op**>();
  }

  for (size_t i = 0; i < count; ++i) {
    DCHECK(events[i].obj);
    Op* op = boost::intrusive::get_parent_from_member(
        events[i].obj, &AsyncIOOp::iocb_);
    decrementPending();
    op->complete(events[i].res);
    completed_.push_back(op);
  }

  return folly::Range<Op**>(&completed_.front(), count);
}
示例#26
0
// helper method for case where needles.size() <= 16
size_t qfind_first_byte_of_needles16(const StringPieceLite haystack,
                                     const StringPieceLite needles) {
  DCHECK_GT(haystack.size(), 0u);
  DCHECK_GT(needles.size(), 0u);
  DCHECK_LE(needles.size(), 16u);
  if ((needles.size() <= 2 && haystack.size() >= 256) ||
      // must bail if we can't even SSE-load a single segment of haystack
      (haystack.size() < 16 &&
       page_for(haystack.end() - 1) != page_for(haystack.data() + 15)) ||
      // can't load needles into SSE register if it could cross page boundary
      page_for(needles.end() - 1) != page_for(needles.data() + 15)) {
    return detail::qfind_first_byte_of_nosse(haystack, needles);
  }

  auto arr2 = _mm_loadu_si128(
      reinterpret_cast<const __m128i*>(needles.data()));
  // do an unaligned load for first block of haystack
  auto arr1 = _mm_loadu_si128(
      reinterpret_cast<const __m128i*>(haystack.data()));
  auto index =
      _mm_cmpestri(arr2, int(needles.size()), arr1, int(haystack.size()), 0);
  if (index < 16) {
    return index;
  }

  // Now, we can do aligned loads hereafter...
  size_t i = nextAlignedIndex(haystack.data());
  for (; i < haystack.size(); i+= 16) {
    arr1 =
        _mm_load_si128(reinterpret_cast<const __m128i*>(haystack.data() + i));
    index = _mm_cmpestri(
        arr2, int(needles.size()), arr1, int(haystack.size() - i), 0);
    if (index < 16) {
      return i + index;
    }
  }
  return std::string::npos;
}
示例#27
0
	void TruncateUTF8ToByteSize(const std::string& input,
		const size_t byte_size,
		std::string* output) {
		DCHECK(output);
		if (byte_size > input.length()) {
			*output = input;
			return;
		}
		DCHECK_LE(byte_size, static_cast<uint32>(kint32max));
		// Note: This cast is necessary because CBU8_NEXT uses int32s.
		int32 truncation_length = static_cast<int32>(byte_size);
		int32 char_index = truncation_length - 1;
		const char* data = input.data();

		// Using CBU8, we will move backwards from the truncation point
		// to the beginning of the string looking for a valid UTF8
		// character.  Once a full UTF8 character is found, we will
		// truncate the string to the end of that character.
		while (char_index >= 0) {
			int32 prev = char_index;
			base_icu::UChar32 code_point = 0;
			CBU8_NEXT(data, char_index, truncation_length, code_point);
			if (!IsValidCharacter(code_point) ||
				!IsValidCodepoint(code_point)) {
				char_index = prev - 1;
			}
			else {
				break;
			}
		}

		if (char_index >= 0)
			*output = input.substr(0, char_index);
		else
			output->clear();
	}
示例#28
0
Decimal RangeInputType::findClosestTickMarkValue(const Decimal& value) {
  updateTickMarkValues();
  if (!m_tickMarkValues.size())
    return Decimal::nan();

  size_t left = 0;
  size_t right = m_tickMarkValues.size();
  size_t middle;
  while (true) {
    DCHECK_LE(left, right);
    middle = left + (right - left) / 2;
    if (!middle)
      break;
    if (middle == m_tickMarkValues.size() - 1 &&
        m_tickMarkValues[middle] < value) {
      middle++;
      break;
    }
    if (m_tickMarkValues[middle - 1] <= value &&
        m_tickMarkValues[middle] >= value)
      break;

    if (m_tickMarkValues[middle] < value)
      left = middle;
    else
      right = middle;
  }
  const Decimal closestLeft = middle ? m_tickMarkValues[middle - 1]
                                     : Decimal::infinity(Decimal::Negative);
  const Decimal closestRight = middle != m_tickMarkValues.size()
                                   ? m_tickMarkValues[middle]
                                   : Decimal::infinity(Decimal::Positive);
  if (closestRight - value < value - closestLeft)
    return closestRight;
  return closestLeft;
}
示例#29
0
 inline bool contains(uint8_t i) const {
   DCHECK_LE(size_, 256);
   return sparse_[i] < size_ && dense_[sparse_[i]] == i;
 }
示例#30
0
void serialize(
    ThriftTensor& out,
    LongRange sizes,
    LongRange strides,
    folly::IOBuf&& data,
    ThriftTensorDataType dtype,
    size_t elementSize,
    ThriftTensorEndianness endianness,
    SharingMode sharing) {
  DCHECK(!data.isChained());
  if (endianness == ThriftTensorEndianness::NATIVE) {
    endianness = gMachineEndianness;
  } else {
    CHECK(endianness == gMachineEndianness)
      << "Non-native endianness not yet implemented";
  }

  int ndims = sizes.size();
  uint64_t dataSize = 1;
  uint64_t contiguousSize = 1;
  int firstContiguousDim = ndims - 1;

  if (!strides.empty()) {
    DCHECK_EQ(strides.size(), ndims);
    while (firstContiguousDim >= 0) {
      if (strides[firstContiguousDim] != contiguousSize) {
        break;
      }
      contiguousSize *= sizes[firstContiguousDim];
      --firstContiguousDim;
    }
    ++firstContiguousDim;
    dataSize = contiguousSize;
    for (int i = 0; i < firstContiguousDim; ++i) {
      dataSize *= sizes[i];
    }
  } else {
    for (auto s : sizes) {
      dataSize *= s;
    }
    contiguousSize = dataSize;
    firstContiguousDim = 0;
  }

  // Dimensions from firstContiguousDim till the last form a contiguous range
  // of contiguousSize elements; we'll copy / clone that in one go rather
  // than iterating through all elements.

  // We want bytes.
  dataSize *= elementSize;
  contiguousSize *= elementSize;

  DCHECK_LE(contiguousSize, dataSize);

  out.dataType = dtype;
  out.endianness = endianness;
  out.sizes.assign(sizes.begin(), sizes.end());

  if (ndims == 0) {
    // Empty tensor, nothing to do.
    out.data = folly::IOBuf();
    data = folly::IOBuf();
    return;
  }

  if (firstContiguousDim == 0) {
    // We're done.
    DCHECK_GE(data.length(), dataSize);
    data.trimEnd(data.length() - dataSize);
    detail::applySharingMode(data, sharing);
    out.data = std::move(data);
    return;
  }

  // We have to do this the hard way...
  folly::IOBufQueue outQueue;

  // If the contiguous chunk size is >= kMinCloneSize, we clone rather
  // than copying
  static constexpr uint64_t kMinCloneSize = 4 << 10;

  // Don't allocate huge contiguous buffers.
  // jemalloc defers to mmap() for buffers of 4MiB or more.
  static constexpr uint64_t kMaxBlockSize = 2 << 20;
  folly::io::QueueAppender appender(&outQueue,
                                    std::min(dataSize, kMaxBlockSize));

  std::vector<uint64_t> counter;
  counter.resize(firstContiguousDim);
  int idx = firstContiguousDim;
  const uint8_t* src = data.data();
  bool mayShare = false;
  switch (sharing) {
  case SHARE_NONE:
    break;
  case SHARE_IOBUF_MANAGED:
    mayShare = data.isManagedOne();
    break;
  case SHARE_ALL:
    mayShare = true;
    break;
  };
  while (idx >= 0) {
    if (idx == firstContiguousDim) {
      if (mayShare && contiguousSize >= kMinCloneSize) {
        appender.insert(partialCloneOne(data, src - data.data(),
                                        contiguousSize));
      } else {
        appender.push(src, contiguousSize);
      }
      --idx;
      continue;
    }
    src += strides[idx] * elementSize;
    if (++counter[idx] == sizes[idx]) {
      src -= sizes[idx] * strides[idx] * elementSize;
      counter[idx] = 0;
      --idx;
    } else {
      idx = firstContiguousDim;
    }
  }

  outQueue.move()->cloneInto(out.data);
}