/** * 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 . */ /* @file diskloc.h Storage subsystem management. Lays out our datafiles on disk, manages disk space. */ #pragma once #include "jsobj.h" namespace mongo { class Record; class DeletedRecord; class Extent; class MongoDataFile; template< class Version > class BtreeBucket; #pragma pack(1) /** represents a disk location/offset on disk in a database. 64 bits. it is assumed these will be passed around by value a lot so don't do anything to make them large (such as adding a virtual function) */ class DiskLoc { int _a; // this will be volume, file #, etsc. but is a logical value could be anything depending on storage engine int ofs; public: enum SentinelValues { /* note NullOfs is different. todo clean up. see refs to NullOfs in code - use is valid but outside DiskLoc context so confusing as-is. */ NullOfs = -1, MaxFiles=16000 // thus a limit of about 32TB of data per db }; DiskLoc(int a, int Ofs) : _a(a), ofs(Ofs) { } DiskLoc() { Null(); } DiskLoc(const DiskLoc& l) { _a=l._a; ofs=l.ofs; } bool questionable() const { return ofs < -1 || _a < -1 || _a > 524288; } bool isNull() const { return _a == -1; } void Null() { _a = -1; ofs = 0; /* note NullOfs is different. todo clean up. see refs to NullOfs in code - use is valid but outside DiskLoc context so confusing as-is. */ } void assertOk() { assert(!isNull()); } void setInvalid() { _a = -2; ofs = 0; } bool isValid() const { return _a != -2; } string toString() const { if ( isNull() ) return "null"; stringstream ss; ss << hex << _a << ':' << ofs; return ss.str(); } BSONObj toBSONObj() const { return BSON( "file" << _a << "offset" << ofs ); } int a() const { return _a; } int& GETOFS() { return ofs; } int getOfs() const { return ofs; } void set(int a, int b) { _a=a; ofs=b; } void inc(int amt) { assert( !isNull() ); ofs += amt; } bool sameFile(DiskLoc b) { return _a== b._a; } bool operator==(const DiskLoc& b) const { return _a==b._a&& ofs == b.ofs; } bool operator!=(const DiskLoc& b) const { return !(*this==b); } const DiskLoc& operator=(const DiskLoc& b) { _a=b._a; ofs = b.ofs; //assert(ofs!=0); return *this; } int compare(const DiskLoc& b) const { int x = _a - b._a; if ( x ) return x; return ofs - b.ofs; } bool operator<(const DiskLoc& b) const { return compare(b) < 0; } /** * Marks this disk loc for writing * @returns a non const reference to this disk loc * This function explicitly signals we are writing and casts away const */ DiskLoc& writing() const; // see dur.h /* Get the "thing" associated with this disk location. it is assumed the object is what you say it is -- you must assure that (think of this as an unchecked type cast) Note: set your Context first so that the database to which the diskloc applies is known. */ BSONObj obj() const; Record* rec() const; DeletedRecord* drec() const; Extent* ext() const; template< class V > const BtreeBucket * btree() const; // Explicitly signals we are writing and casts away const template< class V > BtreeBucket * btreemod() const; /*MongoDataFile& pdf() const;*/ }; #pragma pack() const DiskLoc minDiskLoc(0, 1); const DiskLoc maxDiskLoc(0x7fffffff, 0x7fffffff); } // namespace mongo