/*

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__PAGE_ACCESSOR_HPP_ )
#define _OESS_1__DB__STORAGE__IMPL__PAGE_ACCESSOR_HPP_

#include <memory>

#include <cpp_util_2/h/nocopy.hpp>

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

#include <oess_1/file/h/file.hpp>

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

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

namespace oess_1 {

namespace db {

namespace storage {

namespace impl {

//
// page_accessor_t
//

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

	Штатная реализация std_chain_storage_t владеет объектами кэша и
	основного файла хранилища. Но для выполнения своих операций делегирует
	некоторые действия вспомогательным объектам. Например, интерфейсу
	header_processor_t. А этим вспомогательным объектам требуется доступ
	к страницам хранилища. При этом вспомогательные объекты не должны
	ничего знать ни про кэш, ни про хранилище грязных страниц, ни про
	механизмы извлечения страниц из файла. Для этого вспомогательным
	объектам будет передаваться интерфейс page_accessor_t, реализация которого
	знает обо всех этих деталях.

	Для создания штатной реализации page_accessor_t необходимо использовать
	функцию create_std_page_accessor().

	\attention Указатели, возвращаемые методами read_access(),
		write_access() действительны только до следующего обращения
		к методам *_access и только во время жизни этого объекта
		accessor-а.
*/
class	page_accessor_t
	:	private cpp_util_2::nocopy_t
	{
	public :
		virtual ~page_accessor_t();

		//! Проверить наличие страницы в основном файле.
		/*!
			Если страницы нет в основном файле, то доступ к ее
			содержимому можно получить только через метод
			write_access().

			\return true, если страница в основном файле существует.
		*/
		virtual bool
		is_exists( oess_1::uint_t page ) = 0;

		//! Получить доступ к странице для чтения.
		/*!
			\throw oess_1::logic_ex_t, если страницы в основном файле не
				существует.
		*/
		virtual const oess_1::char_t *
		read_access( oess_1::uint_t page ) = 0;

		//! Получить доступ к странице для записи.
		/*!
			Если страницы в основном файле не существовало, то она создается.
			После этого страница будет считаться существующей, но ее значение
			будет присутствовать только в кэше (либо в хранилище грязных
			страниц) до фиксации транзакции.

			\throw oess_1::logic_ex_t, если режим работы хранилища не
				допускает изменения страниц хранилища (например, хранилище
				открыто в режиме read-only или нет начатых транзакций).
		*/
		virtual oess_1::char_t *
		write_access( oess_1::uint_t page ) = 0;
	};

//
// create_std_page_accessor
//

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

	\return указатель на динамически созданный объект, ответственность
		за уничтожение которого лежит на вызывающей стороне.
*/
std::auto_ptr< page_accessor_t >
create_std_page_accessor(
	//! Конфигурация для хранилища.
	const config_t & config,
	//! Основной файл БД.
	oess_1::file::file_t & main_file,
	//! Логическая длина основного файла. Будет изменяться по мере
	//! создания новых страниц.
	oess_1::uint_t & main_file_logic_length,
	//! Кэш хранилища.
	cache_t & cache,
	//! Хранилище грязных страниц.
	dirty_page_storage_t & dirty_pages,
	//! true, если допускается только чтение страниц хранилища.
	bool is_read_only );

} /* namespace impl */

} /* namespace storage */

} /* namespace db */

} /* namespace oess_1 */

#endif

