2 * Eddie Kohler, Yandong Mao, Robert Morris
3 * Copyright (c) 2012-2014 President and Fellows of Harvard College
4 * Copyright (c) 2012-2014 Massachusetts Institute of Technology
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, subject to the conditions
9 * listed in the Masstree LICENSE file. These conditions include: you must
10 * preserve this copyright notice, and you cannot mention the copyright
11 * holders in advertising related to the Software without their permission.
12 * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
13 * notice is a summary of the Masstree LICENSE file; the license in that file
18 #include "kpermuter.hh"
20 template <typename KA, typename T>
21 struct key_comparator {
22 int operator()(const KA& ka, const T& n, int p) {
23 return n.compare_key(ka, p);
27 struct key_indexed_position {
30 inline key_indexed_position() {
32 inline constexpr key_indexed_position(int i_, int p_)
38 template <typename KA, typename T, typename F>
39 int key_upper_bound_by(const KA& ka, const T& n, F comparator)
41 typename key_permuter<T>::type perm = key_permuter<T>::permutation(n);
42 int l = 0, r = perm.size();
46 int cmp = comparator(ka, n, mp);
57 template <typename KA, typename T>
58 inline int key_upper_bound(const KA& ka, const T& n)
60 return key_upper_bound_by(ka, n, key_comparator<KA, T>());
63 template <typename KA, typename T, typename F>
64 key_indexed_position key_lower_bound_by(const KA& ka, const T& n, F comparator)
66 typename key_permuter<T>::type perm = key_permuter<T>::permutation(n);
67 int l = 0, r = perm.size();
71 int cmp = comparator(ka, n, mp);
75 return key_indexed_position(m, mp);
79 return key_indexed_position(l, -1);
82 template <typename KA, typename T>
83 inline key_indexed_position key_lower_bound(const KA& ka, const T& n)
85 return key_lower_bound_by(ka, n, key_comparator<KA, T>());
89 template <typename KA, typename T, typename F>
90 int key_find_upper_bound_by(const KA& ka, const T& n, F comparator)
92 typename key_permuter<T>::type perm = key_permuter<T>::permutation(n);
93 int l = 0, r = perm.size();
96 int cmp = comparator(ka, n, lp);
105 template <typename KA, typename T, typename F>
106 key_indexed_position key_find_lower_bound_by(const KA& ka, const T& n, F comparator)
108 typename key_permuter<T>::type perm = key_permuter<T>::permutation(n);
109 int l = 0, r = perm.size();
112 int cmp = comparator(ka, n, lp);
116 return key_indexed_position(l, lp);
120 return key_indexed_position(l, -1);
124 struct key_bound_binary {
125 static constexpr bool is_binary = true;
126 template <typename KA, typename T>
127 static inline int upper(const KA& ka, const T& n) {
128 return key_upper_bound_by(ka, n, key_comparator<KA, T>());
130 template <typename KA, typename T>
131 static inline key_indexed_position lower(const KA& ka, const T& n) {
132 return key_lower_bound_by(ka, n, key_comparator<KA, T>());
134 template <typename KA, typename T, typename F>
135 static inline key_indexed_position lower_by(const KA& ka, const T& n, F comparator) {
136 return key_lower_bound_by(ka, n, comparator);
140 struct key_bound_linear {
141 static constexpr bool is_binary = false;
142 template <typename KA, typename T>
143 static inline int upper(const KA& ka, const T& n) {
144 return key_find_upper_bound_by(ka, n, key_comparator<KA, T>());
146 template <typename KA, typename T>
147 static inline key_indexed_position lower(const KA& ka, const T& n) {
148 return key_find_lower_bound_by(ka, n, key_comparator<KA, T>());
150 template <typename KA, typename T, typename F>
151 static inline key_indexed_position lower_by(const KA& ka, const T& n, F comparator) {
152 return key_find_lower_bound_by(ka, n, comparator);
158 bound_method_fast = 0,
162 template <int max_size, int method = bound_method_fast> struct key_bound {};
163 template <int max_size> struct key_bound<max_size, bound_method_binary> {
164 typedef key_bound_binary type;
166 template <int max_size> struct key_bound<max_size, bound_method_linear> {
167 typedef key_bound_linear type;
169 template <int max_size> struct key_bound<max_size, bound_method_fast> {
170 typedef typename key_bound<max_size, (max_size > 16 ? bound_method_binary : bound_method_linear)>::type type;