SortedDataInterface* RocksEngine::getSortedDataInterface(OperationContext* opCtx, StringData ident, const IndexDescriptor* desc) { if (desc->unique()) { return new RocksUniqueIndex(_db.get(), _getIdentPrefix(ident), ident.toString(), Ordering::make(desc->keyPattern())); } else { return new RocksStandardIndex(_db.get(), _getIdentPrefix(ident), ident.toString(), Ordering::make(desc->keyPattern())); } }
RecordStore* RocksEngine::getRecordStore(OperationContext* opCtx, StringData ns, StringData ident, const CollectionOptions& options) { if (options.capped) { return new RocksRecordStore( ns, ident, _db.get(), _getIdentPrefix(ident), true, options.cappedSize ? options.cappedSize : 4096, // default size options.cappedMaxDocs ? options.cappedMaxDocs : -1); } else { return new RocksRecordStore(ns, ident, _db.get(), _getIdentPrefix(ident)); } }
Status RocksEngine::dropIdent(OperationContext* opCtx, StringData ident) { // TODO optimize this using CompactionFilterV2 rocksdb::WriteBatch wb; wb.Delete(kMetadataPrefix + ident.toString()); std::string prefix = _getIdentPrefix(ident); rocksdb::Slice prefixSlice(prefix.data(), prefix.size()); boost::scoped_ptr<rocksdb::Iterator> _iter(_db->NewIterator(rocksdb::ReadOptions())); for (_iter->Seek(prefixSlice); _iter->Valid() && _iter->key().starts_with(prefixSlice); _iter->Next()) { ROCKS_STATUS_OK(_iter->status()); wb.Delete(_iter->key()); } auto s = _db->Write(rocksdb::WriteOptions(), &wb); if (!s.ok()) { return toMongoStatus(s); } { boost::mutex::scoped_lock lk(_identPrefixMapMutex); _identPrefixMap.erase(ident); } return Status::OK(); }
SortedDataInterface* RocksEngine::getSortedDataInterface(OperationContext* opCtx, StringData ident, const IndexDescriptor* desc) { RocksIndexBase* index; if (desc->unique()) { index = new RocksUniqueIndex(_db.get(), _getIdentPrefix(ident), ident.toString(), Ordering::make(desc->keyPattern())); } else { index = new RocksStandardIndex(_db.get(), _getIdentPrefix(ident), ident.toString(), Ordering::make(desc->keyPattern())); } { boost::lock_guard<boost::mutex> lk(_identObjectMapMutex); _identIndexMap[ident] = index; } return index; }
RecordStore* RocksEngine::getRecordStore(OperationContext* opCtx, StringData ns, StringData ident, const CollectionOptions& options) { if (NamespaceString::oplog(ns)) { _oplogIdent = ident.toString(); } RocksRecordStore* recordStore = options.capped ? new RocksRecordStore( ns, ident, _db.get(), _counterManager.get(), _getIdentPrefix(ident), true, options.cappedSize ? options.cappedSize : 4096, // default size options.cappedMaxDocs ? options.cappedMaxDocs : -1) : new RocksRecordStore(ns, ident, _db.get(), _counterManager.get(), _getIdentPrefix(ident)); { boost::lock_guard<boost::mutex> lk(_identObjectMapMutex); _identCollectionMap[ident] = recordStore; } return recordStore; }
// cannot be rolled back Status RocksEngine::dropIdent(OperationContext* opCtx, StringData ident) { rocksdb::WriteBatch wb; wb.Delete(kMetadataPrefix + ident.toString()); // calculate which prefixes we need to drop std::vector<std::string> prefixesToDrop; prefixesToDrop.push_back(_getIdentPrefix(ident)); if (_oplogIdent == ident.toString()) { // if we're dropping oplog, we also need to drop keys from RocksOplogKeyTracker (they // are stored at prefix+1) prefixesToDrop.push_back(rocksGetNextPrefix(prefixesToDrop[0])); } // We record the fact that we're deleting this prefix. That way we ensure that the prefix is // always deleted for (const auto& prefix : prefixesToDrop) { wb.Put(kDroppedPrefix + prefix, ""); } // we need to make sure this is on disk before starting to delete data in compactions rocksdb::WriteOptions syncOptions; syncOptions.sync = true; auto s = _db->Write(syncOptions, &wb); if (!s.ok()) { return rocksToMongoStatus(s); } // remove from map { boost::lock_guard<boost::mutex> lk(_identPrefixMapMutex); _identPrefixMap.erase(ident); } // instruct compaction filter to start deleting { boost::lock_guard<boost::mutex> lk(_droppedPrefixesMutex); for (const auto& prefix : prefixesToDrop) { uint32_t int_prefix; bool ok = extractPrefix(prefix, &int_prefix); invariant(ok); _droppedPrefixes.insert(int_prefix); } } return Status::OK(); }