Motr  M0
graph.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2014-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 
30 #include "lib/assert.h"
31 #include "lib/misc.h" /* M0_SET0, ARRAY_SIZE */
32 
33 #include "graph/graph.h"
34 #include "graph/graph_xc.h"
35 
36 static struct m0_garc *arc_get(const struct m0_gvertice *src,
37  const struct m0_garc_type *atype);
38 static struct m0_gvertice *arc_try(const struct m0_gvertice *vertice,
39  const struct m0_garc_type *atype);
40 
41 static void graph_add(struct m0_graph *g, struct m0_gvertice *vertice);
42 static void graph_del(struct m0_graph *g, struct m0_gvertice *vertice);
43 
44 static struct m0_garc_type GRAPH_PREV;
45 static struct m0_garc_type GRAPH_NEXT;
46 
47 static void vertice_init(struct m0_gvertice *vertice,
48  const struct m0_gvertice_type *vt,
49  const struct m0_fid *fid);
50 
51 static bool has_arc(const struct m0_gvertice *vertice,
52  const struct m0_garc_type *atype);
53 
54 static const struct m0_gvertice_type *vtype(const struct m0_gvertice *src);
55 
56 enum { VTYPE_MAX = 256 };
57 
58 static const struct m0_gvertice_type *vtypes[VTYPE_MAX];
59 
61  const struct m0_garc_type *atype)
62 {
63  struct m0_garc *arc;
64 
67  M0_PRE(has_arc(src, atype));
68  M0_PRE(has_arc(dst, atype));
69  M0_PRE(!m0_gvertice_is_set(src, atype));
70  M0_PRE(ergo(atype->at_reverse != NULL,
71  !m0_gvertice_is_set(dst, atype->at_reverse)));
72 
73  arc = arc_get(src, atype);
74  arc->as_fid = dst->vh_fid;
75  m0_cookie_init(&arc->as_local, &dst->vh_gen);
76 
77  if (atype->at_reverse != NULL) {
78  arc = arc_get(dst, atype->at_reverse);
79  arc->as_fid = src->vh_fid;
80  m0_cookie_init(&arc->as_local, &src->vh_gen);
81  }
82 
86  M0_POST(ergo(atype->at_reverse != NULL,
88 }
89 
91  const struct m0_garc_type *atype)
92 {
95  M0_PRE(has_arc(src, atype));
96  M0_PRE(has_arc(dst, atype));
97  M0_PRE(m0_gvertice_linked(src, dst, atype));
98  M0_PRE(ergo(atype->at_reverse != NULL,
100 
101  M0_SET0(arc_get(src, atype));
102 
103  if (atype->at_reverse != NULL)
104  M0_SET0(arc_get(dst, atype->at_reverse));
105 
108  M0_POST(!m0_gvertice_is_set(src, atype));
109  M0_POST(ergo(atype->at_reverse != NULL,
110  !m0_gvertice_is_set(dst, atype->at_reverse)));
111 }
112 
113 bool m0_gvertice_linked(const struct m0_gvertice *src,
114  const struct m0_gvertice *dst,
115  const struct m0_garc_type *atype)
116 {
119  M0_PRE(has_arc(src, atype));
120  M0_PRE(has_arc(dst, atype));
121 
122  return m0_fid_eq(&arc_get(src, atype)->as_fid, &dst->vh_fid);
123 }
124 
125 bool m0_gvertice_is_set(const struct m0_gvertice *vertice,
126  const struct m0_garc_type *atype)
127 {
128  M0_PRE(m0_gvertice_invariant(vertice));
129  M0_PRE(has_arc(vertice, atype));
130 
131  return m0_fid_is_set(&arc_get(vertice, atype)->as_fid);
132 }
133 
134 void m0_gvertice_init(struct m0_graph *g, struct m0_gvertice *vertice,
135  const struct m0_gvertice_type *vt,
136  const struct m0_fid *fid)
137 {
138  vertice_init(vertice, vt, fid);
139  graph_add(g, vertice);
140  M0_POST(m0_gvertice_invariant(vertice));
141 }
142 
143 void m0_gvertice_fini(struct m0_graph *g, struct m0_gvertice *vertice)
144 {
145  M0_PRE(m0_gvertice_invariant(vertice));
146  graph_del(g, vertice);
147  M0_POST(m0_forall(i, vtype(vertice)->vt_arc_nr,
148  !m0_gvertice_is_set(vertice,
149  vtype(vertice)->vt_arc[i])));
150 }
151 
152 bool m0_gvertice_invariant(const struct m0_gvertice *vertice)
153 {
154  const struct m0_gvertice_type *vt = vtype(vertice);
155  return
157  _0C(m0_forall(i, vt->vt_arc_nr,
158  m0_garc_type_invariant(vt, vt->vt_arc[i])));
159 }
160 
162 {
163  return
164  _0C(vtypes[vt->vt_id] == vt) &&
165  _0C(vt->vt_xt->xct_aggr == M0_XA_RECORD) &&
166  m0_forall(i, vt->vt_arc_nr,
167  _0C(m0_garc_type_invariant(vt, vt->vt_arc[i])));
168 
169 }
170 
172  const struct m0_garc_type *atype)
173 {
174  const struct m0_xcode_type *xt = vt->vt_xt;
175 
176  return
177  _0C(atype->at_field < xt->xct_nr) &&
178  _0C(xt->xct_child[atype->at_field].xf_type == m0_garc_xc);
179 }
180 
181 bool m0_graph_invariant(const struct m0_graph *graph)
182 {
183  return true;
184 }
185 
186 struct m0_gvertice *m0_garc_try(const struct m0_gvertice *vertice,
187  const struct m0_garc_type *atype)
188 {
189  M0_PRE(m0_gvertice_invariant(vertice));
190  return arc_try(vertice, atype);
191 }
192 
194 {
196  M0_PRE(vtypes[vt->vt_id] == NULL);
197  M0_PRE(vt->vt_arc_nr < ARRAY_SIZE(vt->vt_arc) - 1);
198  vtypes[vt->vt_id] = vt;
199 
202 
204 }
205 
206 void m0_garc_type_register(const struct m0_garc_type *atype)
207 {
208 }
209 
211  struct m0_garc_type *reverse)
212 {
213  direct->at_reverse = reverse;
214  reverse->at_reverse = direct;
215 }
216 
218  const struct m0_garc_type *atype)
219 {
220  M0_PRE(vt->vt_arc_nr < ARRAY_SIZE(vt->vt_arc) - 1);
221  vt->vt_arc[vt->vt_arc_nr++] = atype;
222  M0_POST(m0_garc_type_invariant(vt, atype));
223 }
224 
225 static struct m0_gvertice *arc_try(const struct m0_gvertice *vertice,
226  const struct m0_garc_type *atype)
227 {
228  return m0_cookie_of(&arc_get(vertice, atype)->as_local,
229  struct m0_gvertice, vh_gen);
230 }
231 
232 int m0_garc_follow(const struct m0_gvertice *vertice,
233  const struct m0_garc_type *atype, ...)
234 {
235  M0_IMPOSSIBLE("Not implemented.");
236  return 0;
237 }
238 
239 static struct m0_garc *arc_get(const struct m0_gvertice *src,
240  const struct m0_garc_type *atype)
241 {
242  return m0_xcode_addr(&M0_XCODE_OBJ(vtype(src)->vt_xt,
243  /* suppress const */
244  (struct m0_gvertice *)src),
245  atype->at_field, 0);
246 }
247 
248 static void vertice_init(struct m0_gvertice *vertice,
249  const struct m0_gvertice_type *vt,
250  const struct m0_fid *fid)
251 {
252  vertice->vh_typeid = vt->vt_id;
253  vertice->vh_fid = *fid;
254  m0_cookie_new(&vertice->vh_gen);
255 }
256 
257 static void graph_add(struct m0_graph *g, struct m0_gvertice *vertice)
258 {
259  struct m0_gvertice *tail = m0_garc_try(&g->g_anchor, &GRAPH_PREV);
260 
262  M0_PRE(tail != NULL);
263  m0_gvertice_unlink(tail, &g->g_anchor, &GRAPH_NEXT);
264  m0_gvertice_link(tail, vertice, &GRAPH_NEXT);
265  m0_gvertice_link(vertice, &g->g_anchor, &GRAPH_NEXT);
266 
267  M0_POST(m0_garc_try(&g->g_anchor, &GRAPH_PREV) == vertice);
269 }
270 
271 static void graph_del(struct m0_graph *g, struct m0_gvertice *vertice)
272 {
273  struct m0_gvertice *prev = m0_garc_try(vertice, &GRAPH_PREV);
274  struct m0_gvertice *next = m0_garc_try(vertice, &GRAPH_NEXT);
275 
277  M0_PRE(prev != NULL);
278  M0_PRE(next != NULL);
279  m0_gvertice_unlink(vertice, prev, &GRAPH_PREV);
280  m0_gvertice_unlink(vertice, next, &GRAPH_NEXT);
283 }
284 
285 static const struct m0_gvertice_type *vtype(const struct m0_gvertice *vertice)
286 {
287  M0_PRE(IS_IN_ARRAY(vertice->vh_typeid, vtypes));
288  return vtypes[vertice->vh_typeid];
289 }
290 
291 static bool has_arc(const struct m0_gvertice *vertice,
292  const struct m0_garc_type *arc)
293 {
294  const struct m0_gvertice_type *vt = vtype(vertice);
295  return m0_exists(i, vt->vt_arc_nr, vt->vt_arc[i] == arc);
296 }
297 
298 static struct m0_garc_type GRAPH_NEXT = {
299  .at_name = "next in graph",
300  .at_field = 1
301 };
302 
303 static struct m0_garc_type GRAPH_PREV = {
304  .at_name = "prev in graph",
305  .at_field = 2
306 };
307 
308 M0_INTERNAL int m0_graph_mod_init(void)
309 {
313  return 0;
314 }
315 
316 M0_INTERNAL void m0_graph_mod_fini(void)
317 {;}
318 
321 /*
322  * Local variables:
323  * c-indentation-style: "K&R"
324  * c-basic-offset: 8
325  * tab-width: 8
326  * fill-column: 80
327  * scroll-step: 1
328  * End:
329  */
330 /*
331  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
332  */
M0_INTERNAL void * m0_xcode_addr(const struct m0_xcode_obj *obj, int fileno, uint64_t elno)
Definition: xcode.c:612
#define M0_PRE(cond)
const struct m0_xcode_type * xf_type
Definition: xcode.h:253
#define NULL
Definition: misc.h:38
static struct m0_bufvec dst
Definition: xform.c:61
#define ergo(a, b)
Definition: misc.h:293
uint64_t vh_gen
Definition: graph.h:60
void m0_gvertice_fini(struct m0_graph *g, struct m0_gvertice *vertice)
Definition: graph.c:143
size_t xct_nr
Definition: xcode.h:343
static bool has_arc(const struct m0_gvertice *vertice, const struct m0_garc_type *atype)
Definition: graph.c:291
Definition: graph.h:51
struct m0_xcode_field xct_child[0]
Definition: xcode.h:345
static struct m0_garc * arc_get(const struct m0_gvertice *src, const struct m0_garc_type *atype)
Definition: graph.c:239
#define m0_exists(var, nr,...)
Definition: misc.h:134
M0_INTERNAL void m0_graph_mod_fini(void)
Definition: graph.c:316
void m0_gvertice_type_register(struct m0_gvertice_type *vt)
Definition: graph.c:193
static void graph_del(struct m0_graph *g, struct m0_gvertice *vertice)
Definition: graph.c:271
#define M0_SET0(obj)
Definition: misc.h:64
static struct m0_xcode_type ** xt[]
Definition: protocol.c:64
M0_INTERNAL bool m0_fid_is_set(const struct m0_fid *fid)
Definition: fid.c:106
size_t at_field
Definition: graph.h:82
const struct m0_garc_type * vt_arc[M0_GRAPH_ARC_PER_NODE_MAX]
Definition: graph.h:77
struct m0_fid fid
Definition: di.c:46
static struct m0_garc_type GRAPH_PREV
Definition: graph.c:44
bool m0_gvertice_is_set(const struct m0_gvertice *vertice, const struct m0_garc_type *atype)
Definition: graph.c:125
bool m0_gvertice_type_invariant(const struct m0_gvertice_type *vt)
Definition: graph.c:161
uint64_t vt_id
Definition: graph.h:73
int i
Definition: dir.c:1033
M0_INTERNAL int m0_graph_mod_init(void)
Definition: graph.c:308
uint64_t vh_typeid
Definition: graph.h:58
void m0_gvertice_init(struct m0_graph *g, struct m0_gvertice *vertice, const struct m0_gvertice_type *vt, const struct m0_fid *fid)
Definition: graph.c:134
static struct m0_garc_type GRAPH_NEXT
Definition: graph.c:45
static int next[]
Definition: cp.c:248
uint32_t vt_arc_nr
Definition: graph.h:76
bool m0_garc_type_invariant(const struct m0_gvertice_type *vt, const struct m0_garc_type *atype)
Definition: graph.c:171
struct m0_fid as_fid
Definition: graph.h:52
#define M0_POST(cond)
const struct m0_xcode_type * vt_xt
Definition: graph.h:75
void m0_gvertice_unlink(struct m0_gvertice *src, struct m0_gvertice *dst, const struct m0_garc_type *atype)
Definition: graph.c:90
bool m0_gvertice_linked(const struct m0_gvertice *src, const struct m0_gvertice *dst, const struct m0_garc_type *atype)
Definition: graph.c:113
static const struct m0_gvertice_type * vtype(const struct m0_gvertice *src)
Definition: graph.c:285
void m0_garc_type_register(const struct m0_garc_type *atype)
Definition: graph.c:206
struct m0_fid vh_fid
Definition: graph.h:59
struct m0_gvertice * m0_garc_try(const struct m0_gvertice *vertice, const struct m0_garc_type *atype)
Definition: graph.c:186
struct m0_cookie as_local
Definition: graph.h:53
static void vertice_init(struct m0_gvertice *vertice, const struct m0_gvertice_type *vt, const struct m0_fid *fid)
Definition: graph.c:248
void m0_gvertice_link(struct m0_gvertice *src, struct m0_gvertice *dst, const struct m0_garc_type *atype)
Definition: graph.c:60
M0_INTERNAL bool m0_fid_eq(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:164
#define m0_forall(var, nr,...)
Definition: misc.h:112
enum m0_xcode_aggr xct_aggr
Definition: xcode.h:316
const char * at_name
Definition: graph.h:81
Definition: fid.h:38
void m0_garc_type_pair_register(struct m0_garc_type *direct, struct m0_garc_type *reverse)
Definition: graph.c:210
const struct m0_garc_type * at_reverse
Definition: graph.h:83
void m0_garc_type_add(struct m0_gvertice_type *vt, const struct m0_garc_type *atype)
Definition: graph.c:217
#define _0C(exp)
Definition: assert.h:311
#define IS_IN_ARRAY(idx, array)
Definition: misc.h:311
#define M0_XCODE_OBJ(type, ptr)
Definition: xcode.h:962
static void graph_add(struct m0_graph *g, struct m0_gvertice *vertice)
Definition: graph.c:257
bool m0_gvertice_invariant(const struct m0_gvertice *vertice)
Definition: graph.c:152
static const struct m0_gvertice_type * vtypes[VTYPE_MAX]
Definition: graph.c:58
static struct m0_gvertice * arc_try(const struct m0_gvertice *vertice, const struct m0_garc_type *atype)
Definition: graph.c:225
static struct gen g[MAX_GEN]
Definition: beck.c:521
struct m0_pdclust_src_addr src
Definition: fd.c:108
bool m0_graph_invariant(const struct m0_graph *graph)
Definition: graph.c:181
int m0_garc_follow(const struct m0_gvertice *vertice, const struct m0_garc_type *atype,...)
Definition: graph.c:232
Definition: graph.h:66
#define ARRAY_SIZE(a)
Definition: misc.h:45
static int tail(struct m0_sm *mach)
Definition: sm.c:474
#define M0_IMPOSSIBLE(fmt,...)