Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow appending ArrayView to ArrayWriter through add_items() #1494

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
262 changes: 34 additions & 228 deletions velox/core/CoreTypeSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,40 @@ struct StringWriter : public UDFOutputString {
return *this;
}

template <typename T>
void operator+=(const T& input) {
append(input);
}

void operator+=(const char* input) {
append(std::string_view(input));
}

template <typename T>
void append(const T& input) {
auto oldSize = size();
resize(this->size() + input.size());
if (input.size() != 0) {
DCHECK(data());
DCHECK(input.data());
std::memcpy(data() + oldSize, input.data(), input.size());
}
}

void append(const char* input) {
append(std::string_view(input));
}

template <typename T>
void copy_from(const T& input) {
resize(0);
append(input);
}

void copy_from(const char* input) {
append(std::string_view(input));
}

StringWriter& operator=(StringWriter&& rh) noexcept {
storage_ = std::move(rh.storage_);
setData(storage_.data());
Expand Down Expand Up @@ -125,234 +159,6 @@ struct UdfToType {
}
};

template <typename VAL>
class ArrayValWriter {
public:
using container_t = typename std::vector<std::optional<VAL>>;
using iterator = typename container_t::iterator;
using reference = typename container_t::reference;
using const_iterator = typename container_t::const_iterator;
using const_reference = typename container_t::const_reference;
using val_type = VAL;

static std::shared_ptr<const Type> veloxType() {
return ARRAY(UdfToType<val_type>::veloxType());
}

ArrayValWriter() = default;
ArrayValWriter(const_iterator start, const_iterator end)
: values_(start, end) {}

void reserve(size_t size) {
values_.reserve(size);
}
iterator begin() {
return values_.begin();
}
iterator end() {
return values_.end();
}
void append(val_type val) {
values_.push_back(std::optional<val_type>{std::move(val)});
}
void append(std::optional<val_type> val) {
values_.push_back(std::move(val));
}
void appendNullable() {
append(std::optional<val_type>{});
}
void clear() {
values_.clear();
}

const_iterator begin() const {
return values_.begin();
}
const_iterator end() const {
return values_.end();
}

const_reference at(size_t index) const {
return values_.at(index);
}
size_t size() const {
return values_.size();
}

private:
container_t values_;
};

template <typename VAL>
class ArrayValReader : public ArrayValWriter<VAL> {
public:
ArrayValReader() = default;
explicit ArrayValReader(std::vector<VAL> vals) {
reserve(vals.size());
for (auto& val : vals) {
append(std::move(val));
}
}

bool mayHaveNulls() const {
return false;
}

std::optional<VAL> operator[](size_t index) const {
return {ArrayValWriter<VAL>::at(index)};
}

std::optional<VAL> at(size_t index) const {
return {ArrayValWriter<VAL>::at(index)};
}
};

template <typename... T>
struct RowWriter {
template <std::size_t... Is>
static std::tuple<std::optional<T>...> addOptional(
const std::tuple<T...>& val,
std::index_sequence<Is...>) {
return std::tuple<std::optional<T>...>{std::get<Is>(val)...};
}

public:
static std::shared_ptr<const Type> veloxType() {
return ROW({UdfToType<T>::veloxType()...});
}

RowWriter() {}

/* implicit */ RowWriter(const std::tuple<std::optional<T>...>& val)
: values_(val) {}
/* implicit */ RowWriter(const std::tuple<T...>& val)
: values_(addOptional(val, std::index_sequence_for<T...>{})) {}

template <size_t N>
auto& at() {
return std::get<N>(values_);
}

template <size_t N>
const auto& at() const {
return std::get<N>(values_);
}

void clear() {
values_ = std::tuple<std::optional<T>...>();
}

private:
std::tuple<std::optional<T>...> values_;
};

template <typename... T>
struct RowReader : public RowWriter<T...> {};

template <typename KEY, typename VAL>
struct IMapVal {
static std::shared_ptr<const Type> veloxType() {
return MAP(UdfToType<KEY>::veloxType(), UdfToType<VAL>::veloxType());
}
using container_t = typename folly::F14FastMap<KEY, std::optional<VAL>>;
using iterator = typename container_t::iterator;
using reference = typename container_t::reference;
using const_iterator = typename container_t::const_iterator;
using mapped_type = typename container_t::mapped_type;
using key_type = KEY;
using val_type = VAL;

iterator begin() {
return data_.begin();
}
iterator end() {
return data_.end();
}
iterator find(const key_type& key) {
return data_.find(key);
}
mapped_type& at(const key_type& key) {
return data_.at(key);
}
val_type& append(const key_type& key) {
auto& opt = (data_[key] = std::optional(val_type{}));
return *opt; // todo(youknowjack): avoid presence check here
}
std::optional<val_type>& appendNullable(const key_type& key) {
return data_[key] = {};
}
std::pair<iterator, bool> emplace(
const key_type& key,
std::optional<val_type> value) {
return data_.emplace(key, std::move(value));
}
void clear() {
data_.clear();
}
void reserve(typename container_t::size_type n) {
data_.reserve(n);
}

const_iterator begin() const {
return data_.begin();
}
const_iterator end() const {
return data_.end();
}
const_iterator find(const key_type& key) const {
return data_.find(key);
}
bool contains(const key_type& key) const {
return data_.find(key) != end();
}
const mapped_type& at(const key_type& key) const {
return data_.at(key);
}
size_t size() const {
return data_.size();
}

private:
container_t data_;
};

template <typename KEY, typename VAL>
class SlowMapVal : public IMapVal<KEY, VAL> {};

template <typename KEY, typename VAL>
class SlowMapWriter : public IMapVal<KEY, VAL> {
public:
// Allow map-like object to be assigned to a map writer. This should change
// once we implement writer proxies.
template <template <typename, typename> typename T>
SlowMapWriter& operator=(const T<KEY, VAL>& rh) {
assignFrom(rh);

return *this;
}

// Allow Velox's MapView to be assigned to a map writer. This should also
// change once we implement writer proxies.
template <bool nullFree, template <bool, typename, typename> typename T>
SlowMapWriter& operator=(const T<nullFree, KEY, VAL>& rh) {
assignFrom(rh);

return *this;
}

private:
// This allows us to share code between assignment operators.
// Ensure rh supports a map-like iterator interface before calling this
// function.
template <typename T>
inline void assignFrom(const T& rh) {
IMapVal<KEY, VAL>::clear();
for (const auto& it : rh) {
IMapVal<KEY, VAL>::emplace(it.first, it.second);
}
}
};

} // namespace core
} // namespace velox
} // namespace facebook
22 changes: 0 additions & 22 deletions velox/core/SimpleFunctionMetadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,28 +272,6 @@ struct TypeAnalysis<Row<T...>> {
}
};

// TODO: remove once old writers deprecated.
template <typename V>
struct TypeAnalysis<ArrayWriterT<V>> {
void run(TypeAnalysisResults& results) {
TypeAnalysis<Array<V>>().run(results);
}
};

template <typename K, typename V>
struct TypeAnalysis<MapWriterT<K, V>> {
void run(TypeAnalysisResults& results) {
TypeAnalysis<Map<K, V>>().run(results);
}
};

template <typename... T>
struct TypeAnalysis<RowWriterT<T...>> {
void run(TypeAnalysisResults& results) {
TypeAnalysis<Row<T...>>().run(results);
}
};

// todo(youknowjack): need a better story for types for UDFs. Mapping
// c++ types <-> Velox types is imprecise (e.g. string vs
// binary) and difficult to change.
Expand Down
2 changes: 1 addition & 1 deletion velox/core/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

add_executable(velox_core_test TestMap.cpp TestMetafunctions.cpp TestString.cpp
add_executable(velox_core_test TestMetafunctions.cpp TestString.cpp
TestTypeAnalysis.cpp)

add_test(velox_core_test velox_core_test)
Expand Down
77 changes: 0 additions & 77 deletions velox/core/tests/TestMap.cpp

This file was deleted.

Loading