///###////////////////////////////////////////////////////////////////////////
//
// Burton Computer Corporation
// http://www.burton-computer.com
// http://www.cooldevtools.com
// $Id: DatabaseConfig.cc 272 2007-01-06 19:37:27Z brian $
//
// Copyright (C) 2007 Burton Computer Corporation
// ALL RIGHTS RESERVED
//
// This program is open source software; you can redistribute it
// and/or modify it under the terms of the Q Public License (QPL)
// version 1.0. Use of this software in whole or in part, including
// linking it (modified or unmodified) into other programs is
// subject to the terms of the QPL.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// Q Public License for more details.
//
// You should have received a copy of the Q Public License
// along with this program; see the file LICENSE.txt. If not, visit
// the Burton Computer Corporation or CoolDevTools web site
// QPL pages at:
//
// http://www.burton-computer.com/qpl.html
// http://www.cooldevtools.com/qpl.html
//
#include <stdexcept>
#include "File.h"
#include "WordData.h"
#include "FrequencyDBImpl.h"
#include "FrequencyDBImpl_split.h"
#include "FrequencyDBImpl_hash.h"
#include "FrequencyDBImpl_cache.h"
#include "FrequencyDBImpl_dual.h"
#include "FrequencyDBImpl_dbm.h"
#include "FrequencyDBImpl_bdb.h"
#include "FrequencyDBImpl_pbl.h"
#include "FrequencyDBImpl_null.h"
#include "DatabaseConfig.h"
struct DBType {
const string prefix;
const char *suffix;
FrequencyDBImplFactory factory;
};
static DBType DBTYPES[] = {
#ifdef USE_MMAP
{ "split", 0, FrequencyDBImpl_split::factory },
{ "hash", FrequencyDBImpl_hash::SEARCH_SUFFIX, FrequencyDBImpl_hash::factory },
#endif
#ifdef USE_PBL
{ "pbl", FrequencyDBImpl_pbl::SEARCH_SUFFIX, FrequencyDBImpl_pbl::factory },
#endif
#ifdef USE_DB
{ "bdb", 0, FrequencyDBImpl_bdb::factory },
#endif
#ifdef USE_DBM
{ "gdbm", 0, FrequencyDBImpl_dbm::factory },
#endif
#ifdef USE_PBL
{ "", FrequencyDBImpl_pbl::SEARCH_SUFFIX, FrequencyDBImpl_pbl::factory },
#endif
#ifdef USE_DB
{ "", 0, FrequencyDBImpl_bdb::factory },
#endif
#ifdef USE_DBM
{ "", 0, FrequencyDBImpl_dbm::factory },
#endif
#ifdef USE_MMAP
{ "", FrequencyDBImpl_hash::SEARCH_SUFFIX, FrequencyDBImpl_hash::factory },
#endif
{ "", 0 }
};
DatabaseConfig::DatabaseConfig()
: m_targetSizeMB(32),
m_maxCacheTerms(15000)
{
File basedir(File::getHomeDir(), ".spamprobe");
File sp_dir(basedir, "sp_words");
m_privateFilename = sp_dir.getPath();
}
DatabaseConfig::~DatabaseConfig()
{
}
void DatabaseConfig::parseCommandLineArg(string &arg,
string &database_type,
int &target_size_mb)
{
database_type = "";
target_size_mb = m_targetSizeMB;
string::size_type first_colon = arg.find(":");
if (first_colon == string::npos) {
return;
}
database_type = arg.substr(0, first_colon);
string::size_type last_colon = arg.find(":", first_colon + 1);
if (last_colon == string::npos) {
arg.erase(0, first_colon + 1);
} else {
target_size_mb = atoi(arg.substr(first_colon + 1, last_colon - first_colon - 1).c_str());
arg.erase(0, last_colon + 1);
}
}
OWNED FrequencyDBImpl *DatabaseConfig::createDatabaseImpl(bool read_only) const
{
string private_filename(m_privateFilename);
Ptr<FrequencyDBImpl> private_db(createDatabaseImplUsingBestFit(m_databaseType, private_filename));
Ptr<FrequencyDBImpl> db;
if (m_sharedFilename.length() == 0) {
db.set(private_db.release());
} else {
string shared_filename(m_sharedFilename);
Ptr<FrequencyDBImpl> shared_db(createDatabaseImplUsingBestFit("", shared_filename));
db.set(new FrequencyDBImpl_dual(shared_db.release(), private_db.release(), shared_filename));
}
if (m_maxCacheTerms > 0) {
db.set(new FrequencyDBImpl_cache(db.release(), m_maxCacheTerms));
}
return db->open(private_filename, read_only, FrequencyDBImpl::PRIVATE_DB_MODE) ? db.release() : 0;
}
OWNED FrequencyDBImpl *DatabaseConfig::createDatabaseImplUsingBestFit(const string &type,
string &filename) const
{
Ptr<FrequencyDBImpl> db;
if (db.isNull() && type.length() > 0) {
db.set(createDatabaseImplForType(type, filename));
}
if (db.isNull()) {
db.set(createDatabaseImplUsingExistingFile(filename));
}
if (db.isNull()) {
db.set(createDatabaseImplUsingDefaultType(filename));
}
if (db.isNull()) {
throw runtime_error(string("no database type known for filename: ") + filename);
}
return db.release();
}
OWNED FrequencyDBImpl *DatabaseConfig::createDatabaseImplForType(const string &type,
string &filename) const
{
File search_file(filename);
for (DBType *dbt = DBTYPES; dbt->factory; ++dbt) {
if (dbt->prefix == type) {
if (dbt->suffix) {
search_file.setSuffix(dbt->suffix);
}
if (is_debug) {
cerr << "USING REQUESTED DATABASE TYPE '" << dbt->prefix << "' PATH " << search_file.getPath() << endl;
}
filename = search_file.getPath();
return (dbt->factory)(this);
}
}
return 0;
}
OWNED FrequencyDBImpl *DatabaseConfig::createDatabaseImplUsingDefaultType(string &filename) const
{
return createDatabaseImplForType("", filename);
}
OWNED FrequencyDBImpl *DatabaseConfig::createDatabaseImplUsingExistingFile(string &filename) const
{
File search_file(filename);
for (DBType *dbt = DBTYPES; dbt->factory; ++dbt) {
if (dbt->suffix) {
search_file.setSuffix(dbt->suffix);
if (search_file.isFile()) {
if (is_debug) {
cerr << "USING DISCOVERED DATABASE TYPE '" << dbt->prefix << "' PATH " << search_file.getPath() << endl;
}
filename = search_file.getPath();
return (dbt->factory)(this);
}
}
}
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1