/* * include/framework/interface/Record.h * * Copyright (C) 2023 Douglas Rumbaugh * * Distributed under the Modified BSD License. * * FIXME: the record implementations could probably be broken out into * different files, leaving only the interface here */ #pragma once #include #include #include #include "psu-util/hash.h" namespace de { template concept RecordInterface = requires(R r, R s) { { r < s } ->std::convertible_to; { r == s } ->std::convertible_to; }; template concept WeightedRecordInterface = requires(R r) { {r.weight} -> std::convertible_to; }; template concept NDRecordInterface = RecordInterface && requires(R r, R s) { {r.calc_distance(s)} -> std::convertible_to; }; template concept KVPInterface = RecordInterface && requires(R r) { r.key; r.value; }; template concept AlexInterface = KVPInterface && requires(R r) { {r.key} -> std::convertible_to; {r.value} -> std::convertible_to; }; template concept WrappedInterface = RecordInterface && requires(R r, R s, bool b) { {r.header} -> std::convertible_to; r.rec; {r.set_delete()}; {r.is_deleted()} -> std::convertible_to; {r.set_tombstone(b)}; {r.is_tombstone()} -> std::convertible_to; {r.set_timestamp()}; {r.get_timestamp()} -> std::convertible_to; {r.clear_timestamp()}; {r.is_deleted()} -> std::convertible_to; {r.set_visible()}; {r < s} -> std::convertible_to; {r == s} ->std::convertible_to; }; template struct Wrapped { uint32_t header; R rec; inline void set_delete() { header |= 2; } inline bool is_deleted() const { return header & 2; } inline void set_visible() { header |= 4; } inline bool is_visible() const { return header & 4; } inline void set_timestamp(int ts) { header |= (ts << 3); } inline int get_timestamp() const { return header >> 3; } inline void clear_timestamp() { header &= 7; } inline void set_tombstone(bool val=true) { if (val) { header |= 1; } else { header &= 0; } } inline bool is_tombstone() const { return header & 1; } inline bool operator<(const Wrapped& other) const { return rec < other.rec || (rec == other.rec && header < other.header); } inline bool operator==(const Wrapped& other) const { return rec == other.rec; } }; template struct Record { K key; V value; inline bool operator<(const Record& other) const { return key < other.key || (key == other.key && value < other.value); } inline bool operator==(const Record& other) const { return key == other.key && value == other.value; } }; template struct WeightedRecord { K key; V value; W weight = 1; inline bool operator==(const WeightedRecord& other) const { return key == other.key && value == other.value; } inline bool operator<(const WeightedRecord& other) const { return key < other.key || (key == other.key && value < other.value); } }; template struct CosinePoint{ V data[D]; inline bool operator==(const CosinePoint& other) const { for (size_t i=0; i other.data[i]) { return false; } } return false; } inline double calc_distance(const CosinePoint& other) const { double prod = 0; double asquared = 0; double bsquared = 0; for (size_t i=0; i struct EuclidPoint{ V data[D]; inline bool operator==(const EuclidPoint& other) const { for (size_t i=0; i other.data[i]) { return false; } } return false; } inline double calc_distance(const EuclidPoint& other) const { double dist = 0; for (size_t i=0; i struct RecordHash { size_t operator()(R const &rec) const { return psudb::hash_bytes((std::byte *) &rec, sizeof(R)); } }; template class DistCmpMax { public: DistCmpMax(R *baseline) : P(baseline) {} inline bool operator()(const R *a, const R *b) requires WrappedInterface { return a->rec.calc_distance(P->rec) > b->rec.calc_distance(P->rec); } inline bool operator()(const R *a, const R *b) requires (!WrappedInterface){ return a->calc_distance(*P) > b->calc_distance(*P); } private: R *P; }; }