/** * Copyright 2012 Facebook * @author Tudor Bosman (tudorb@fb.com) */ #ifndef THRIFT_LIB_CPP_PROTOCOL_NEUTRONIUM_INTERNTABLE_H_ #define THRIFT_LIB_CPP_PROTOCOL_NEUTRONIUM_INTERNTABLE_H_ #include #include #include #include "folly/Range.h" #include "folly/experimental/io/IOBuf.h" #include "folly/experimental/io/Cursor.h" namespace apache { namespace thrift { namespace protocol { namespace neutronium { /** * Interned string table. * * Strings are stored in a chain of IOBufs, so serializing and deserializing * the InternTable is fast and easy. */ class InternTable { public: InternTable(); /** * Add a string to the table, returning the id. */ uint32_t add(folly::StringPiece str); /** * Get a string from the table, by id; throws std::out_of_range if the * id is invalid. */ folly::StringPiece get(uint32_t id) const { return strings_.at(id); } /** * Serialize the table to a IOBuf chain. * Note that part of the chain may be shared with the InternTable, so * you must call unshare() on the returned buffers if you want to * write to them. */ std::unique_ptr serialize(); /** * Load the table from a IOBuf chain. * Takes ownership of the IOBuf chain. * InternTable will call unshare() appropriately before writing to * buffers from the provided chain. */ void deserialize(std::unique_ptr&& data); /** * Clear the table. */ void clear(); private: // Performance optimization to reduce the number of calls to unshare() / // unshareOne(), which folly::io::Cursor benchmarks have shown to be // somewhat expensive. Given that we know that we only write to the tail // of the IOBuf chain, we can often tell with certainty that the tail // is private to us and so we don't need to check or call unshareOne(). bool maybeShared_; std::unique_ptr head_; std::vector strings_; typedef std::unordered_map StringMap; // Only allocate writer if needed (when actually add()ing) struct Writer { template /* implicit */ Writer(Args... args) : appender(args...) { } folly::io::Appender appender; StringMap map; }; std::unique_ptr writer_; // Not copiable; not movable InternTable(const InternTable&) = delete; InternTable(InternTable&&) = delete; InternTable& operator=(const InternTable&) = delete; InternTable& operator=(InternTable&&) = delete; }; } // namespace neutronium } // namespace protocol } // namespace thrift } // namespace apache #endif /* THRIFT_LIB_CPP_PROTOCOL_NEUTRONIUM_INTERNTABLE_H_ */