/*

Copyright (c) 2002-2005, Yauheni Akhotnikau
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

- Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

- The name of the author may not be used to endorse or promote products derived
from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.

*/

/*!
	\since v.1.4.0
	\file
	\brief Интерфейс объекта, отвечающего за работу с заголовками
		различных областей основного файла хранилища.
*/

#if !defined( _OESS_1__DB__STORAGE__IMPL__HEADER_PROCESSOR_HPP_ )
#define _OESS_1__DB__STORAGE__IMPL__HEADER_PROCESSOR_HPP_

#include <memory>

#include <cpp_util_2/h/nocopy.hpp>

#include <oess_1/defs/h/types.hpp>

#include <oess_1/db/storage/h/chain_storage.hpp>

#include <oess_1/db/storage/impl/h/page_accessor.hpp>

namespace oess_1 {

namespace db {

namespace storage {

namespace impl {

//
// header_processor_t
//

/*!
	\since v.1.4.0
	\brief Интерфейс объекта, отвечающего за работу с заголовками
		различных областей основного файла хранилища.

	Основной файл имеет строгую логическую структуру -- он разбит на
	сегменты и сектора. Сам файл, каждый из сегментов и каждый из
	секторов имеет заголовки -- страницы основного файла, которые
	содержат информацию у свободных участках файла в соответствующей
	области (сегменте или секторе). Заголовки секторов так же
	хранят информацию о цепочках блоков (т.е. какой блок идет следующим
	за определенным блоком).

	За создание и удаление цепочек в основном файле хранилища отвечает
	std_chain_storage_t. Но такую часть своей работы, как работу с
	заголовками логических областей внутри файла, он делегирует
	вспомогательному объекту, реализующему данный интерфейс.

	После завершения какой-либо операции (создания, загрузки,
	удаления, обновления объекта) \b необходимо
	вызвать метод operation_finished() для фиксации изменившихся заголовков
	на страницах хранилища (если были сделаны изменения) и для уменьшения
	объема занимаемой памяти (т.к. для повышения эффективности все
	десериализованные в процессе выполнения операции заголовки сохраняются
	в ОП).

	Для создания штатной реализации header_processor_t необходимо
	использовать функцию create_std_header_processor().
*/
class	header_processor_t
	:	private cpp_util_2::nocopy_t
	{
	public :
		virtual ~header_processor_t();

		//! Выделить новый блок.
		/*!
			Для нового блока ссылка на следующий блок выставляется
			в invalid_chain_id.
		*/
		virtual chain_id_t
		allocate_block() = 0;

		//! Сделать блок свободным.
		virtual void
		deallocate_block(
			//! Идентификатор освобождаемого блока.
			const chain_id_t & block ) = 0;

		//! Получить ссылку на следующий блок из указанного блока.
		virtual chain_id_t
		get_next(
			//! Этот блок должен существовать.
			const chain_id_t & block ) = 0;

		//! Установить ссылку на следующий блок для указаного блока.
		virtual void
		change_next(
			//! Этот блок должен существовать.
			const chain_id_t & block,
			//! Предполагается, что этот блок так же существует.
			const chain_id_t & next ) = 0;

		//! Зафиксировать все внесенные изменения в хранилище и уменьшить
		//! расход памяти.
		virtual void
		operation_finished(
			//! true, если выполнялась read-only операция (например,
			//! загрузка объекта в ОП).
			bool is_read_only = false ) = 0;
	};

//
// create_std_header_processor
//

/*!
	\since v.1.4.0
	\brief Создать штатную реализацию интерфейса %header_processor_t.

	\return указатель на динамически созданный объект, ответственность
		за уничтожение которого лежит на вызывающей стороне.
*/
std::auto_ptr< header_processor_t >
create_std_header_processor(
	//! Конфигурация для хранилища.
	const config_t & config,
	//! Объект для доступа к страницам хранилища.
	page_accessor_t & accessor,
	//! true, если объект должен создаваться только для чтения.
	bool is_read_only );

} /* namespace impl */

} /* namespace storage */

} /* namespace db */

} /* namespace oess_1 */

#endif


