ClickHouse/dbms/include/DB/DataStreams/IBlockInputStream.h
2014-02-23 06:41:02 +04:00

107 lines
4.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <boost/noncopyable.hpp>
#include <Poco/SharedPtr.h>
#include <DB/Core/Block.h>
#include <DB/Storages/StoragePtr.h>
namespace DB
{
using Poco::SharedPtr;
/** Коллбэк для отслеживания прогресса выполнения запроса.
* Используется в IProfilingBlockInputStream и Context-е.
* Функция принимает количество строк в последнем блоке, количество байт в последнем блоке.
* Следует иметь ввиду, что колбэк может вызываться из разных потоков.
*/
typedef boost::function<void(size_t, size_t)> ProgressCallback;
/** Интерфейс потока для чтения данных по блокам из БД.
* Реляционные операции предполагается делать также реализациями этого интерфейса.
*/
class IBlockInputStream : private boost::noncopyable
{
public:
typedef SharedPtr<IBlockInputStream> BlockInputStreamPtr;
typedef std::vector<BlockInputStreamPtr> BlockInputStreams;
/** Листовой BlockInputStream обычно требует, чтобы был жив какой-то Storage.
* Переданный сюда указатель на Storage будет просто храниться в этом экземпляре,
* не позволяя уничтожить Storage раньше этого BlockInputStream.
*/
IBlockInputStream(StoragePtr owned_storage_ = StoragePtr()) : owned_storage(owned_storage_) {}
/** Прочитать следующий блок.
* Если блоков больше нет - вернуть пустой блок (для которого operator bool возвращает false).
*/
virtual Block read() = 0;
/** Прочитать что-нибудь перед началом всех данных или после конца всех данных.
* В функции readSuffix можно реализовать финализацию, которая может привести к исключению.
* readPrefix() должна вызываться до первого вызова read().
* readSuffix() должна вызываться после того, как read() вернула пустой блок, или после вызова cancel(), но не во время выполнения read().
*/
virtual void readPrefix() {}
virtual void readSuffix() {}
virtual ~IBlockInputStream() {}
/** Для вывода дерева преобразований потока данных (плана выполнения запроса).
*/
virtual String getName() const = 0;
virtual String getShortName() const; /// То же самое, но без BlockInputStream на конце.
/** Уникальный идентификатор части конвейера выполнения запроса.
* Источники с одинаковым идентификатором считаются идентичными
* (выдающими одинаковые данные), и могут быть заменены на один источник
* при одновременном выполнении сразу нескольких запросов.
* Если источник нельзя склеивать ни с каким другим - верните в качестве идентификатора адрес объекта.
*/
virtual String getID() const = 0;
BlockInputStreams & getChildren() { return children; }
void dumpTree(std::ostream & ostr, size_t indent = 0, size_t multiplier = 1);
void dumpTreeWithProfile(std::ostream & ostr, size_t indent = 0);
/// Получить листовые источники (не считая этот).
BlockInputStreams getLeaves();
/// Получить количество строк и байт, прочитанных в листовых источниках.
void getLeafRowsBytes(size_t & rows, size_t & bytes);
/** Проверить глубину конвейера.
* Если задано max_depth и глубина больше - кинуть исключение.
*/
size_t checkDepth(size_t max_depth) const;
void setOwnedStorage(StoragePtr & owned_storage_) { owned_storage = owned_storage_; }
protected:
StoragePtr owned_storage;
BlockInputStreams children;
private:
void getLeavesImpl(BlockInputStreams & res, BlockInputStreamPtr this_shared_ptr = NULL);
size_t checkDepthImpl(size_t max_depth, size_t level) const;
/** Получить текст, который идентифицирует этот источник и всё поддерево.
* В отличие от getID - без учёта параметров.
*/
String getTreeID() const;
};
typedef IBlockInputStream::BlockInputStreamPtr BlockInputStreamPtr;
typedef IBlockInputStream::BlockInputStreams BlockInputStreams;
}