From abca68458ea039737dda3d4bba7225dbbde3c67d Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Tue, 28 Apr 2015 12:02:20 +0300 Subject: [PATCH] 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. --- cql3/lists.cc | 28 ++++++++++++++++++++++++++++ cql3/lists.hh | 34 ++++++---------------------------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/cql3/lists.cc b/cql3/lists.cc index 747f31b928..46b9f73bc1 100644 --- a/cql3/lists.cc +++ b/cql3/lists.cc @@ -8,6 +8,7 @@ #include "cql3_type.hh" #include "constants.hh" #include +#include namespace cql3 { @@ -329,6 +330,33 @@ lists::do_append(shared_ptr 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(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(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; diff --git a/cql3/lists.hh b/cql3/lists.hh index c435dac23a..9531da05e6 100644 --- a/cql3/lists.hh +++ b/cql3/lists.hh @@ -56,6 +56,7 @@ public: }; class value : public multi_item_terminal, collection_terminal { + public: std::vector _elements; public: explicit value(std::vector 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 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: