예제 #1
0
ColumnPtr ColumnArray::filterGeneric(const Filter & filt, ssize_t result_size_hint) const
{
	size_t size = getOffsets().size();
	if (size != filt.size())
		throw Exception("Size of filter doesn't match size of column.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);

	if (size == 0)
		return std::make_shared<ColumnArray>(data);

	Filter nested_filt(getOffsets().back());
	for (size_t i = 0; i < size; ++i)
	{
		if (filt[i])
			memset(&nested_filt[offsetAt(i)], 1, sizeAt(i));
		else
			memset(&nested_filt[offsetAt(i)], 0, sizeAt(i));
	}

	std::shared_ptr<ColumnArray> res = std::make_shared<ColumnArray>(data);

	ssize_t nested_result_size_hint = 0;
	if (result_size_hint < 0)
		nested_result_size_hint = result_size_hint;
	else if (result_size_hint && result_size_hint < 1000000000 && data->size() < 1000000000)	/// Избегаем переполнения.
		nested_result_size_hint = result_size_hint * data->size() / size;

	res->data = data->filter(nested_filt, nested_result_size_hint);

	Offsets_t & res_offsets = res->getOffsets();
	if (result_size_hint)
		res_offsets.reserve(result_size_hint > 0 ? result_size_hint : size);

	size_t current_offset = 0;
	for (size_t i = 0; i < size; ++i)
	{
		if (filt[i])
		{
			current_offset += sizeAt(i);
			res_offsets.push_back(current_offset);
		}
	}

	return res;
}
예제 #2
0
ColumnPtr ColumnArray::filterGeneric(const Filter & filt, ssize_t result_size_hint) const
{
    size_t size = getOffsets().size();
    if (size != filt.size())
        throw Exception("Size of filter doesn't match size of column.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);

    if (size == 0)
        return ColumnArray::create(data);

    Filter nested_filt(getOffsets().back());
    for (size_t i = 0; i < size; ++i)
    {
        if (filt[i])
            memset(&nested_filt[offsetAt(i)], 1, sizeAt(i));
        else
            memset(&nested_filt[offsetAt(i)], 0, sizeAt(i));
    }

    auto res = ColumnArray::create(data->cloneEmpty());

    ssize_t nested_result_size_hint = 0;
    if (result_size_hint < 0)
        nested_result_size_hint = result_size_hint;
    else if (result_size_hint && result_size_hint < 1000000000 && data->size() < 1000000000)    /// Avoid overflow.
         nested_result_size_hint = result_size_hint * data->size() / size;

    res->data = data->filter(nested_filt, nested_result_size_hint);

    Offsets & res_offsets = res->getOffsets();
    if (result_size_hint)
        res_offsets.reserve(result_size_hint > 0 ? result_size_hint : size);

    size_t current_offset = 0;
    for (size_t i = 0; i < size; ++i)
    {
        if (filt[i])
        {
            current_offset += sizeAt(i);
            res_offsets.push_back(current_offset);
        }
    }

    return res;
}