aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/tvmauth/client/misc/roles/entities_index.h
blob: 50ecacd77ffd5a1e071eb24aa05914e1a74701a4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#pragma once 
 
#include "types.h" 
 
#include <library/cpp/tvmauth/client/exception.h> 
 
#include <set> 
#include <vector> 
 
namespace NTvmAuth::NRoles { 
    class TEntitiesIndex: TMoveOnly { 
    public: 
        struct TSubTree; 
        using TIdxByAttrs = THashMap<TKeyValue, TSubTree>; 
 
        struct TSubTree { 
            std::vector<TEntityPtr> Entities; 
            TIdxByAttrs SubTree; 
        }; 
 
        class TStage { 
        public: 
            TStage(const std::set<TString>& k); 
 
            bool GetNextKeySet(std::vector<TString>& out); 
 
        private: 
            std::vector<TString> Keys_; 
            size_t Id_ = 0; 
        }; 
 
    public: 
        TEntitiesIndex(const std::vector<TEntityPtr>& entities); 
 
        /** 
         * Iterators must be to sorted unique key/value 
         */ 
        template <typename Iterator> 
        bool ContainsExactEntity(Iterator begin, Iterator end) const; 
 
        /** 
         * Iterators must be to sorted unique key/value 
         */ 
        template <typename Iterator> 
        const std::vector<TEntityPtr>& GetEntitiesWithAttrs(Iterator begin, Iterator end) const; 
 
    public: // for tests 
        static std::set<TString> GetUniqueSortedKeys(const std::vector<TEntityPtr>& entities); 
        static void MakeUnique(TEntitiesIndex::TSubTree& branch); 
 
        TString PrintDebugString() const; 
 
    private: 
        template <typename Iterator> 
        const TSubTree* FindSubtree(Iterator begin, Iterator end, size_t& size) const; 
 
    private: 
        TSubTree Idx_; 
        std::vector<TEntityPtr> EmptyResult_; 
    }; 
 
    template <typename Iterator> 
    bool TEntitiesIndex::ContainsExactEntity(Iterator begin, Iterator end) const { 
        size_t size = 0; 
        const TSubTree* subtree = FindSubtree(begin, end, size); 
        if (!subtree) { 
            return false; 
        } 
 
        auto res = std::find_if( 
            subtree->Entities.begin(), 
            subtree->Entities.end(), 
            [size](const auto& e) { return size == e->size(); }); 
        return res != subtree->Entities.end(); 
    } 
 
    template <typename Iterator> 
    const std::vector<TEntityPtr>& TEntitiesIndex::GetEntitiesWithAttrs(Iterator begin, Iterator end) const { 
        size_t size = 0; 
        const TSubTree* subtree = FindSubtree(begin, end, size); 
        if (!subtree) { 
            return EmptyResult_; 
        } 
 
        return subtree->Entities; 
    } 
 
    template <typename Iterator> 
    const TEntitiesIndex::TSubTree* TEntitiesIndex::FindSubtree(Iterator begin, 
                                                                Iterator end, 
                                                                size_t& size) const { 
        const TSubTree* subtree = &Idx_; 
        size = 0; 
 
        for (auto attr = begin; attr != end; ++attr) { 
            auto it = subtree->SubTree.find(TKeyValueView{attr->first, attr->second}); 
            if (it == subtree->SubTree.end()) { 
                return nullptr; 
            } 
 
            ++size; 
            subtree = &it->second; 
        } 
 
        return subtree; 
    } 
}