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:
Avi Kivity
2015-04-28 12:02:20 +03:00
parent 4736504f4a
commit abca68458e
2 changed files with 34 additions and 28 deletions

View File

@@ -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;

View File

@@ -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: