query/procedure: Implement mgp_list & mgp_map API

Reviewers: mferencevic, llugovic, ipaljak

Reviewed By: mferencevic

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D2518
This commit is contained in:
Teon Banek 2019-10-28 16:21:13 +01:00
parent a72743757c
commit 4879686ef4
2 changed files with 128 additions and 0 deletions

View File

@ -612,6 +612,103 @@ const mgp_edge *mgp_value_get_edge(const mgp_value *val) { return val->edge_v; }
const mgp_path *mgp_value_get_path(const mgp_value *val) { return val->path_v; }
mgp_list *mgp_list_make_empty(size_t capacity, mgp_memory *memory) {
auto *list = new_mgp_object<mgp_list>(memory);
if (!list) return nullptr;
try {
// May throw std::bad_alloc or std::length_error.
list->elems.reserve(capacity);
} catch (...) {
mgp_list_destroy(list);
return nullptr;
}
return list;
}
void mgp_list_destroy(mgp_list *list) { delete_mgp_object(list); }
int mgp_list_append(mgp_list *list, const mgp_value *val) {
if (mgp_list_size(list) >= mgp_list_capacity(list)) return 0;
return mgp_list_append_extend(list, val);
}
int mgp_list_append_extend(mgp_list *list, const mgp_value *val) {
try {
// May throw std::bad_alloc or std::length_error.
list->elems.push_back(*val);
} catch (...) {
return 0;
}
return 1;
}
size_t mgp_list_size(const mgp_list *list) { return list->elems.size(); }
size_t mgp_list_capacity(const mgp_list *list) {
return list->elems.capacity();
}
const mgp_value *mgp_list_at(const mgp_list *list, size_t i) {
if (i >= mgp_list_size(list)) return nullptr;
return &list->elems[i];
}
mgp_map *mgp_map_make_empty(mgp_memory *memory) {
return new_mgp_object<mgp_map>(memory);
}
void mgp_map_destroy(mgp_map *map) { delete_mgp_object(map); }
int mgp_map_insert(mgp_map *map, const char *key, const mgp_value *value) {
try {
// Unfortunately, cppreference.com does not say what exceptions are thrown,
// so catch all of them. It's probably `std::bad_alloc` and
// `std::length_error`.
map->items.emplace(key, *value);
return 1;
} catch (...) {
return 0;
}
}
size_t mgp_map_size(const mgp_map *map) { return map->items.size(); }
const mgp_value *mgp_map_at(const mgp_map *map, const char *key) {
auto found_it = map->items.find(key);
if (found_it == map->items.end()) return nullptr;
return &found_it->second;
}
const char *mgp_map_item_key(const mgp_map_item *item) { return item->key; }
const mgp_value *mgp_map_item_value(const mgp_map_item *item) {
return item->value;
}
mgp_map_items_iterator *mgp_map_iter_items(const mgp_map *map,
mgp_memory *memory) {
return new_mgp_object<mgp_map_items_iterator>(memory, map);
}
void mgp_map_items_iterator_destroy(mgp_map_items_iterator *it) {
delete_mgp_object(it);
}
const mgp_map_item *mgp_map_items_iterator_get(
const mgp_map_items_iterator *it) {
if (it->current_it == it->map->items.end()) return nullptr;
return &it->current;
}
const mgp_map_item *mgp_map_items_iterator_next(mgp_map_items_iterator *it) {
if (it->current_it == it->map->items.end()) return nullptr;
++it->current_it;
if (it->current_it == it->map->items.end()) return nullptr;
it->current.key = it->current_it->first.c_str();
it->current.value = &it->current_it->second;
return &it->current;
}
/// Plugin Result
int mgp_result_set_error_msg(mgp_result *res, const char *msg) {

View File

@ -171,6 +171,37 @@ struct mgp_map {
utils::pmr::map<utils::pmr::string, mgp_value> items;
};
struct mgp_map_item {
const char *key;
const mgp_value *value;
};
struct mgp_map_items_iterator {
using allocator_type = utils::Allocator<mgp_map_items_iterator>;
mgp_map_items_iterator(const mgp_map *map, utils::MemoryResource *memory)
: memory(memory), map(map), current_it(map->items.begin()) {
if (current_it != map->items.end()) {
current.key = current_it->first.c_str();
current.value = &current_it->second;
}
}
mgp_map_items_iterator(const mgp_map_items_iterator &) = delete;
mgp_map_items_iterator(mgp_map_items_iterator &&) = delete;
mgp_map_items_iterator &operator=(const mgp_map_items_iterator &) = delete;
mgp_map_items_iterator &operator=(mgp_map_items_iterator &&) = delete;
~mgp_map_items_iterator() = default;
utils::MemoryResource *GetMemoryResource() const { return memory; }
utils::MemoryResource *memory;
const mgp_map *map;
decltype(map->items.begin()) current_it;
mgp_map_item current;
};
struct mgp_vertex {
/// Allocator type so that STL containers are aware that we need one.
/// We don't actually need this, but it simplifies the C API, because we store