pacemaker 2.1.4-dc6eb4362e
Scalable High-Availability cluster resource manager
scores.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2022 the Pacemaker project contributors
3 *
4 * The version control history for this file may have further details.
5 *
6 * This source code is licensed under the GNU Lesser General Public License
7 * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8 */
9
10#include <crm_internal.h>
11
12#ifndef _GNU_SOURCE
13# define _GNU_SOURCE
14#endif
15
16#include <stdio.h> // snprintf(), NULL
17#include <string.h> // strcpy(), strdup()
18#include <sys/types.h> // size_t
19
23
35int
36char2score(const char *score)
37{
38 if (score == NULL) {
39 return 0;
40
41 } else if (pcmk_str_is_minus_infinity(score)) {
42 return -CRM_SCORE_INFINITY;
43
44 } else if (pcmk_str_is_infinity(score)) {
45 return CRM_SCORE_INFINITY;
46
47 } else if (pcmk__str_eq(score, PCMK__VALUE_RED, pcmk__str_casei)) {
48 return pcmk__score_red;
49
50 } else if (pcmk__str_eq(score, PCMK__VALUE_YELLOW, pcmk__str_casei)) {
51 return pcmk__score_yellow;
52
53 } else if (pcmk__str_eq(score, PCMK__VALUE_GREEN, pcmk__str_casei)) {
54 return pcmk__score_green;
55
56 } else {
57 long long score_ll;
58
59 pcmk__scan_ll(score, &score_ll, 0LL);
60 if (score_ll > CRM_SCORE_INFINITY) {
61 return CRM_SCORE_INFINITY;
62
63 } else if (score_ll < -CRM_SCORE_INFINITY) {
64 return -CRM_SCORE_INFINITY;
65
66 } else {
67 return (int) score_ll;
68 }
69 }
70}
71
84char *
85score2char_stack(int score, char *buf, size_t len)
86{
87 CRM_CHECK((buf != NULL) && (len >= sizeof(CRM_MINUS_INFINITY_S)),
88 return NULL);
89
90 if (score >= CRM_SCORE_INFINITY) {
91 strcpy(buf, CRM_INFINITY_S);
92 } else if (score <= -CRM_SCORE_INFINITY) {
93 strcpy(buf, CRM_MINUS_INFINITY_S);
94 } else {
95 snprintf(buf, len, "%d", score);
96 }
97 return buf;
98}
99
113char *
114score2char(int score)
115{
116 char *result = NULL;
117
118 if (score >= CRM_SCORE_INFINITY) {
119 result = strdup(CRM_INFINITY_S);
120 CRM_ASSERT(result != NULL);
121
122 } else if (score <= -CRM_SCORE_INFINITY) {
124 CRM_ASSERT(result != NULL);
125
126 } else {
127 result = pcmk__itoa(score);
128 }
129 return result;
130}
131
139int
140pcmk__add_scores(int score1, int score2)
141{
142 int result = score1 + score2;
143
144 // First handle the cases where one or both is infinite
145
146 if (score1 <= -CRM_SCORE_INFINITY) {
147
148 if (score2 <= -CRM_SCORE_INFINITY) {
149 crm_trace("-INFINITY + -INFINITY = -INFINITY");
150 } else if (score2 >= CRM_SCORE_INFINITY) {
151 crm_trace("-INFINITY + +INFINITY = -INFINITY");
152 } else {
153 crm_trace("-INFINITY + %d = -INFINITY", score2);
154 }
155
156 return -CRM_SCORE_INFINITY;
157
158 } else if (score2 <= -CRM_SCORE_INFINITY) {
159
160 if (score1 >= CRM_SCORE_INFINITY) {
161 crm_trace("+INFINITY + -INFINITY = -INFINITY");
162 } else {
163 crm_trace("%d + -INFINITY = -INFINITY", score1);
164 }
165
166 return -CRM_SCORE_INFINITY;
167
168 } else if (score1 >= CRM_SCORE_INFINITY) {
169
170 if (score2 >= CRM_SCORE_INFINITY) {
171 crm_trace("+INFINITY + +INFINITY = +INFINITY");
172 } else {
173 crm_trace("+INFINITY + %d = +INFINITY", score2);
174 }
175
176 return CRM_SCORE_INFINITY;
177
178 } else if (score2 >= CRM_SCORE_INFINITY) {
179 crm_trace("%d + +INFINITY = +INFINITY", score1);
180 return CRM_SCORE_INFINITY;
181 }
182
183 /* As long as CRM_SCORE_INFINITY is less than half of the maximum integer,
184 * we can ignore the possibility of integer overflow
185 */
186
187 // Bound result to infinity
188
189 if (result >= CRM_SCORE_INFINITY) {
190 crm_trace("%d + %d = +INFINITY", score1, score2);
191 return CRM_SCORE_INFINITY;
192
193 } else if (result <= -CRM_SCORE_INFINITY) {
194 crm_trace("%d + %d = -INFINITY", score1, score2);
195 return -CRM_SCORE_INFINITY;
196 }
197
198 crm_trace("%d + %d = %d", score1, score2, result);
199 return result;
200}
bool pcmk_str_is_infinity(const char *s)
Definition: utils.c:513
bool pcmk_str_is_minus_infinity(const char *s)
Definition: utils.c:518
#define CRM_SCORE_INFINITY
Definition: crm.h:85
#define CRM_INFINITY_S
Definition: crm.h:86
#define CRM_MINUS_INFINITY_S
Definition: crm.h:88
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:226
#define crm_trace(fmt, args...)
Definition: logging.h:364
#define PCMK__VALUE_RED
#define PCMK__VALUE_GREEN
#define PCMK__VALUE_YELLOW
pcmk__action_result_t result
Definition: pcmk_fence.c:34
#define CRM_ASSERT(expr)
Definition: results.h:42
int pcmk__score_yellow
Definition: scores.c:22
char * score2char_stack(int score, char *buf, size_t len)
Convert an integer score to a string, using a provided buffer.
Definition: scores.c:85
int pcmk__add_scores(int score1, int score2)
Definition: scores.c:140
char * score2char(int score)
Return the string equivalent of an integer score.
Definition: scores.c:114
int char2score(const char *score)
Get the integer value of a score string.
Definition: scores.c:36
int pcmk__score_green
Definition: scores.c:21
int pcmk__score_red
Definition: scores.c:20
int pcmk__scan_ll(const char *text, long long *result, long long default_value)
Definition: strings.c:97
@ pcmk__str_casei