Motr  M0
combinations.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2016-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_LIB
24 #include "lib/trace.h"
25 
31 M0_INTERNAL uint64_t m0_fact(uint64_t n)
32 {
33  M0_PRE(n > 0);
34 
35  return n == 1 || n == 0 ? 1 : n * m0_fact(n - 1);
36 }
37 
38 M0_INTERNAL uint32_t m0_ncr(uint64_t n, uint64_t r)
39 {
40  uint64_t i;
41  uint64_t m = n;
42 
43  M0_PRE(n >= r);
44 
45  if (r == 0)
46  return 1;
47  for (i = 1; i < r; i++)
48  m *= n - i;
49  return m / m0_fact(r);
50 }
51 
52 M0_INTERNAL int m0_combination_index(int N, int K, int *x)
53 {
54  int m;
55  int q;
56  int n;
57  int r;
58  int idx = 0;
59 
60  M0_ENTRY("N:%d K=%d", N, K);
61  M0_PRE(0 < K && K <= N);
62  M0_PRE(m0_forall(i, K, x[i] < N));
63 
64  for (q = 0; q < x[0]; q++) {
65  n = N - (q + 1);
66  r = K - 1;
67  idx += m0_ncr(n, r);
68  }
69  for (m = 1; m < K; m++) {
70  for (q = 0; q < (x[m] - x[m - 1] - 1); q++) {
71  n = N - (x[m - 1] + 1) - (q + 1);
72  r = K - m - 1;
73  idx += m0_ncr(n, r);
74  }
75  }
76  return M0_RC(idx);
77 }
78 
79 M0_INTERNAL void m0_combination_inverse(int cid, int N, int K, int *x)
80 {
81  int m;
82  int q;
83  int n;
84  int r;
85  int idx = 0;
86  int old_idx = 0;
87  int i = 0;
88  int j;
89 
90  M0_ENTRY("N:%d K=%d cid:%d \n", N, K, cid);
91  M0_PRE(0 < K && K <= N);
92 
93  for (q = 0; idx < cid + 1; q++) {
94  old_idx = idx;
95  n = N - (q + 1);
96  r = K - 1;
97  idx += m0_ncr(n, r);
98  }
99  idx = old_idx;
100  x[i++] = q - 1;
101 
102  for (m = 1; m < K; m++) {
103  for (q = 0; idx < cid + 1; q++) {
104  old_idx = idx;
105  n = N - (x[i - 1] + 1) - (q + 1);
106  r = K - m - 1;
107  idx += m0_ncr(n, r);
108  }
109  if (idx >= cid + 1)
110  idx = old_idx;
111  x[i] = x[i - 1] + q;
112  i++;
113  }
114 
115  M0_LOG(M0_DEBUG, "Combinations");
116  for (j = 0; j < i; j++)
117  M0_LOG(M0_DEBUG, "%d \t", x[j]);
118  M0_LEAVE();
119 }
120 
121 #undef M0_TRACE_SUBSYSTEM
122 
125 /*
126  * Local variables:
127  * c-indentation-style: "K&R"
128  * c-basic-offset: 8
129  * tab-width: 8
130  * fill-column: 80
131  * scroll-step: 1
132  * End:
133  */
#define M0_PRE(cond)
static struct m0_semaphore q
Definition: rwlock.c:55
static struct m0_addb2_mach * m
Definition: consumer.c:38
static bool x
Definition: sm.c:168
#define M0_LOG(level,...)
Definition: trace.h:167
M0_LEAVE()
M0_INTERNAL void m0_combination_inverse(int cid, int N, int K, int *x)
Definition: combinations.c:79
#define N(i)
return M0_RC(rc)
#define M0_ENTRY(...)
Definition: trace.h:170
int i
Definition: dir.c:1033
M0_INTERNAL int m0_combination_index(int N, int K, int *x)
Definition: combinations.c:52
M0_INTERNAL uint32_t m0_ncr(uint64_t n, uint64_t r)
Definition: combinations.c:38
#define m0_forall(var, nr,...)
Definition: misc.h:112
uint64_t n
Definition: fops.h:107
static int r[NR]
Definition: thread.c:46
M0_INTERNAL uint64_t m0_fact(uint64_t n)
Definition: combinations.c:31