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

Cursor iterators lose lockstep at cursor end

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major - P3
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 3.2.0-rc0, 3.1.4
    • Component/s: Implementation
    • Labels:
      None
    • Story Points:
      1
    • Sprint:
      Perl/CXX 2017-03-24, Perl/CXX 2017-04-14

      Description

      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.

        Attachments

          Issue Links

            Activity

              People

              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: