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:
parent
a72743757c
commit
4879686ef4
@ -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; }
|
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
|
/// Plugin Result
|
||||||
|
|
||||||
int mgp_result_set_error_msg(mgp_result *res, const char *msg) {
|
int mgp_result_set_error_msg(mgp_result *res, const char *msg) {
|
||||||
|
@ -171,6 +171,37 @@ struct mgp_map {
|
|||||||
utils::pmr::map<utils::pmr::string, mgp_value> items;
|
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 = ¤t_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 {
|
struct mgp_vertex {
|
||||||
/// Allocator type so that STL containers are aware that we need one.
|
/// 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
|
/// We don't actually need this, but it simplifies the C API, because we store
|
||||||
|
Loading…
Reference in New Issue
Block a user