flex/storages/rt_mutable_graph/csr/nbr.h (551 lines of code) (raw):

/** Copyright 2020 Alibaba Group Holding Limited. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef STORAGES_RT_MUTABLE_GRAPH_CSR_NBR_H_ #define STORAGES_RT_MUTABLE_GRAPH_CSR_NBR_H_ #include "grape/types.h" #include "flex/storages/rt_mutable_graph/types.h" #include "flex/utils/property/column.h" #include "flex/utils/property/table.h" #include "flex/utils/property/types.h" namespace gs { template <typename EDATA_T> struct ImmutableNbr { ImmutableNbr() = default; ImmutableNbr(const ImmutableNbr& rhs) : neighbor(rhs.neighbor), data(rhs.data) {} ~ImmutableNbr() = default; ImmutableNbr& operator=(const ImmutableNbr& rhs) { neighbor = rhs.neighbor; data = rhs.data; return *this; } const EDATA_T& get_data() const { return data; } vid_t get_neighbor() const { return neighbor; } void set_data(const EDATA_T& val) { data = val; } void set_neighbor(vid_t neighbor) { this->neighbor = neighbor; } bool exists() const { return neighbor != std::numeric_limits<vid_t>::max(); } vid_t neighbor; EDATA_T data; }; template <> struct __attribute__((packed)) ImmutableNbr<Date> { ImmutableNbr() = default; ImmutableNbr(const ImmutableNbr& rhs) : neighbor(rhs.neighbor), data(rhs.data) {} ~ImmutableNbr() = default; ImmutableNbr& operator=(const ImmutableNbr& rhs) { neighbor = rhs.neighbor; data = rhs.data; return *this; } const Date& get_data() const { return data; } vid_t get_neighbor() const { return neighbor; } void set_data(const Date& val) { data = val; } void set_neighbor(vid_t neighbor) { this->neighbor = neighbor; } bool exists() const { return neighbor != std::numeric_limits<vid_t>::max(); } vid_t neighbor; Date data; }; template <> struct ImmutableNbr<grape::EmptyType> { ImmutableNbr() = default; ImmutableNbr(const ImmutableNbr& rhs) : neighbor(rhs.neighbor) {} ~ImmutableNbr() = default; ImmutableNbr& operator=(const ImmutableNbr& rhs) { neighbor = rhs.neighbor; return *this; } void set_data(const grape::EmptyType&) {} void set_neighbor(vid_t neighbor) { this->neighbor = neighbor; } const grape::EmptyType& get_data() const { return data; } vid_t get_neighbor() const { return neighbor; } union { vid_t neighbor; grape::EmptyType data; }; }; template <typename EDATA_T> class ImmutableNbrSlice { public: using const_nbr_t = const ImmutableNbr<EDATA_T>; using const_nbr_ptr_t = const ImmutableNbr<EDATA_T>*; ImmutableNbrSlice() = default; ImmutableNbrSlice(const ImmutableNbrSlice& rhs) : ptr_(rhs.ptr_), size_(rhs.size_) {} ~ImmutableNbrSlice() = default; void set_size(int size) { size_ = size; } int size() const { return size_; } void set_begin(const_nbr_ptr_t ptr) { ptr_ = ptr; } const_nbr_ptr_t begin() const { return ptr_; } const_nbr_ptr_t end() const { return ptr_ + size_; } static ImmutableNbrSlice empty() { ImmutableNbrSlice ret; ret.set_begin(nullptr); ret.set_size(0); return ret; } private: const_nbr_ptr_t ptr_; int size_; }; template <> class ImmutableNbrSlice<std::string_view> { public: struct ColumnNbr { using const_nbr_t = const ImmutableNbr<size_t>; using const_nbr_ptr_t = const ImmutableNbr<size_t>*; ColumnNbr(const_nbr_ptr_t ptr, const StringColumn& column) : ptr_(ptr), column_(column) {} vid_t get_neighbor() const { return ptr_->neighbor; } std::string_view get_data() const { return column_.get_view(ptr_->data); } const ColumnNbr& operator*() const { return *this; } const ColumnNbr* operator->() const { return this; } const ColumnNbr& operator=(const ColumnNbr& nbr) const { ptr_ = nbr.ptr_; return *this; } bool operator==(const ColumnNbr& nbr) const { return ptr_ == nbr.ptr_; } bool operator!=(const ColumnNbr& nbr) const { return ptr_ != nbr.ptr_; } const ColumnNbr& operator++() const { ++ptr_; return *this; } const ColumnNbr& operator+=(size_t n) const { ptr_ += n; return *this; } size_t operator-(const ColumnNbr& nbr) const { return ptr_ - nbr.ptr_; } bool operator<(const ColumnNbr& nbr) const { return ptr_ < nbr.ptr_; } mutable const_nbr_ptr_t ptr_; const StringColumn& column_; }; using const_nbr_t = const ColumnNbr; using const_nbr_ptr_t = const ColumnNbr; ImmutableNbrSlice(const StringColumn& column) : slice_(), column_(column) {} ImmutableNbrSlice(const ImmutableNbrSlice<size_t>& slice, const StringColumn& column) : slice_(slice), column_(column) {} ImmutableNbrSlice(const ImmutableNbrSlice& rhs) : slice_(rhs.slice_), column_(rhs.column_) {} ~ImmutableNbrSlice() = default; void set_size(int size) { slice_.set_size(size); } int size() const { return slice_.size(); } void set_begin(const ImmutableNbr<size_t>* ptr) { slice_.set_begin(ptr); } const ColumnNbr begin() const { return ColumnNbr(slice_.begin(), column_); } const ColumnNbr end() const { return ColumnNbr(slice_.end(), column_); } static ImmutableNbrSlice empty(const StringColumn& column) { ImmutableNbrSlice ret(column); ret.set_begin(nullptr); ret.set_size(0); return ret; } private: ImmutableNbrSlice<size_t> slice_; const StringColumn& column_; }; template <> class ImmutableNbrSlice<RecordView> { public: struct TableNbr { using const_nbr_t = const ImmutableNbr<size_t>; using const_nbr_ptr_t = const ImmutableNbr<size_t>*; TableNbr(const_nbr_ptr_t ptr, const Table& table) : ptr_(ptr), table_(table) {} vid_t get_neighbor() const { return ptr_->neighbor; } RecordView get_data() const { return RecordView(ptr_->data, &table_); } const TableNbr& operator*() const { return *this; } const TableNbr* operator->() const { return this; } const TableNbr& operator=(const TableNbr& nbr) const { ptr_ = nbr.ptr_; return *this; } bool operator==(const TableNbr& nbr) const { return ptr_ == nbr.ptr_; } bool operator!=(const TableNbr& nbr) const { return ptr_ != nbr.ptr_; } const TableNbr& operator++() const { ++ptr_; return *this; } const TableNbr& operator+=(size_t n) const { ptr_ += n; return *this; } size_t operator-(const TableNbr& nbr) const { return ptr_ - nbr.ptr_; } bool operator<(const TableNbr& nbr) const { return ptr_ < nbr.ptr_; } mutable const_nbr_ptr_t ptr_; const Table& table_; }; using const_nbr_t = const TableNbr; using const_nbr_ptr_t = const TableNbr; ImmutableNbrSlice(const ImmutableNbrSlice<size_t>& slice, const Table& table) : slice_(slice), table_(table) {} ImmutableNbrSlice(const ImmutableNbrSlice& rhs) : slice_(rhs.slice_), table_(rhs.table_) {} ~ImmutableNbrSlice() = default; void set_size(int size) { slice_.set_size(size); } int size() const { return slice_.size(); } void set_begin(const ImmutableNbr<size_t>* ptr) { slice_.set_begin(ptr); } const TableNbr begin() const { return TableNbr(slice_.begin(), table_); } const TableNbr end() const { return TableNbr(slice_.end(), table_); } static ImmutableNbrSlice empty(const Table& table) { ImmutableNbrSlice ret(ImmutableNbrSlice<size_t>::empty(), table); return ret; } private: ImmutableNbrSlice<size_t> slice_; const Table& table_; }; template <typename EDATA_T> struct MutableNbr { MutableNbr() = default; MutableNbr(const MutableNbr& rhs) : neighbor(rhs.neighbor), timestamp(rhs.timestamp.load()), data(rhs.data) {} ~MutableNbr() = default; MutableNbr& operator=(const MutableNbr& rhs) { neighbor = rhs.neighbor; timestamp.store(rhs.timestamp.load()); data = rhs.data; return *this; } const EDATA_T& get_data() const { return data; } vid_t get_neighbor() const { return neighbor; } timestamp_t get_timestamp() const { return timestamp.load(); } void set_data(const EDATA_T& val, timestamp_t ts) { data = val; timestamp.store(ts); } void set_neighbor(vid_t neighbor) { this->neighbor = neighbor; } void set_timestamp(timestamp_t ts) { timestamp.store(ts); } vid_t neighbor; std::atomic<timestamp_t> timestamp; EDATA_T data; }; template <> struct MutableNbr<grape::EmptyType> { MutableNbr() = default; MutableNbr(const MutableNbr& rhs) : neighbor(rhs.neighbor), timestamp(rhs.timestamp.load()) {} ~MutableNbr() = default; MutableNbr& operator=(const MutableNbr& rhs) { neighbor = rhs.neighbor; timestamp.store(rhs.timestamp.load()); return *this; } void set_data(const grape::EmptyType&, timestamp_t ts) { timestamp.store(ts); } void set_neighbor(vid_t neighbor) { this->neighbor = neighbor; } void set_timestamp(timestamp_t ts) { timestamp.store(ts); } const grape::EmptyType& get_data() const { return data; } vid_t get_neighbor() const { return neighbor; } timestamp_t get_timestamp() const { return timestamp.load(); } vid_t neighbor; union { std::atomic<timestamp_t> timestamp; grape::EmptyType data; }; }; template <typename EDATA_T> class MutableNbrSlice { public: using const_nbr_t = const MutableNbr<EDATA_T>; using const_nbr_ptr_t = const MutableNbr<EDATA_T>*; MutableNbrSlice() : ptr_(nullptr), size_(0){}; MutableNbrSlice(const MutableNbrSlice& rhs) : ptr_(rhs.ptr_), size_(rhs.size_) {} ~MutableNbrSlice() = default; void set_size(int size) { size_ = size; } inline int size() const { return size_; } void set_begin(const_nbr_ptr_t ptr) { ptr_ = ptr; } inline const_nbr_ptr_t begin() const { return ptr_; } inline const_nbr_ptr_t end() const { return ptr_ + size_; } static MutableNbrSlice empty() { MutableNbrSlice ret; ret.set_begin(nullptr); ret.set_size(0); return ret; } private: const_nbr_ptr_t ptr_; int size_; }; template <> class MutableNbrSlice<RecordView> { public: struct MutableTableNbr { using const_nbr_t = const MutableNbr<size_t>; using const_nbr_ptr_t = const MutableNbr<size_t>*; MutableTableNbr(const_nbr_ptr_t ptr, const Table& table) : ptr_(ptr), table_(table) {} vid_t get_neighbor() const { return ptr_->neighbor; } timestamp_t get_timestamp() const { return ptr_->timestamp.load(); } RecordView get_data() const { return RecordView(ptr_->data, &table_); } const MutableTableNbr& operator*() const { return *this; } const MutableTableNbr* operator->() const { return this; } const MutableTableNbr& operator=(const MutableTableNbr& nbr) const { ptr_ = nbr.ptr_; return *this; } bool operator==(const MutableTableNbr& nbr) const { return ptr_ == nbr.ptr_; } bool operator!=(const MutableTableNbr& nbr) const { return ptr_ != nbr.ptr_; } const MutableTableNbr& operator++() const { ++ptr_; return *this; } const MutableTableNbr& operator+=(size_t n) const { ptr_ += n; return *this; } size_t operator-(const MutableTableNbr& nbr) const { return ptr_ - nbr.ptr_; } bool operator<(const MutableTableNbr& nbr) const { return ptr_ < nbr.ptr_; } mutable const_nbr_ptr_t ptr_; const Table& table_; }; using const_nbr_t = const MutableTableNbr; using const_nbr_ptr_t = const MutableTableNbr; MutableNbrSlice(MutableNbrSlice<size_t> slice, const Table& table) : slice_(slice), table_(table) {} MutableNbrSlice(const MutableNbrSlice& rhs) : slice_(rhs.slice_), table_(rhs.table_) {} ~MutableNbrSlice() = default; void set_size(int size) { slice_.set_size(size); } int size() const { return slice_.size(); } int field_num() const { return table_.col_num(); } void set_begin(const MutableNbr<size_t>* ptr) { slice_.set_begin(ptr); } const MutableTableNbr begin() const { return MutableTableNbr(slice_.begin(), table_); } const MutableTableNbr end() const { return MutableTableNbr(slice_.end(), table_); } static MutableNbrSlice empty(const Table& table) { MutableNbrSlice ret(MutableNbrSlice<size_t>::empty(), table); return ret; } MutableNbrSlice<size_t> slice_; const Table& table_; }; template <> class MutableNbrSlice<std::string_view> { public: struct MutableColumnNbr { using const_nbr_t = const MutableNbr<size_t>; using const_nbr_ptr_t = const MutableNbr<size_t>*; MutableColumnNbr(const_nbr_ptr_t ptr, const StringColumn& column) : ptr_(ptr), column_(column) {} vid_t get_neighbor() const { return ptr_->neighbor; } std::string_view get_data() const { return column_.get_view(ptr_->data); } timestamp_t get_timestamp() const { return ptr_->timestamp.load(); } const MutableColumnNbr& operator*() const { return *this; } const MutableColumnNbr* operator->() const { return this; } const MutableColumnNbr& operator=(const MutableColumnNbr& nbr) const { ptr_ = nbr.ptr_; return *this; } bool operator==(const MutableColumnNbr& nbr) const { return ptr_ == nbr.ptr_; } bool operator!=(const MutableColumnNbr& nbr) const { return ptr_ != nbr.ptr_; } const MutableColumnNbr& operator++() const { ++ptr_; return *this; } const MutableColumnNbr& operator+=(size_t n) const { ptr_ += n; return *this; } size_t operator-(const MutableColumnNbr& nbr) const { return ptr_ - nbr.ptr_; } bool operator<(const MutableColumnNbr& nbr) const { return ptr_ < nbr.ptr_; } mutable const_nbr_ptr_t ptr_; const StringColumn& column_; }; using const_nbr_t = const MutableColumnNbr; using const_nbr_ptr_t = const MutableColumnNbr; MutableNbrSlice(MutableNbrSlice<size_t> slice, const StringColumn& column) : slice_(slice), column_(column) {} MutableNbrSlice(const MutableNbrSlice& rhs) : slice_(rhs.slice_), column_(rhs.column_) {} ~MutableNbrSlice() = default; void set_size(int size) { slice_.set_size(size); } int size() const { return slice_.size(); } void set_begin(const MutableNbr<size_t>* ptr) { slice_.set_begin(ptr); } const MutableColumnNbr begin() const { return MutableColumnNbr(slice_.begin(), column_); } const MutableColumnNbr end() const { return MutableColumnNbr(slice_.end(), column_); } static MutableNbrSlice empty(const StringColumn& column) { MutableNbrSlice ret(MutableNbrSlice<size_t>::empty(), column); return ret; } private: MutableNbrSlice<size_t> slice_; const StringColumn& column_; }; template <typename EDATA_T> class MutableNbrSliceMut { public: using nbr_t = MutableNbr<EDATA_T>; using nbr_ptr_t = MutableNbr<EDATA_T>*; MutableNbrSliceMut() : ptr_(nullptr), size_(0){}; ~MutableNbrSliceMut() = default; void set_size(int size) { size_ = size; } int size() const { return size_; } void set_begin(nbr_t* ptr) { ptr_ = ptr; } nbr_t* begin() { return ptr_; } nbr_t* end() { return ptr_ + size_; } static MutableNbrSliceMut empty() { MutableNbrSliceMut ret; ret.set_begin(nullptr); ret.set_size(0); return ret; } private: nbr_t* ptr_; int size_; }; template <> class MutableNbrSliceMut<std::string_view> { public: struct MutableColumnNbr { using nbr_t = MutableNbr<size_t>; MutableColumnNbr(nbr_t* ptr, StringColumn& column) : ptr_(ptr), column_(column) {} vid_t neighbor() const { return ptr_->neighbor; } std::string_view data() { return column_.get_view(ptr_->data); } vid_t get_neighbor() const { return ptr_->neighbor; } const std::string_view get_data() const { return column_.get_view(ptr_->data); } timestamp_t get_timestamp() const { return ptr_->timestamp.load(); } size_t get_index() const { return ptr_->data; } void set_data(const std::string_view& sw, timestamp_t ts) { column_.set_value(ptr_->data, sw); ptr_->timestamp.store(ts); } void set_neighbor(vid_t neighbor) { ptr_->neighbor = neighbor; } void set_timestamp(timestamp_t ts) { ptr_->timestamp.store(ts); } const MutableColumnNbr& operator*() const { return *this; } MutableColumnNbr& operator*() { return *this; } MutableColumnNbr& operator=(const MutableColumnNbr& nbr) { ptr_ = nbr.ptr_; return *this; } bool operator==(const MutableColumnNbr& nbr) const { return ptr_ == nbr.ptr_; } bool operator!=(const MutableColumnNbr& nbr) const { return ptr_ != nbr.ptr_; } MutableColumnNbr& operator++() { ptr_++; return *this; } MutableColumnNbr& operator+=(size_t n) { ptr_ += n; return *this; } bool operator<(const MutableColumnNbr& nbr) { return ptr_ < nbr.ptr_; } nbr_t* ptr_; StringColumn& column_; }; using nbr_ptr_t = MutableColumnNbr; MutableNbrSliceMut(MutableNbrSliceMut<size_t> slice, StringColumn& column) : slice_(slice), column_(column) {} ~MutableNbrSliceMut() = default; void set_size(int size) { slice_.set_size(size); } int size() const { return slice_.size(); } void set_begin(MutableNbr<size_t>* ptr) { slice_.set_begin(ptr); } MutableColumnNbr begin() { return MutableColumnNbr(slice_.begin(), column_); } MutableColumnNbr end() { return MutableColumnNbr(slice_.end(), column_); } static MutableNbrSliceMut empty(StringColumn& column) { MutableNbrSliceMut ret(MutableNbrSliceMut<size_t>::empty(), column); return ret; } private: MutableNbrSliceMut<size_t> slice_; StringColumn& column_; }; template <> class MutableNbrSliceMut<RecordView> { public: struct MutableTableNbr { using nbr_t = MutableNbr<size_t>; MutableTableNbr(nbr_t* ptr, Table& table) : ptr_(ptr), table_(table) {} vid_t neighbor() const { return ptr_->neighbor; } vid_t get_neighbor() const { return ptr_->neighbor; } timestamp_t get_timestamp() const { return ptr_->timestamp.load(); } size_t get_index() const { return ptr_->data; } RecordView get_data() const { return RecordView(ptr_->data, &table_); } void set_data(const Record& r, timestamp_t ts) { grape::InArchive in; for (size_t i = 0; i < r.len; ++i) { in << r.props[i]; } grape::OutArchive out; out.SetSlice(in.GetBuffer(), in.GetSize()); table_.ingest(ptr_->data, out); ptr_->timestamp.store(ts); } void set_neighbor(vid_t neighbor) { ptr_->neighbor = neighbor; } void set_timestamp(timestamp_t ts) { ptr_->timestamp.store(ts); } const MutableTableNbr& operator*() const { return *this; } MutableTableNbr& operator*() { return *this; } const MutableTableNbr* operator->() const { return this; } MutableTableNbr* operator->() { return this; } MutableTableNbr& operator=(const MutableTableNbr& nbr) { ptr_ = nbr.ptr_; return *this; } bool operator==(const MutableTableNbr& nbr) const { return ptr_ == nbr.ptr_; } bool operator!=(const MutableTableNbr& nbr) const { return ptr_ != nbr.ptr_; } const MutableTableNbr& operator++() const { ptr_++; return *this; } const MutableTableNbr& operator+=(size_t n) const { ptr_ += n; return *this; } size_t operator-(const MutableTableNbr& nbr) const { return ptr_ - nbr.ptr_; } bool operator<(const MutableTableNbr& nbr) { return ptr_ < nbr.ptr_; } mutable nbr_t* ptr_; Table& table_; }; using nbr_ptr_t = MutableTableNbr; MutableNbrSliceMut(MutableNbrSliceMut<size_t> slice, Table& table) : slice_(slice), table_(table) {} ~MutableNbrSliceMut() = default; void set_size(int size) { slice_.set_size(size); } int size() const { return slice_.size(); } int field_num() const { return table_.col_num(); } void set_begin(MutableNbr<size_t>* ptr) { slice_.set_begin(ptr); } nbr_ptr_t begin() { return MutableTableNbr(slice_.begin(), table_); } nbr_ptr_t end() { return MutableTableNbr(slice_.end(), table_); } static MutableNbrSliceMut empty(Table& table) { MutableNbrSliceMut ret(MutableNbrSliceMut<size_t>::empty(), table); return ret; } MutableNbrSliceMut<size_t> slice_; Table& table_; }; } // namespace gs #endif // STORAGES_RT_MUTABLE_GRAPH_CSR_NBR_H_