2017-04-01 09:19:00 +00:00
|
|
|
#include <Storages/MergeTree/ActiveDataPartSet.h>
|
2016-06-07 08:23:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
|
|
|
ActiveDataPartSet::ActiveDataPartSet(const Strings & names)
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
for (const auto & name : names)
|
|
|
|
addImpl(name);
|
2016-06-07 08:23:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ActiveDataPartSet::add(const String & name)
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
|
|
addImpl(name);
|
2016-06-07 08:23:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ActiveDataPartSet::addImpl(const String & name)
|
|
|
|
{
|
2017-08-14 18:16:11 +00:00
|
|
|
if (!getContainingPartImpl(name).empty())
|
2017-04-01 07:20:54 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
Part part;
|
|
|
|
part.name = name;
|
2017-08-14 18:16:11 +00:00
|
|
|
part.info = MergeTreePartInfo::fromPartName(name);
|
2017-04-01 07:20:54 +00:00
|
|
|
|
|
|
|
/// Parts contained in `part` are located contiguously inside `data_parts`, overlapping with the place where the part itself would be inserted.
|
|
|
|
Parts::iterator it = parts.lower_bound(part);
|
|
|
|
|
|
|
|
/// Let's go left.
|
|
|
|
while (it != parts.begin())
|
|
|
|
{
|
|
|
|
--it;
|
|
|
|
if (!part.contains(*it))
|
|
|
|
{
|
|
|
|
++it;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
parts.erase(it++);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Let's go to the right.
|
|
|
|
while (it != parts.end() && part.contains(*it))
|
|
|
|
{
|
|
|
|
parts.erase(it++);
|
|
|
|
}
|
|
|
|
|
|
|
|
parts.insert(part);
|
2016-06-07 08:23:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String ActiveDataPartSet::getContainingPart(const String & part_name) const
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
|
|
return getContainingPartImpl(part_name);
|
2016-06-08 13:08:20 +00:00
|
|
|
}
|
|
|
|
|
2016-06-07 08:23:15 +00:00
|
|
|
|
2016-06-08 13:08:20 +00:00
|
|
|
String ActiveDataPartSet::getContainingPartImpl(const String & part_name) const
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
Part part;
|
2017-08-14 18:16:11 +00:00
|
|
|
part.info = MergeTreePartInfo::fromPartName(part_name);
|
2017-04-01 07:20:54 +00:00
|
|
|
|
|
|
|
/// A part can only be covered/overlapped by the previous or next one in `parts`.
|
|
|
|
Parts::iterator it = parts.lower_bound(part);
|
|
|
|
|
|
|
|
if (it != parts.end())
|
|
|
|
{
|
|
|
|
if (it->name == part_name)
|
|
|
|
return it->name;
|
|
|
|
if (it->contains(part))
|
|
|
|
return it->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (it != parts.begin())
|
|
|
|
{
|
|
|
|
--it;
|
|
|
|
if (it->contains(part))
|
|
|
|
return it->name;
|
|
|
|
}
|
|
|
|
|
2017-08-14 18:16:11 +00:00
|
|
|
return String();
|
2016-06-07 08:23:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Strings ActiveDataPartSet::getParts() const
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
2016-06-07 08:23:15 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
Strings res;
|
|
|
|
res.reserve(parts.size());
|
|
|
|
for (const Part & part : parts)
|
|
|
|
res.push_back(part.name);
|
2016-06-07 08:23:15 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
return res;
|
2016-06-07 08:23:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
size_t ActiveDataPartSet::size() const
|
|
|
|
{
|
2017-04-01 07:20:54 +00:00
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
|
|
return parts.size();
|
2016-06-07 08:23:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|