6#ifndef METALL_CONTAINER_EXPERIMENT_JGRAPH_JGRAPH_HPP
7#define METALL_CONTAINER_EXPERIMENT_JGRAPH_JGRAPH_HPP
36template <
typename allocator_type>
40template <
typename storage_iterator_type>
48template <
typename _allocator_type = std::allocator<std::
byte>>
61 using other_allocator =
62 typename std::allocator_traits<allocator_type>::template
rebind_alloc<T>;
65 using other_scoped_allocator =
70 typename std::allocator_traits<
74 static constexpr internal_id_type k_max_internal_id =
75 std::numeric_limits<internal_id_type>::max();
77 class vertex_data_type {
81 explicit vertex_data_type(
86 vertex_data_type(
const vertex_data_type &) =
default;
89 vertex_data_type(
const vertex_data_type &other,
const allocator_type &
alloc)
90 : m_id(other.m_id,
alloc), m_value(other.m_value,
alloc) {}
97 vertex_data_type(vertex_data_type &&other,
103 vertex_data_type &operator=(
const vertex_data_type &) =
default;
112 const value_type &value()
const {
return m_value; }
119 using vertex_storage_type =
122 other_scoped_allocator<std::pair<
const internal_id_type,
125 class edge_data_type {
129 explicit edge_data_type(
const id_type &source_id,
131 const internal_id_type &
edge_id,
132 const allocator_type &
allocator = allocator_type())
134 m_destination_id(destination_id,
allocator),
139 edge_data_type(
const edge_data_type &) =
default;
143 edge_data_type(
const edge_data_type &other,
const allocator_type &
alloc)
144 : m_source_id(other.m_source_id,
alloc),
145 m_destination_id(other.m_destination_id,
alloc),
146 m_edge_id(other.m_edge_id),
147 m_value(other.m_value,
alloc) {}
155 : m_source_id(other.m_source_id,
alloc),
156 m_destination_id(other.m_destination_id,
alloc),
157 m_edge_id(other.m_edge_id),
158 m_value(other.m_value,
alloc) {}
161 edge_data_type &operator=(
const edge_data_type &) =
default;
168 const id_type destination_id()
const {
return id_type(m_destination_id); }
176 const value_type &value()
const {
return m_value; }
179 string_type m_source_id;
180 string_type m_destination_id;
181 internal_id_type m_edge_id;
185 using edge_storage_type =
188 other_scoped_allocator<
189 std::pair<const internal_id_type, edge_data_type>>>;
192 using adj_list_edge_list_type =
195 std::hash<internal_id_type>, std::equal_to<>,
196 other_scoped_allocator<std::pair<
197 const internal_id_type, internal_id_type>>>;
201 adj_list_edge_list_type, std::hash<internal_id_type>, std::equal_to<>,
202 other_scoped_allocator<
203 std::pair<const internal_id_type, adj_list_edge_list_type>>>;
207 internal_id_type, string_type, std::hash<internal_id_type>,
224 typename adj_list_edge_list_type::iterator,
225 typename std::pointer_traits<
typename std::allocator_traits<
229 typename adj_list_edge_list_type::const_iterator,
230 typename std::pointer_traits<
typename std::allocator_traits<
236 : m_vertex_storage(
alloc),
237 m_edge_storage(
alloc),
239 m_vertex_id_table(
alloc) {}
245 return priv_get_vertex_internal_id(
vertex_id) != k_max_internal_id;
251 if (
src == k_max_internal_id)
return 0;
254 if (
dst == k_max_internal_id)
return 0;
269 adj_list_edge_list_type{m_adj_list.get_allocator()});
271 auto ret = m_vertex_storage.emplace(
273 vertex_data_type{
vertex_id, m_vertex_storage.get_allocator()});
288 const auto edge_id = priv_generate_edge_id();
295 m_edge_storage.emplace(
297 edge_id, m_edge_storage.get_allocator()});
303 m_vertex_storage.find(priv_get_vertex_internal_id(
vertex_id)));
308 m_vertex_storage.find(priv_get_vertex_internal_id(
vertex_id)));
334 std::size_t
num_edges()
const {
return m_edge_storage.size(); }
400 return m_vertex_storage.get_allocator();
404 internal_id_type priv_get_vertex_internal_id(
405 const std::string_view &
vid)
const {
406 auto hash = priv_hash_id(
vid.data());
408 for (std::size_t
d = 0;
d <= m_max_vid_distance; ++
d) {
409 const auto vitr = m_vertex_id_table.find(hash);
410 if (
vitr == m_vertex_id_table.end()) {
417 hash = (hash + 1) % k_max_internal_id;
420 return k_max_internal_id;
423 internal_id_type priv_generate_vertex_internal_id(
424 const std::string_view &
vid) {
425 auto hash = priv_hash_id(
vid.data());
428 while (m_vertex_id_table.count(hash) > 0) {
429 hash = (hash + 1) % k_max_internal_id;
432 m_max_vid_distance = std::max(
distance, m_max_vid_distance);
434 m_vertex_id_table[
hash] =
vid.data();
439 internal_id_type priv_generate_edge_id() {
return ++m_max_edge_id; }
441 static internal_id_type priv_hash_id(
const std::string_view &
id) {
442 return metall::mtlldetail::murmur_hash_64a(
id.
data(),
id.
length(), 1234);
445 vertex_storage_type m_vertex_storage;
446 edge_storage_type m_edge_storage;
447 adj_list_type m_adj_list;
448 id_table_type m_vertex_id_table;
449 internal_id_type m_max_edge_id{0};
450 std::size_t m_max_vid_distance{0};
455template <
typename storage_iterator_type>
458 static constexpr bool is_const_value = std::is_const_v<
459 typename std::iterator_traits<storage_iterator_type>::value_type>;
462 using raw_value_type =
typename std::tuple_element<
464 typename std::iterator_traits<storage_iterator_type>::value_type>
::type;
468 std::conditional_t<is_const_value, const raw_value_type, raw_value_type>;
469 using pointer =
typename std::pointer_traits<
typename std::iterator_traits<
473 typename std::iterator_traits<storage_iterator_type>::difference_type;
496 return m_current_pos == other.m_current_pos;
511template <
typename storage_iterator_type>
517template <
typename storage_iterator_type>
527 static constexpr bool is_const_value = std::is_const_v<
528 typename std::pointer_traits<storage_pointer_type>::element_type>;
531 using raw_value_type =
typename std::pointer_traits<
536 std::conditional_t<is_const_value, const raw_value_type, raw_value_type>;
538 typename std::pointer_traits<storage_pointer_type>::element_type::
568 return m_current_pos == other.m_current_pos;
572 const auto &
edge_id = m_current_pos->second;
573 return &(m_storage_pointer->at(
edge_id));
577 const auto &
edge_id = m_current_pos->second;
578 return &(m_storage_pointer->at(
edge_id));
582 const auto &
edge_id = m_current_pos->second;
583 return (m_storage_pointer->at(
edge_id));
587 const auto &
edge_id = m_current_pos->second;
588 return (m_storage_pointer->at(
edge_id));