void IndexFactory::dropIndex(const listAlgorithmsTypePtr& algs, const std::set<std::string>& keys) { IndexAlgorithm* result = NULL; for (listAlgorithmsType::iterator i = algs->begin(); i != algs->end(); i++) { IndexAlgorithm* impl = *i; std::set<std::string> implKeys = impl->keys(); std::set<std::string>::const_iterator iKeys = keys.begin(); std::set<std::string>::const_iterator implItKeys = implKeys.begin(); while (true) { if ((iKeys != keys.end()) && (implItKeys != implKeys.end())) { std::string key1 = *iKeys; std::string key2 = *implItKeys; if (key1.compare(key2) != 0) { break; } iKeys++; implItKeys++; // get to the end of both sides and all the keys are equal if ((iKeys == keys.end()) && (implItKeys == implKeys.end())) { algs->erase(i); delete impl; break; } } } } }
void DBController::remove(const char* db, const char* ns, const char* documentId, const char* revision, const BSONObj* options) { if (_logger->isDebug()) _logger->debug(2, "DBController::update db: %s, ns: %s, documentId: %s, revision: %s", db, ns, documentId, revision); StreamType* streamData = StreamManager::getStreamManager()->open(db, ns, DATA_FTYPE); IndexAlgorithm* impl = IndexFactory::indexFactory.index(db, ns, "_id"); BSONObj indexBSON; indexBSON.add("_id", documentId); Index* index = impl->find(&indexBSON); if (index != NULL) { // TODO check the revision id StreamType* out = StreamManager::getStreamManager()->open(db, ns, DATA_FTYPE); out->flush(); long currentPos = out->currentPos(); out->seek(index->posData); BSONObj* obj = readBSON(out); obj->add("_status", 2); // DELETED // Get back to the record start out->seek(index->posData); writeBSON(out, obj); // restores the last position out->seek(currentPos); //std::string id = obj->getDJString("_id"); //CacheManager::objectCache()->remove(id); delete obj; } }
void DBController::updateIndex(const char* db, const char* ns, BSONObj* bson, long filePos) { BSONObj indexBSON; djondb::string id = bson->getDJString("_id"); indexBSON.add("_id", (char*)id); IndexAlgorithm* impl = IndexFactory::indexFactory.index(db, ns, "_id"); impl->update(indexBSON, id, filePos); }
Index* DBController::findIndex(const char* db, const char* ns, BSONObj* bson) { IndexAlgorithm* impl = IndexFactory::indexFactory.index(db, ns, "_id"); BSONObj indexBSON; indexBSON.add("_id", (const char*)bson->getDJString("_id")); Index* index = impl->find(&indexBSON); return index; }
BSONArrayObj* DBController::find(const char* db, const char* ns, const char* select, const char* filter, const BSONObj* options) throw(ParseException) { if (_logger->isDebug()) _logger->debug(2, "DBController::find db: %s, ns: %s, select: %s, filter: %s", db, ns, select, filter); BSONArrayObj* result; FilterParser* parser = FilterParser::parse(filter); std::set<std::string> tokens = parser->tokens(); if (IndexFactory::indexFactory.containsIndex(db, ns, tokens)) { IndexAlgorithm* impl = IndexFactory::indexFactory.index(db, ns, tokens); std::list<Index*> elements = impl->find(parser); std::string filedir = _dataDir + db; filedir = filedir + FILESEPARATOR; std::stringstream ss; ss << filedir << ns << ".dat"; std::string filename = ss.str(); result = new BSONArrayObj(); FileInputStream* fis = new FileInputStream(filename.c_str(), "rb"); DBFileInputStream* dbStream = new DBFileInputStream(fis); BSONInputStream* bis = new BSONInputStream(dbStream); for (std::list<Index*>::iterator it = elements.begin(); it != elements.end(); it++) { Index* index = *it; long posData = index->posData; dbStream->seek(posData); BSONObj* obj = bis->readBSON(select); result->add(*obj); delete obj; } delete bis; delete dbStream; } else { result = findFullScan(db, ns, select, parser, options); } delete parser; return result; }
IndexAlgorithm* IndexFactory::index(const char* db, const char* ns, const std::set<std::string>& keys) { listAlgorithmsTypePtr algorithms = findAlgorithms(db, ns); IndexAlgorithm* indexImpl = findIndex(algorithms, keys); if (indexImpl == NULL) { int len = strlen(db) + strlen(ns) + strlen(".ixp") + 20; char* indexFileName = (char*)malloc(len); memset(indexFileName, 0, len); sprintf(indexFileName, "%s/%s.ixp", db, ns), //indexImpl = new BPlusIndex(keys); indexImpl = new BPlusIndexP(indexFileName); indexImpl->setKeys(keys); algorithms->push_back(indexImpl); free(indexFileName); } return indexImpl; }
IndexAlgorithm* IndexFactory::findIndex(const listAlgorithmsTypePtr& algs, const std::set<std::string>& keys) { IndexAlgorithm* result = NULL; for (listAlgorithmsType::const_iterator i = algs->begin(); i != algs->end(); i++) { IndexAlgorithm* impl = *i; std::set<std::string> implKeys = impl->keys(); std::set<std::string>::const_iterator iKeys = keys.begin(); std::set<std::string>::const_iterator implItKeys = implKeys.begin(); bool found = true; while (true) { if ((iKeys != keys.end()) && (implItKeys != implKeys.end())) { std::string key1 = *iKeys; std::string key2 = *implItKeys; if (key1.compare(key2) != 0) { found = false; break; } iKeys++; implItKeys++; // get to the end of both sides and all the keys are equal if ((iKeys == keys.end()) && (implItKeys == implKeys.end())) { break; } } else { found = false; break; } } // If all the keys match the implementation keys then this is an exact index if (found) { result = impl; break; } } return result; }