rocksdb/thrift/lib/cpp/protocol/neutronium/InternTable.h

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_ */