/* clientcursor.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 . */ /* Cursor -- and its derived classes -- are our internal cursors. ClientCursor is a wrapper that represents a cursorid from our database application's perspective. */ #pragma once #include "../stdafx.h" namespace mongo { typedef long long CursorId; /* passed to the client so it can send back on getMore */ class Cursor; /* internal server cursor base class */ class ClientCursor; typedef map CCById; extern CCById clientCursorsById; class ClientCursor { DiskLoc _lastLoc; // use getter and setter not this. static CursorId allocCursorId(); public: ClientCursor() : cursorid( allocCursorId() ), pos(0), idleAgeMillis(0) { clientCursorsById.insert( make_pair(cursorid, this) ); } ~ClientCursor(); const CursorId cursorid; string ns; auto_ptr matcher; auto_ptr c; int pos; /* # objects into the cursor so far */ DiskLoc lastLoc() const { return _lastLoc; } void setLastLoc(DiskLoc); auto_ptr< set > filter; // which fields query wants returned Message originalMessage; // this is effectively an auto ptr for data the matcher points to unsigned idleAgeMillis; // how long has the cursor been around, relative to server idle time /* Get rid of cursors for namespaces that begin with nsprefix. Used by drop, deleteIndexes, dropDatabase. */ static void invalidate(const char *nsPrefix); static bool erase(CursorId id) { ClientCursor *cc = find(id); if ( cc ) { delete cc; return true; } return false; } static ClientCursor* find(CursorId id, bool warn = true) { CCById::iterator it = clientCursorsById.find(id); if ( it == clientCursorsById.end() ) { if ( warn ) OCCASIONALLY out() << "ClientCursor::find(): cursor not found in map " << id << " (ok after a drop)\n"; return 0; } return it->second; } /* call when cursor's location changes so that we can update the cursorsbylocation map. if you are locked and internally iterating, only need to call when you are ready to "unlock". */ void updateLocation(); void cleanupByLocation(DiskLoc loc); }; } // namespace mongo