Uploaded image for project: 'C++ Driver'
  1. C++ Driver
  2. CXX-1258

Cursor iterators lose lockstep at cursor end

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • 3.2.0-rc0, 3.1.4
    • Affects Version/s: None
    • Component/s: Implementation
    • Labels:
      None

      When there are multiple iterators for a cursor, iterators should move in lockstep, meaning that incrementing any iterator is equivalent to incrementing all of them. This fails when an interator is incremented and there are no more documents. In that case, other iterators will not compare equal to cursor.end().

      Example code:

      #include <iostream>
      #include <string>
      
      #include <bsoncxx/builder/basic/document.hpp>
      #include <bsoncxx/json.hpp>
      #include <bsoncxx/stdx/string_view.hpp>
      #include <mongocxx/client.hpp>
      #include <mongocxx/instance.hpp>
      #include <mongocxx/uri.hpp>
      
      using bsoncxx::builder::basic::kvp;
      
      int main() {
          auto inst = mongocxx::instance{};
          auto client = mongocxx::client{mongocxx::uri{}};
          auto coll = client["test"]["foo"];
          coll.drop();
      
          for (auto n : {1, 2, 3, 4}) {
              auto doc = bsoncxx::builder::basic::document{};
              doc.append(kvp("x", n));
              coll.insert_one(doc.extract());
          }
      
          auto cursor = coll.find({});
          auto iter = cursor.begin();
      
          for (auto&& doc : cursor) {
              std::cout << bsoncxx::to_json(doc) << std::endl;
          }
      
          auto cond = iter == cursor.end() ? std::string("==") : std::string("!=");
          std::cout << "iter " << cond << " cursor.end()" << std::endl;
      
          return EXIT_SUCCESS;
      }
      
      { "_id" : { "$oid" : "58cab1205a4e4090514b7822" }, "x" : 1 }
      { "_id" : { "$oid" : "58cab1205a4e4090514b7823" }, "x" : 2 }
      { "_id" : { "$oid" : "58cab1205a4e4090514b7824" }, "x" : 3 }
      { "_id" : { "$oid" : "58cab1205a4e4090514b7825" }, "x" : 4 }
      iter != cursor.end()
      

      The current way that iterators are marked "at the end" is by setting their _cursor member to nullptr. This means that a cursor that doesn't yet know that it's at the end won't compare equal to the cursor.end() iterator with a nullptr _cursor.

      Iterator equality comparison needs to be enhanced so that comparing a nullptr _cursor with a non-null _cursor has some additional way to see if _cursor has actually been exhausted.

            Assignee:
            david.golden@mongodb.com David Golden
            Reporter:
            david.golden@mongodb.com David Golden
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: