コード例 #1
0
ファイル: collection_map.cpp プロジェクト: 7segments/mongo
    // on input, _initLock is held, so this can be called by only one thread at a time,
    // also, on input, the CollectionMap must be allocated
    Collection *CollectionMap::open_ns(const StringData& ns, const bool bulkLoad) {
        verify(allocated());
        BSONObj serialized;
        BSONObj nsobj = BSON("ns" << ns);
        storage::Key sKey(nsobj, NULL);
        DBT ndbt = sKey.dbt();

        // If this transaction is read only, then we cannot possible already
        // hold a lock in the metadb and we certainly don't need to hold one
        // for the duration of this operation. So we use an alternate txn stack.
        const bool needAltTxn = !cc().hasTxn() || cc().txn().readOnly();
        scoped_ptr<Client::AlternateTransactionStack> altStack(!needAltTxn ? NULL :
                                                               new Client::AlternateTransactionStack());
        scoped_ptr<Client::Transaction> altTxn(!needAltTxn ? NULL :
                                               new Client::Transaction(0));

        // Pass flags that get us a write lock on the metadb row
        // for the ns we'd like to open.
        DB *db = _metadb->db();
        const int r = db->getf_set(db, cc().txn().db_txn(), DB_SERIALIZABLE | DB_RMW,
                                   &ndbt, getf_serialized, &serialized);
        if (r == 0) {
            // We found an entry for this ns and we have the row lock.
            // First check if someone got the lock before us and already
            // did the open.
            Collection *cl = find_ns(ns);
            if (cl != NULL) {
                return cl;
            }
            // No need to hold the openRWLock during Collection::make(),
            // the fact that we have the row lock ensures only one thread will
            // be here for a particular ns at a time.
            shared_ptr<Collection> details = Collection::make( serialized, bulkLoad );
            SimpleRWLock::Exclusive lk(_openRWLock);
            verify(!_collections[ns]);
            _collections[ns] = details;
            return details.get();
        } else if (r != DB_NOTFOUND) {
            storage::handle_ydb_error(r);
        }
        return NULL;
    }
コード例 #2
0
ファイル: dictionary.cpp プロジェクト: aberg001/mongo
        void Dictionary::open(const BSONObj &info,
                              const mongo::Descriptor &descriptor, const bool may_create,
                              const bool hot_index) {
            int readPageSize = 65536;
            int pageSize = 4 * 1024 * 1024;
            TOKU_COMPRESSION_METHOD compression = TOKU_ZLIB_WITHOUT_CHECKSUM_METHOD;
            BSONObj key_pattern = info["key"].Obj();
            
            BSONElement e;
            e = info["readPageSize"];
            if (e.ok() && !e.isNull()) {
                readPageSize = BytesQuantity<int>(e);
                uassert(16743, "readPageSize must be a number > 0.", readPageSize > 0);
                TOKULOG(1) << "db " << _dname << ", using read page size " << readPageSize << endl;
            }
            e = info["pageSize"];
            if (e.ok() && !e.isNull()) {
                pageSize = BytesQuantity<int>(e);
                uassert(16445, "pageSize must be a number > 0.", pageSize > 0);
                TOKULOG(1) << "db " << _dname << ", using page size " << pageSize << endl;
            }
            e = info["compression"];
            if (e.ok() && !e.isNull()) {
                std::string str = e.String();
                if (str == "lzma") {
                    compression = TOKU_LZMA_METHOD;
                } else if (str == "quicklz") {
                    compression = TOKU_QUICKLZ_METHOD;
                } else if (str == "zlib") {
                    compression = TOKU_ZLIB_WITHOUT_CHECKSUM_METHOD;
                } else if (str == "none") {
                    compression = TOKU_NO_COMPRESSION;
                } else {
                    uassert(16442, "compression must be one of: lzma, quicklz, zlib, none.", false);
                }
                TOKULOG(1) << "db " << _dname << ", using compression method \"" << str << "\"" << endl;
            }

            int r = _db->set_readpagesize(_db, readPageSize);
            if (r != 0) {
                handle_ydb_error(r);
            }

            r = _db->set_pagesize(_db, pageSize);
            if (r != 0) {
                handle_ydb_error(r);
            }

            r = _db->set_compression_method(_db, compression);
            if (r != 0) {
                handle_ydb_error(r);
            }

            // If this is a non-creating open for a read-only (or non-existent)
            // transaction, we can use an alternate stack since there's nothing
            // to roll back and no locktree locks to hold.
            const bool needAltTxn = !may_create && (!cc().hasTxn() || cc().txn().readOnly());
            scoped_ptr<Client::AlternateTransactionStack> altStack(!needAltTxn ? NULL :
                                                                   new Client::AlternateTransactionStack());
            scoped_ptr<Client::Transaction> altTxn(!needAltTxn ? NULL :
                                                   new Client::Transaction(0));

            const int db_flags = may_create ? DB_CREATE : 0;
            r = _db->open(_db, cc().txn().db_txn(), _dname.c_str(), NULL,
                          DB_BTREE, db_flags, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
            if (r == ENOENT && !may_create) {
                throw NeedsCreate();
            }
            if (r != 0) {
                handle_ydb_error(r);
            }
            if (may_create) {
                set_db_descriptor(_db, descriptor, hot_index);
            }
            verify_or_upgrade_db_descriptor(_db, descriptor, hot_index);

            if (altTxn.get() != NULL) {
                altTxn->commit();
            }
        }