/*

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.

*/

/*!
	\file
	\since v.1.4.0
	\brief Интерфейс кэша основного файла хранилища.
*/
#if !defined( _OESS_1__DB__STORAGE__IMPL__CACHE_HPP_ )
#define _OESS_1__DB__STORAGE__IMPL__CACHE_HPP_

#include <memory>

#include <cpp_util_2/h/nocopy.hpp>

#include <oess_1/db/storage/h/loaded_page.hpp>
#include <oess_1/db/storage/h/dirty_page_storage.hpp>

namespace oess_1 {

namespace db {

namespace storage {

namespace impl {

/*!
	\since v.1.4.0
	\brief Интерфейс кэша основного файла хранилища.
*/
class	cache_t
	:	private cpp_util_2::nocopy_t
	{
	public :
		virtual ~cache_t();

		/*!
			Инициализация и переинициализация кэша.
		*/
		virtual void
		reinit(
			//! Количество страниц, которые могут одновременно
			//! находиться в кэше.
			oess_1::uint_t cache_size,
			//! Размер одной страницы в байтах.
			oess_1::uint_t page_size ) = 0;

		/*!
			Очиска содержимого кэша и переход в неинициализированное
			состояние.

			Для работы с таким кэшем необходимо заново вызвать
			метод reinit().
		*/
		virtual void
		cleanup() = 0;

		/*!
			Получить содержимое страницы для чтения.

			\return 0, если страницы в кэше нет.
		*/
		virtual const oess_1::char_t *
		read_access(
			//! Порядковый номер страницы в основном файле.
			oess_1::uint_t ordinal ) = 0;

		/*!
			Получить содержимое страницы для изменения.

			Страница помечается как грязная.

			\return 0, если страницы в кэше нет.
		*/
		virtual oess_1::char_t *
		write_access(
			//! Порядковый номер страницы в основном файле.
			oess_1::uint_t ordinal ) = 0;

		/*!
			Поместить страницу в кэш.

			Если у страницы нет предыдущего значения, то она сразу
			помечается как грязная.

			Если свободных элементов в кэше нет, и вытесняется
			грязная страница, то она вытесняется в
			хранилище \a storage.
		*/
		virtual oess_1::char_t *
		push(
			//! Значение загруженной страницы.
			const ref_loaded_page_t & page,
			//! Приемник для вытесняемой грязной страницы.
			dirty_page_storage_t & storage,
			//! Признак того, что первый раз страница будет
			//! использоваться для чтения.
			bool is_read_only_access ) = 0;

		/*!
			Скопировать все грязные страницы в указанное
			хранилище грязных страниц.

			Должна вызываться в конце транзакции для того, чтобы
			собрать все грязные страницы в одном месте.

			Грязные страницы остаются в кэше. Признак того, что
			они грязные, не сбрасывается.
		*/
		virtual void
		copy_all_dirties(
			dirty_page_storage_t & storage ) = 0;

		/*!
			Очистить все грязные страницы.

			Вызывается после успешной фиксации транзакции.
			Для всех грязных страниц выставляется признак того,
			что они чистые. Текущее значение страницы становится
			исходным значением.
		*/
		virtual void
		clear_all_dirties() = 0;

		/*!
			Выбросить все грязные страницы из кэша.

			Вызывается после отката транзакции. Все грязные
			страницы выбрасываются, как будто они и не загружались.
		*/
		virtual void
		throw_away_all_dirties() = 0;
	};

/*!
	\since v.1.4.0

	Создать стандартную реализацию интерфейса cache_t.
*/
std::auto_ptr< cache_t >
create_std_cache();

} /* namespace impl */

} /* namespace storage */

} /* namespace db */

} /* namespace oess_1 */

#endif

