summaryrefslogtreecommitdiff
path: root/src/mongo/db/diskloc.h
blob: 5295df3e260a6194f923b394ffa95fdf5ee5d259 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/**
*    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 <http://www.gnu.org/licenses/>.
*/

/* @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;
    class DiskLoc;

    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<V> * btree() const;

        // Explicitly signals we are writing and casts away const
        template< class V >
        BtreeBucket<V> * btreemod() const;

        /*MongoDataFile& pdf() const;*/
    };
#pragma pack()

    const DiskLoc minDiskLoc(0, 1);
    const DiskLoc maxDiskLoc(0x7fffffff, 0x7fffffff);

} // namespace mongo