cql3: convert lists::prepender to C++
Note the original code contains a bug, causing the prepended literal to be reversed. The conversion (and Origin) are fixed.
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include "cql3_type.hh"
|
||||
#include "constants.hh"
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/range/adaptor/reversed.hpp>
|
||||
|
||||
namespace cql3 {
|
||||
|
||||
@@ -329,6 +330,33 @@ lists::do_append(shared_ptr<term> t,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lists::prepender::execute(mutation& m, const exploded_clustering_prefix& prefix, const update_parameters& params) {
|
||||
assert(column.type->is_multi_cell()); // "Attempted to prepend to a frozen list";
|
||||
auto&& value = _t->bind(params._options);
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto&& lvalue = dynamic_pointer_cast<lists::value>(std::move(value));
|
||||
assert(lvalue);
|
||||
auto time = precision_time::REFERENCE_TIME - (db_clock::now() - precision_time::REFERENCE_TIME);
|
||||
|
||||
collection_type_impl::mutation mut;
|
||||
mut.cells.reserve(lvalue->get_elements().size());
|
||||
// We reverse the order of insertion, so that the last element gets the lastest time
|
||||
// (lists are sorted by time)
|
||||
for (auto&& v : lvalue->_elements | boost::adaptors::reversed) {
|
||||
auto&& pt = precision_time::get_next(time);
|
||||
auto uuid = utils::UUID_gen::get_time_UUID_bytes(pt.millis.time_since_epoch().count(), pt.nanos);
|
||||
mut.cells.emplace_back(bytes(uuid.data(), uuid.size()), params.make_cell(*v));
|
||||
}
|
||||
// now reverse again, to get the original order back
|
||||
std::reverse(mut.cells.begin(), mut.cells.end());
|
||||
auto&& ltype = static_cast<list_type_impl*>(column.type.get());
|
||||
m.set_cell(prefix, column, atomic_cell_or_collection::from_collection_mutation(ltype->serialize_mutation_form(std::move(mut))));
|
||||
}
|
||||
|
||||
bool
|
||||
lists::discarder::requires_read() {
|
||||
return true;
|
||||
|
||||
@@ -56,6 +56,7 @@ public:
|
||||
};
|
||||
|
||||
class value : public multi_item_terminal, collection_terminal {
|
||||
public:
|
||||
std::vector<bytes_opt> _elements;
|
||||
public:
|
||||
explicit value(std::vector<bytes_opt> elements)
|
||||
@@ -169,34 +170,11 @@ public:
|
||||
const update_parameters& params,
|
||||
tombstone ts = {});
|
||||
|
||||
#if 0
|
||||
public static class Prepender extends Operation
|
||||
{
|
||||
public Prepender(ColumnDefinition column, Term t)
|
||||
{
|
||||
super(column, t);
|
||||
}
|
||||
|
||||
public void execute(ByteBuffer rowKey, ColumnFamily cf, Composite prefix, UpdateParameters params) throws InvalidRequestException
|
||||
{
|
||||
assert column.type.isMultiCell() : "Attempted to prepend to a frozen list";
|
||||
Term.Terminal value = t.bind(params.options);
|
||||
if (value == null)
|
||||
return;
|
||||
|
||||
assert value instanceof Lists.Value;
|
||||
long time = PrecisionTime.REFERENCE_TIME - (System.currentTimeMillis() - PrecisionTime.REFERENCE_TIME);
|
||||
|
||||
List<ByteBuffer> toAdd = ((Lists.Value)value).elements;
|
||||
for (int i = 0; i < toAdd.size(); i++)
|
||||
{
|
||||
PrecisionTime pt = PrecisionTime.getNext(time);
|
||||
ByteBuffer uuid = ByteBuffer.wrap(UUIDGen.getTimeUUIDBytes(pt.millis, pt.nanos));
|
||||
cf.addColumn(params.makeColumn(cf.getComparator().create(prefix, column, uuid), toAdd.get(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
class prepender : public operation {
|
||||
public:
|
||||
using operation::operation;
|
||||
virtual void execute(mutation& m, const exploded_clustering_prefix& prefix, const update_parameters& params) override;
|
||||
};
|
||||
|
||||
class discarder : public operation {
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user