]> git.proxmox.com Git - ceph.git/blob - ceph/src/cls/numops/cls_numops.cc
import 15.2.0 Octopus source
[ceph.git] / ceph / src / cls / numops / cls_numops.cc
1 /*
2 * Ceph - scalable distributed file system
3 *
4 * Copyright (C) 2015 CERN
5 *
6 * Author: Joaquim Rocha <joaquim.rocha@cern.ch>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 */
14
15 /** \file
16 *
17 * This is an OSD class that implements methods for object numeric options on
18 * its omap values.
19 *
20 */
21
22 #include "objclass/objclass.h"
23 #include <errno.h>
24 #include <string>
25 #include <sstream>
26 #include <cstdio>
27 #include <include/compat.h>
28
29 #define DECIMAL_PRECISION 10
30
31 using ceph::bufferlist;
32 using std::string;
33 using ceph::decode;
34 using ceph::encode;
35
36 CLS_VER(1,0)
37 CLS_NAME(numops)
38
39 static int add(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
40 {
41 string key, diff_str;
42
43 auto iter = in->cbegin();
44 try {
45 decode(key, iter);
46 decode(diff_str, iter);
47 } catch (const buffer::error &err) {
48 CLS_LOG(20, "add: invalid decode of input");
49 return -EINVAL;
50 }
51
52 char *end_ptr = 0;
53 double difference = strtod(diff_str.c_str(), &end_ptr);
54
55 if (end_ptr && *end_ptr != '\0') {
56 CLS_ERR("add: invalid input value: %s", diff_str.c_str());
57 return -EINVAL;
58 }
59
60 bufferlist bl;
61 int ret = cls_cxx_map_get_val(hctx, key, &bl);
62
63 double value;
64
65 if (ret == -ENODATA || bl.length() == 0) {
66 value = 0;
67 } else if (ret < 0) {
68 if (ret != -ENOENT) {
69 CLS_ERR("add: error reading omap key %s: %d", key.c_str(), ret);
70 }
71 return ret;
72 } else {
73 std::string stored_value(bl.c_str(), bl.length());
74 end_ptr = 0;
75 value = strtod(stored_value.c_str(), &end_ptr);
76
77 if (end_ptr && *end_ptr != '\0') {
78 CLS_ERR("add: invalid stored value: %s", stored_value.c_str());
79 return -EBADMSG;
80 }
81 }
82
83 value += difference;
84
85 std::stringstream stream;
86 stream << std::setprecision(DECIMAL_PRECISION) << value;
87
88 bufferlist new_value;
89 new_value.append(stream.str());
90
91 return cls_cxx_map_set_val(hctx, key, &new_value);
92 }
93
94 static int mul(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
95 {
96 string key, diff_str;
97
98 auto iter = in->cbegin();
99 try {
100 decode(key, iter);
101 decode(diff_str, iter);
102 } catch (const buffer::error &err) {
103 CLS_LOG(20, "mul: invalid decode of input");
104 return -EINVAL;
105 }
106
107 char *end_ptr = 0;
108 double difference = strtod(diff_str.c_str(), &end_ptr);
109
110 if (end_ptr && *end_ptr != '\0') {
111 CLS_ERR("mul: invalid input value: %s", diff_str.c_str());
112 return -EINVAL;
113 }
114
115 bufferlist bl;
116 int ret = cls_cxx_map_get_val(hctx, key, &bl);
117
118 double value;
119
120 if (ret == -ENODATA || bl.length() == 0) {
121 value = 0;
122 } else if (ret < 0) {
123 if (ret != -ENOENT) {
124 CLS_ERR("mul: error reading omap key %s: %d", key.c_str(), ret);
125 }
126 return ret;
127 } else {
128 std::string stored_value(bl.c_str(), bl.length());
129 end_ptr = 0;
130 value = strtod(stored_value.c_str(), &end_ptr);
131
132 if (end_ptr && *end_ptr != '\0') {
133 CLS_ERR("mul: invalid stored value: %s", stored_value.c_str());
134 return -EBADMSG;
135 }
136 }
137
138 value *= difference;
139
140 std::stringstream stream;
141 stream << std::setprecision(DECIMAL_PRECISION) << value;
142
143 bufferlist new_value;
144 new_value.append(stream.str());
145
146 return cls_cxx_map_set_val(hctx, key, &new_value);
147 }
148
149 CLS_INIT(numops)
150 {
151 CLS_LOG(20, "loading cls_numops");
152
153 cls_handle_t h_class;
154 cls_method_handle_t h_add;
155 cls_method_handle_t h_mul;
156
157 cls_register("numops", &h_class);
158
159 cls_register_cxx_method(h_class, "add",
160 CLS_METHOD_RD | CLS_METHOD_WR,
161 add, &h_add);
162
163 cls_register_cxx_method(h_class, "mul",
164 CLS_METHOD_RD | CLS_METHOD_WR,
165 mul, &h_mul);
166 }