Работа с базой данных: стратегии

/* Стандартная стратегия для работы с типами в базе данных. Применима для простых типов (не содержащих указателей и сложной логики инициализации).*/

template<typename T>

class StdStrategy {

public:

 

/* Возвращает размер данных. */

static size_t size(const T& key) { return sizeof(key); }

 

/* Возвращает данные в виде константного указателя void*. Размер определется вызовом метода size(). */

static const void* data(const T& key) { return &key; }

     

/* Копирует данные из void* в переменную типа, с которым работает стратегия. */

static void put(T& d, const void* v, size_t size) {

       assert(sizeof(d) <= size);

       const T c = *(static_cast<const T*>(v));

       d = c;

}

 

};

 

/* Спецификация стандартной стратегии для класса STL-строк. */

template<>

class StdStrategy<std::string> {

public:

static size_t size(const std::string& key) {

       return key.length();

}

 

static const void* data(const std::string& key) {

       return key.c_str();

}

     

static void put(std::string& s, const void* v, size_t size) {

       s = std::string(static_cast<const char*>(v), size);       

}

};

 

 



Работа с базой данных: контроллер.

 

/* Шаблон контроллера базы данных. Детали реализации опущены для экономии места, представлен только интерфейс.*/

template<

typename KeyType,

typename DataType,

template <typename> class KeyStrategy = StdStrategy,

template <typename> class DataStrategy = StdStrategy      

>

class DBController {

public:

 

typedef KeyType Key;

typedef DataType Data;

 

/* Конструктор. Принимает имя файла базы данных. Если такого файла нет, он будет создан. */

DBController(const std::string& dbname) {... }

 

/* Деструктор. Корректно закрывает базу данных. */

~DBController() {... }

 

/* Возвращает данные по ключу. Выбрасывает исключение, если такого ключа нет в БД. */

Data get(const Key& key) {... }

 

/* Записывает пару ключ/значение в БД. Если такой ключ уже существует, старое его значение будет утрачено. */

void put(const Key& key, const Data& data) {... }

 

/* Проверяет, существует ли ключ в базе данных. */

bool exists(const Key& key) {... }

 

/* Делает проход по всей базе данных и вызывает oper(key, value) для каждой пары ключ/значение. Тип Т должен быть пригоден для этой цели, иначе возникнет ошибка компиляции. */

template<typename T> void foreach(T& oper) {... }

 

/* Очищает базу данных, удаляя все имеющиеся в ней пары ключ/значение. */

void truncate() {

       impl_->truncate();

}

 

private:

/*... */

};

 

Множество пакетов.

 

/* Интерфейс, описывающий множество пакетов. */

class Set {

public:

 

/* Вернуть пакет по локальному номеру. */

virtual Packet at(SET_INDEX index) const = 0;

 

/* Получить размер множества. */

virtual SIZE size() const = 0;

 

virtual ~Set() {}

};

 

Правило.

 

// Интерфейс правила

class Rule {

public:

 

/* Тип итератора для доступа к подмножествам. SET_INDEX - это псевдоним типа uint32_t */

typedef std::vector<SET_INDEX>::iterator Iterator;

     

/* Клонирование правила */

virtual Rule* clone() const = 0;

 

/* Применение правила к переданному множеству. Все остальные методы, которые имеют дело с "текущим делением", не должны вызываться раньше этого. */

virtual SIZE compute(const std::auto_ptr<Set> subset) = 0;

 

/* Возвращает разницу в весе частей текущего деления. */

virtual SIZE getDiff() const = 0;

 

/* Возвращают левое и правое дочернее правило для текущего деления. */

virtual Rule* getLeftRule() const = 0;

virtual Rule* getRightRule() const = 0;

 

/* Возвращает "истину", если правило прошло (см. описание архитектуры генератора). */

virtual bool isPassed() const = 0;

 

/* Вовзращает "истину", если текущее деление невырожденное. */

virtual bool isDivided() const = 0;

 

/* Работа с флагом активности правила. */

virtual bool isActive() const = 0;

virtual void setActive(bool active) = 0;

     

/* Возвращает текущее деление в текстовом виде, пригодном для использования в командах iptables. */

virtual std::string printRule() const = 0;

 

/* Возвращают итераторы на начало и конец левого и правого подмножества текущего деления. */

virtual Iterator leftBegin() const = 0;

virtual Iterator leftEnd() const = 0;

virtual Iterator rightBegin() const = 0;

virtual Iterator rightEnd() const = 0;

 

virtual ~Rule() {}

};



Приложение Б.

(обязательное)

Файл описания диапазонов адресов.

 

Файл описания диапазонов адресов состоит из записей, разделенные пробельными символами. Записи могут быть двух видов:

1. строка «source» или «dest». Обозначает, что все последующие за этой строкой записи (пока не встретится противоположная строка, либо конец файла) относятся к адресам отправителя или получателя соответственно. Для этих двух параметров можно задать разные наборы диапазонов.

2. Все, что не является «source» или «dest», трактуется как пары «диапазон адресов» и «маска диапазона». Оба этих поля также могут быть разделены любыми пробельными символами. Они имеют стандартный формат записи адресов в виде четырех чисел от 0 до 255, разделенных точками (маска тоже записывается таким образом, нотация CIDR не поддерживается). Важна очередность задания параметров, поскольку именно с помощью нее система отличает диапазон от маски. Диапазон может идти вслед за флагом «source/dest», либо вслед за маской. Маска должна идти вслед за диапазоном. Флаг «source/dest» не может идти вслед за диапазоном (так как ожидается маска) — этот случай система отлавливает и сообщает об ошибке.

 

Пример.

source

10.3.0.0      255.255.0.0

193.124.208.0 255.255.255.0

dest

10.4.16.0     255.255.255.0

193.124.208.0 255.255.255.0

source

10.168.131.0  255.255.255.0

 

 


[1] Класс, не хранящий данных, все методы которого — чисто виртуальные.

[2]  Имя файла с нужным журналом зависит от настроек демона syslogd. Обычно это /var/log/kern.log.





double arrow
Сейчас читают про: