proxygen
AtomicBatchDispatcher.h
Go to the documentation of this file.
1 /*
2  * Copyright 2016-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <memory>
19 #include <stdexcept>
20 #include <string>
21 #include <utility>
22 #include <vector>
23 
24 #include <folly/CPortability.h>
25 #include <folly/Function.h>
26 #include <folly/Optional.h>
28 #include <folly/futures/Future.h>
29 #include <folly/futures/Promise.h>
30 
31 namespace folly {
32 namespace fibers {
33 
40 class FOLLY_EXPORT ABDUsageException : public std::logic_error {
41  using std::logic_error::logic_error;
42 };
43 
48 class FOLLY_EXPORT ABDCommitNotCalledException : public std::runtime_error {
49  public:
51  : std::runtime_error(
52  "AtomicBatchDispatcher destroyed before commit() was called") {}
53 };
54 
62 class FOLLY_EXPORT ABDTokenNotDispatchedException : public std::runtime_error {
63  using std::runtime_error::runtime_error;
64 };
65 
167 template <typename InputT, typename ResultT>
169  private:
170  struct DispatchBaton;
171  friend struct DispatchBaton;
172 
173  public:
174  using DispatchFunctionT =
175  folly::Function<std::vector<ResultT>(std::vector<InputT>&&)>;
176 
177  class Token {
178  public:
179  explicit Token(std::shared_ptr<DispatchBaton> baton, size_t sequenceNumber);
180 
181  Future<ResultT> dispatch(InputT input);
182 
183  // Allow moving a Token object
184  Token(Token&&) = default;
185  Token& operator=(Token&&) = default;
186 
187  size_t sequenceNumber() const;
188 
189  private:
190  // Disallow copying a Token object
191  Token(const Token&) = delete;
192  Token& operator=(const Token&) = delete;
193 
194  std::shared_ptr<DispatchBaton> baton_;
196  };
197 
198  explicit AtomicBatchDispatcher(DispatchFunctionT&& dispatchFunc);
199 
201 
202  // numEntries is a *hint* about the number of inputs to expect:
203  // - It is used purely to reserve space for storing vector of inputs etc.,
204  // so that reeallocation and move copy are reduced / not needed.
205  // - It is provided purely for performance reasons
206  void reserve(size_t numEntries);
207 
208  Token getToken();
209 
210  void commit();
211 
212  // Allow moving an AtomicBatchDispatcher object
214  AtomicBatchDispatcher& operator=(AtomicBatchDispatcher&&) = default;
215 
216  private:
217  // Disallow copying an AtomicBatchDispatcher object
219  AtomicBatchDispatcher& operator=(const AtomicBatchDispatcher&) = delete;
220 
222  std::shared_ptr<DispatchBaton> baton_;
223 };
224 
225 // initialCapacity is a *hint* about the number of inputs to expect:
226 // - It is used purely to reserve space for storing vector of inputs etc.,
227 // so that reeallocation and move copy are reduced / not needed.
228 // - It is provided purely for performance reasons
229 template <typename InputT, typename ResultT>
231  folly::Function<std::vector<ResultT>(std::vector<InputT>&&)> dispatchFunc,
232  size_t initialCapacity = 0);
233 
234 } // namespace fibers
235 } // namespace folly
236 
AtomicBatchDispatcher< InputT, ResultT > createAtomicBatchDispatcher(folly::Function< std::vector< ResultT >(std::vector< InputT > &&)> dispatchFunc, size_t initialCapacity)
STL namespace.
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
#define FOLLY_EXPORT
Definition: CPortability.h:133
std::shared_ptr< DispatchBaton > baton_
std::enable_if< std::is_integral< Src >::value &&IsSomeString< Tgt >::value &&sizeof(Src)< 4 >::typetoAppend(Src value, Tgt *result){typedef typename std::conditional< std::is_signed< Src >::value, int64_t, uint64_t >::type Intermediate;toAppend< Tgt >static_cast< Intermediate >value), result);}template< class Src >typename std::enable_if< std::is_integral< Src >::value &&sizeof(Src)< 4 &&!std::is_same< Src, char >::value, size_t >::typeestimateSpaceNeeded(Src value){typedef typename std::conditional< std::is_signed< Src >::value, int64_t, uint64_t >::type Intermediate;return estimateSpaceNeeded(static_cast< Intermediate >value));}template< class Tgt, class Src >typename std::enable_if< std::is_enum< Src >::value &&IsSomeString< Tgt >::value >::typetoAppend(Src value, Tgt *result){toAppend(static_cast< typename std::underlying_type< Src >::type >value), result);}template< class Src >typename std::enable_if< std::is_enum< Src >::value, size_t >::typeestimateSpaceNeeded(Src value){return estimateSpaceNeeded(static_cast< typename std::underlying_type< Src >::type >value));}namespace detail{constexpr int kConvMaxDecimalInShortestLow=-6;constexpr int kConvMaxDecimalInShortestHigh=21;}template< class Tgt, class Src >typename std::enable_if< std::is_floating_point< Src >::value &&IsSomeString< Tgt >::value >::typetoAppend(Src value, Tgt *result, double_conversion::DoubleToStringConverter::DtoaMode mode, unsigned int numDigits){using namespace double_conversion;DoubleToStringConverter conv(DoubleToStringConverter::NO_FLAGS,"Infinity","NaN", 'E', detail::kConvMaxDecimalInShortestLow, detail::kConvMaxDecimalInShortestHigh, 6, 1);char buffer[256];StringBuilder builder(buffer, sizeof(buffer));switch(mode){case DoubleToStringConverter::SHORTEST:conv.ToShortest(value,&builder);break;case DoubleToStringConverter::SHORTEST_SINGLE:conv.ToShortestSingle(static_cast< float >value),&builder);break;case DoubleToStringConverter::FIXED:conv.ToFixed(value, int(numDigits),&builder);break;default:CHECK(mode==DoubleToStringConverter::PRECISION);conv.ToPrecision(value, int(numDigits),&builder);break;}const size_t length=size_t(builder.position());builder.Finalize();result->append(buffer, length);}template< class Tgt, class Src >typename std::enable_if< std::is_floating_point< Src >::value &&IsSomeString< Tgt >::value >::typetoAppend(Src value, Tgt *result){toAppend(value, result, double_conversion::DoubleToStringConverter::SHORTEST, 0);}template< class Src >typename std::enable_if< std::is_floating_point< Src >::value, size_t >::typeestimateSpaceNeeded(Src value){constexpr int kMaxMantissaSpace=double_conversion::DoubleToStringConverter::kBase10MaximalLength+1;constexpr int kMaxExponentSpace=2+3;static const int kMaxPositiveSpace=std::max({kMaxMantissaSpace+kMaxExponentSpace, kMaxMantissaSpace-detail::kConvMaxDecimalInShortestLow, detail::kConvMaxDecimalInShortestHigh,});return size_t(kMaxPositiveSpace+(value< 0?1:0));}template< class Src >struct HasLengthEstimator:std::false_type{};template< class Src >constexpr typename std::enable_if< !std::is_fundamental< Src >::value &&!IsSomeString< Src >::value &&!std::is_convertible< Src, const char * >::value &&!std::is_convertible< Src, StringPiece >::value &&!std::is_enum< Src >::value &&!HasLengthEstimator< Src >::value, size_t >::typeestimateSpaceNeeded(const Src &){return sizeof(Src)+1;}namespace detail{template< class Tgt >typename std::enable_if< IsSomeString< Tgt >::value, size_t >::typeestimateSpaceToReserve(size_t sofar, Tgt *){return sofar;}template< class T, class...Ts >size_t estimateSpaceToReserve(size_t sofar, const T &v, const Ts &...vs){return estimateSpaceToReserve(sofar+estimateSpaceNeeded(v), vs...);}template< class...Ts >void reserveInTarget(const Ts &...vs){getLastElement(vs...) -> reserve(estimateSpaceToReserve(0, vs...))
Definition: Conv.h:792
auto dispatch(Type type, F &&f) -> decltype(f(std::declval< Default >()))
Definition: Instructions.h:175