/** @file mongommf.h
*
* Copyright (C) 2008 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
#pragma once
#include "../util/mmap.h"
#include "../util/paths.h"
namespace mongo {
/** MongoMMF adds some layers atop memory mapped files - specifically our handling of private views & such.
if you don't care about journaling/durability (temp sort files & such) use MemoryMappedFile class,
not this.
*/
class MongoMMF : private MemoryMappedFile {
public:
MongoMMF();
virtual ~MongoMMF();
virtual void close();
/** @return true if opened ok. */
bool open(string fname, bool sequentialHint);
/** @return file length */
unsigned long long length() const { return MemoryMappedFile::length(); }
string filename() const { return MemoryMappedFile::filename(); }
void flush(bool sync) { MemoryMappedFile::flush(sync); }
/* Creates with length if DNE, otherwise uses existing file length,
passed length.
@param sequentialHint if true will be sequentially accessed
@return true for ok
*/
bool create(string fname, unsigned long long& len, bool sequentialHint);
/* Get the "standard" view (which is the private one).
@return the private view.
*/
void* getView() const { return _view_private; }
/* Get the "write" view (which is required for writing).
@return the write view.
*/
void* view_write() const { return _view_write; }
/* switch to _view_write. normally, this is a bad idea since your changes will not
show up in _view_private if there have been changes there; thus the leading underscore
as a tad of a "warning". but useful when done with some care, such as during
initialization.
*/
static void* _switchToWritableView(void *private_ptr);
/** for a filename a/b/c.3
filePath() is "a/b/c"
fileSuffixNo() is 3
if the suffix is "ns", fileSuffixNo -1
*/
RelativePath relativePath() const {
DEV assert( !_p._p.empty() );
return _p;
}
int fileSuffixNo() const { return _fileSuffixNo; }
/** true if we have written.
set in PREPLOGBUFFER, it is NOT set immediately on write intent declaration.
reset to false in REMAPPRIVATEVIEW
*/
bool& willNeedRemap() { return _willNeedRemap; }
void remapThePrivateView();
virtual bool isMongoMMF() { return true; }
private:
void *_view_write;
void *_view_private;
bool _willNeedRemap;
RelativePath _p; // e.g. "somepath/dbname"
int _fileSuffixNo; // e.g. 3. -1="ns"
void setPath(string pathAndFileName);
bool finishOpening();
};
/** for durability support we want to be able to map pointers to specific MongoMMF objects.
*/
class PointerToMMF : boost::noncopyable {
public:
PointerToMMF();
/** register view. \
threadsafe
*/
void add(void *view, MongoMMF *f);
/** de-register view.
threadsafe
*/
void remove(void *view);
/** find associated MMF object for a given pointer.
threadsafe
@param ofs out returns offset into the view of the pointer, if found.
@return the MongoMMF to which this pointer belongs. null if not found.
*/
MongoMMF* find(void *p, /*out*/ size_t& ofs);
/** for doing many finds in a row with one lock operation */
mutex& _mutex() { return _m; }
MongoMMF* find_inlock(void *p, /*out*/ size_t& ofs);
map::iterator finditer_inlock(void *p) { return _views.upper_bound(p); }
private:
mutex _m;
map _views;
};
// allows a pointer into any private view of a MongoMMF to be resolved to the MongoMMF object
extern PointerToMMF privateViews;
}