diff options
Diffstat (limited to 'src/mongo/db/storage/mmap_v1/dur_commitjob.h')
-rw-r--r-- | src/mongo/db/storage/mmap_v1/dur_commitjob.h | 304 |
1 files changed, 158 insertions, 146 deletions
diff --git a/src/mongo/db/storage/mmap_v1/dur_commitjob.h b/src/mongo/db/storage/mmap_v1/dur_commitjob.h index b2d07c3b293..8261b613c57 100644 --- a/src/mongo/db/storage/mmap_v1/dur_commitjob.h +++ b/src/mongo/db/storage/mmap_v1/dur_commitjob.h @@ -35,179 +35,191 @@ namespace mongo { namespace dur { - typedef std::vector<std::shared_ptr<DurOp> > DurOpsVector; +typedef std::vector<std::shared_ptr<DurOp>> DurOpsVector; - /** - * Declaration of an intent to write to a region of a memory mapped view. We store the end - * rather than the start pointer to make operator < faster since that is heavily used in - * set lookup. - */ - struct WriteIntent { - WriteIntent() : p(0) { } - WriteIntent(void *a, unsigned b) : p((char*)a + b), len(b) { } +/** + * Declaration of an intent to write to a region of a memory mapped view. We store the end + * rather than the start pointer to make operator < faster since that is heavily used in + * set lookup. + */ +struct WriteIntent { + WriteIntent() : p(0) {} + WriteIntent(void* a, unsigned b) : p((char*)a + b), len(b) {} + + void* start() const { + return (char*)p - len; + } + void* end() const { + return p; + } + unsigned length() const { + return len; + } + bool operator<(const WriteIntent& rhs) const { + return end() < rhs.end(); + } + + bool overlaps(const WriteIntent& rhs) const { + return (start() <= rhs.end() && end() >= rhs.start()); + } + + bool contains(const WriteIntent& rhs) const { + return (start() <= rhs.start() && end() >= rhs.end()); + } + + // merge into me: + void absorb(const WriteIntent& other); + + friend std::ostream& operator<<(std::ostream& out, const WriteIntent& wi) { + return (out << "p: " << wi.p << " end: " << wi.end() << " len: " << wi.len); + } + +private: + void* p; // intent to write up to p + unsigned len; // up to this len +}; + +typedef std::vector<WriteIntent> WriteIntentsVector; - void* start() const { return (char*)p - len; } - void* end() const { return p; } - unsigned length() const { return len; } - bool operator < (const WriteIntent& rhs) const { return end() < rhs.end(); } - bool overlaps(const WriteIntent& rhs) const { - return (start() <= rhs.end() && end() >= rhs.start()); - } +/** + * Bitmap to remember things we have already marked for journaling. False negatives are ok + * if infrequent, since they impact performance. + */ +template <int Prime> +class Already { + MONGO_DISALLOW_COPYING(Already); + +public: + Already() { + clear(); + } + + void clear() { + memset(this, 0, sizeof(*this)); + } - bool contains(const WriteIntent& rhs) const { - return (start() <= rhs.start() && end() >= rhs.end()); + /** + * Checks if we have Already recorded/indicated our write intent for this region of + * memory and automatically upgrades the length if the length was shorter previously. + * + * @return true if already indicated. + */ + bool checkAndSet(void* p, int len) { + const unsigned x = hashPointer(p); + std::pair<void*, int>& nd = nodes[x % Prime]; + + if (nd.first == p) { + if (nd.second < len) { + nd.second = len; + return false; // haven't indicated this len yet + } + return true; // already indicated } - // merge into me: - void absorb(const WriteIntent& other); - - friend std::ostream& operator << (std::ostream& out, const WriteIntent& wi) { - return (out << "p: " << wi.p << " end: " << wi.end() << " len: " << wi.len); + nd.first = p; + nd.second = len; + return false; // a new set + } + +private: + static unsigned hashPointer(void* v) { + unsigned x = 0; + unsigned char* p = (unsigned char*)&v; + for (unsigned i = 0; i < sizeof(void*); i++) { + x = x * 131 + p[i]; } + return x; + } + + std::pair<void*, int> nodes[Prime]; +}; - private: - void *p; // intent to write up to p - unsigned len; // up to this len - }; - typedef std::vector<WriteIntent> WriteIntentsVector; +/** + * Tracks all write operations on the private view so they can be journaled. + */ +class CommitJob { + MONGO_DISALLOW_COPYING(CommitJob); +public: + CommitJob(); + ~CommitJob(); /** - * Bitmap to remember things we have already marked for journaling. False negatives are ok - * if infrequent, since they impact performance. + * Note an operation other than a "basic write". */ - template<int Prime> - class Already { - MONGO_DISALLOW_COPYING(Already); - public: - Already() { - clear(); - } - - void clear() { - memset(this, 0, sizeof(*this)); - } - - /** - * Checks if we have Already recorded/indicated our write intent for this region of - * memory and automatically upgrades the length if the length was shorter previously. - * - * @return true if already indicated. - */ - bool checkAndSet(void* p, int len) { - const unsigned x = hashPointer(p); - std::pair<void*, int>& nd = nodes[x % Prime]; - - if (nd.first == p) { - if (nd.second < len) { - nd.second = len; - return false; // haven't indicated this len yet - } - return true; // already indicated - } - - nd.first = p; - nd.second = len; - return false; // a new set - } + void noteOp(std::shared_ptr<DurOp> p); - private: - - static unsigned hashPointer(void *v) { - unsigned x = 0; - unsigned char *p = (unsigned char *)&v; - for (unsigned i = 0; i < sizeof(void*); i++) { - x = x * 131 + p[i]; - } - return x; - } + /** + * Record/note an intent to write. + * + * NOTE: Not thread safe. Requires the mutex to be locked. + */ + void note(void* p, int len); - std::pair<void*, int> nodes[Prime]; - }; + /** + * When this value is false we don't have to do any group commit. + */ + bool hasWritten() const { + return _hasWritten; + } + /** + * We use the commitjob object over and over, calling committingReset() rather than + * reconstructing. + */ + void committingReset(); /** - * Tracks all write operations on the private view so they can be journaled. + * We check how much written and if it is getting to be a lot, we commit sooner. */ - class CommitJob { - MONGO_DISALLOW_COPYING(CommitJob); - public: - CommitJob(); - ~CommitJob(); - - /** - * Note an operation other than a "basic write". - */ - void noteOp(std::shared_ptr<DurOp> p); - - /** - * Record/note an intent to write. - * - * NOTE: Not thread safe. Requires the mutex to be locked. - */ - void note(void* p, int len); - - /** - * When this value is false we don't have to do any group commit. - */ - bool hasWritten() const { return _hasWritten; } - - /** - * We use the commitjob object over and over, calling committingReset() rather than - * reconstructing. - */ - void committingReset(); - - /** - * We check how much written and if it is getting to be a lot, we commit sooner. - */ - size_t bytes() const { return _bytes; } - - /** - * Sorts the internal list of write intents so that overlapping and duplicate items can be - * merged. We do the sort here so the caller receives something they must keep const from - * their POV. - */ - const WriteIntentsVector& getIntentsSorted() { - sort(_intents.begin(), _intents.end()); - return _intents; - } + size_t bytes() const { + return _bytes; + } - const DurOpsVector& ops() const { - return _durOps; - } + /** + * Sorts the internal list of write intents so that overlapping and duplicate items can be + * merged. We do the sort here so the caller receives something they must keep const from + * their POV. + */ + const WriteIntentsVector& getIntentsSorted() { + sort(_intents.begin(), _intents.end()); + return _intents; + } - SimpleMutex groupCommitMutex; + const DurOpsVector& ops() const { + return _durOps; + } - private: + SimpleMutex groupCommitMutex; - void _insertWriteIntent(void* p, int len) { - _intents.push_back(WriteIntent(p, len)); - wassert(_intents.size() < 2000000); - } +private: + void _insertWriteIntent(void* p, int len) { + _intents.push_back(WriteIntent(p, len)); + wassert(_intents.size() < 2000000); + } - // Whether we put write intents or durops - bool _hasWritten; + // Whether we put write intents or durops + bool _hasWritten; - // Write intents along with a bitmask for whether we have already noted them - Already<127> _alreadyNoted; - WriteIntentsVector _intents; + // Write intents along with a bitmask for whether we have already noted them + Already<127> _alreadyNoted; + WriteIntentsVector _intents; - // All the ops other than basic writes - DurOpsVector _durOps; + // All the ops other than basic writes + DurOpsVector _durOps; - // Used to count the private map used bytes. Note that _lastNotedPos doesn't reset with - // each commit, but that is ok we aren't being that precise. - size_t _lastNotedPos; - size_t _bytes; + // Used to count the private map used bytes. Note that _lastNotedPos doesn't reset with + // each commit, but that is ok we aren't being that precise. + size_t _lastNotedPos; + size_t _bytes; - // Warning logging for large commits - uint64_t _lastComplainMs; - unsigned _complains; - }; + // Warning logging for large commits + uint64_t _lastComplainMs; + unsigned _complains; +}; -} // namespace "dur" -} // namespace "mongo" +} // namespace "dur" +} // namespace "mongo" |