103 lines
2.7 KiB
C
103 lines
2.7 KiB
C
|
/**
|
||
|
* 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 <memory>
|
||
|
#include <unordered_map>
|
||
|
#include <vector>
|
||
|
#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<folly::IOBuf> 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<folly::IOBuf>&& 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<folly::IOBuf> head_;
|
||
|
std::vector<folly::StringPiece> strings_;
|
||
|
|
||
|
typedef
|
||
|
std::unordered_map<folly::StringPiece, uint32_t, folly::StringPieceHash>
|
||
|
StringMap;
|
||
|
|
||
|
// Only allocate writer if needed (when actually add()ing)
|
||
|
struct Writer {
|
||
|
template <typename... Args>
|
||
|
/* implicit */ Writer(Args... args) : appender(args...) { }
|
||
|
folly::io::Appender appender;
|
||
|
StringMap map;
|
||
|
};
|
||
|
std::unique_ptr<Writer> 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_ */
|
||
|
|