00001
00017 #pragma once
00018
00019 #include "../pch.h"
00020
00021 #include "jsobj.h"
00022 #include "diskloc.h"
00023 #include "matcher.h"
00024
00025 namespace mongo {
00026
00027 class NamespaceDetails;
00028 class Record;
00029 class CoveredIndexMatcher;
00030
00031
00032
00033
00034
00035
00036
00037 class Cursor : boost::noncopyable {
00038 public:
00039 virtual ~Cursor() {}
00040 virtual bool ok() = 0;
00041 bool eof() { return !ok(); }
00042 virtual Record* _current() = 0;
00043 virtual BSONObj current() = 0;
00044 virtual DiskLoc currLoc() = 0;
00045 virtual bool advance() = 0;
00046 virtual BSONObj currKey() const { return BSONObj(); }
00047
00048
00049
00050 virtual DiskLoc refLoc() = 0;
00051
00052
00053
00054
00055
00056 virtual void setTailable() {}
00057
00058 virtual bool tailable() {
00059 return false;
00060 }
00061
00062 virtual void aboutToDeleteBucket(const DiskLoc& b) { }
00063
00064
00065 virtual Cursor* clone() {
00066 return 0;
00067 }
00068
00069 virtual BSONObj indexKeyPattern() {
00070 return BSONObj();
00071 }
00072
00073
00074
00075
00076 virtual void noteLocation() { }
00077
00078
00079 virtual void checkLocation() { }
00080
00081 virtual bool supportGetMore() = 0;
00082 virtual bool supportYields() = 0;
00083
00084 virtual string toString() { return "abstract?"; }
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 virtual bool getsetdup(DiskLoc loc) = 0;
00095
00096 virtual bool isMultiKey() const = 0;
00097
00105 virtual bool modifiedKeys() const = 0;
00106
00107 virtual BSONObj prettyIndexBounds() const { return BSONArray(); }
00108
00109 virtual bool capped() const { return false; }
00110
00111 virtual long long nscanned() = 0;
00112
00113
00114
00115
00116 virtual CoveredIndexMatcher *matcher() const { return 0; }
00117
00118
00119
00120
00121 virtual void setMatcher( shared_ptr< CoveredIndexMatcher > matcher ) {
00122 massert( 13285, "manual matcher config not allowed", false );
00123 }
00124 };
00125
00126
00127 class AdvanceStrategy {
00128 public:
00129 virtual ~AdvanceStrategy() { }
00130 virtual DiskLoc next( const DiskLoc &prev ) const = 0;
00131 };
00132
00133 const AdvanceStrategy *forward();
00134 const AdvanceStrategy *reverse();
00135
00136
00137 class BasicCursor : public Cursor {
00138 public:
00139 BasicCursor(DiskLoc dl, const AdvanceStrategy *_s = forward()) : curr(dl), s( _s ), _nscanned() {
00140 incNscanned();
00141 init();
00142 }
00143 BasicCursor(const AdvanceStrategy *_s = forward()) : s( _s ), _nscanned() {
00144 init();
00145 }
00146 bool ok() { return !curr.isNull(); }
00147 Record* _current() {
00148 assert( ok() );
00149 return curr.rec();
00150 }
00151 BSONObj current() {
00152 Record *r = _current();
00153 BSONObj j(r);
00154 return j;
00155 }
00156 virtual DiskLoc currLoc() { return curr; }
00157 virtual DiskLoc refLoc() { return curr.isNull() ? last : curr; }
00158 bool advance();
00159 virtual string toString() { return "BasicCursor"; }
00160 virtual void setTailable() {
00161 if ( !curr.isNull() || !last.isNull() )
00162 tailable_ = true;
00163 }
00164 virtual bool tailable() { return tailable_; }
00165 virtual bool getsetdup(DiskLoc loc) { return false; }
00166 virtual bool isMultiKey() const { return false; }
00167 virtual bool modifiedKeys() const { return false; }
00168 virtual bool supportGetMore() { return true; }
00169 virtual bool supportYields() { return true; }
00170 virtual CoveredIndexMatcher *matcher() const { return _matcher.get(); }
00171 virtual void setMatcher( shared_ptr< CoveredIndexMatcher > matcher ) { _matcher = matcher; }
00172 virtual long long nscanned() { return _nscanned; }
00173
00174 protected:
00175 DiskLoc curr, last;
00176 const AdvanceStrategy *s;
00177 void incNscanned() { if ( !curr.isNull() ) { ++_nscanned; } }
00178 private:
00179 bool tailable_;
00180 shared_ptr< CoveredIndexMatcher > _matcher;
00181 long long _nscanned;
00182 void init() { tailable_ = false; }
00183 };
00184
00185
00186 class ReverseCursor : public BasicCursor {
00187 public:
00188 ReverseCursor(DiskLoc dl) : BasicCursor( dl, reverse() ) { }
00189 ReverseCursor() : BasicCursor( reverse() ) { }
00190 virtual string toString() { return "ReverseCursor"; }
00191 };
00192
00193 class ForwardCappedCursor : public BasicCursor, public AdvanceStrategy {
00194 public:
00195 ForwardCappedCursor( NamespaceDetails *nsd = 0, const DiskLoc &startLoc = DiskLoc() );
00196 virtual string toString() {
00197 return "ForwardCappedCursor";
00198 }
00199 virtual DiskLoc next( const DiskLoc &prev ) const;
00200 virtual bool capped() const { return true; }
00201 private:
00202 NamespaceDetails *nsd;
00203 };
00204
00205 class ReverseCappedCursor : public BasicCursor, public AdvanceStrategy {
00206 public:
00207 ReverseCappedCursor( NamespaceDetails *nsd = 0, const DiskLoc &startLoc = DiskLoc() );
00208 virtual string toString() {
00209 return "ReverseCappedCursor";
00210 }
00211 virtual DiskLoc next( const DiskLoc &prev ) const;
00212 virtual bool capped() const { return true; }
00213 private:
00214 NamespaceDetails *nsd;
00215 };
00216
00217 }