]> git.proxmox.com Git - ceph.git/blob - ceph/src/cls/numops/cls_numops.cc
add subtree-ish sources for 12.0.3
[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 <iostream>
25 #include <map>
26 #include <string>
27 #include <sstream>
28 #include <cstdio>
29 #include <include/compat.h>
30
31 #define DECIMAL_PRECISION 10
32
33 CLS_VER(1,0)
34 CLS_NAME(numops)
35
36 static int add(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
37 {
38 string key, diff_str;
39
40 bufferlist::iterator iter = in->begin();
41 try {
42 ::decode(key, iter);
43 ::decode(diff_str, iter);
44 } catch (const buffer::error &err) {
45 CLS_LOG(20, "add: invalid decode of input");
46 return -EINVAL;
47 }
48
49 char *end_ptr = 0;
50 double difference = strtod(diff_str.c_str(), &end_ptr);
51
52 if (end_ptr && *end_ptr != '\0') {
53 CLS_ERR("add: invalid input value: %s", diff_str.c_str());
54 return -EINVAL;
55 }
56
57 bufferlist bl;
58 int ret = cls_cxx_map_get_val(hctx, key, &bl);
59
60 double value;
61
62 if (ret == -ENODATA || bl.length() == 0) {
63 value = 0;
64 } else if (ret < 0) {
65 if (ret != -ENOENT) {
66 CLS_ERR("add: error reading omap key %s: %d", key.c_str(), ret);
67 }
68 return ret;
69 } else {
70 std::string stored_value(bl.c_str(), bl.length());
71 end_ptr = 0;
72 value = strtod(stored_value.c_str(), &end_ptr);
73
74 if (end_ptr && *end_ptr != '\0') {
75 CLS_ERR("add: invalid stored value: %s", stored_value.c_str());
76 return -EBADMSG;
77 }
78 }
79
80 value += difference;
81
82 std::stringstream stream;
83 stream << std::setprecision(DECIMAL_PRECISION) << value;
84
85 bufferlist new_value;
86 new_value.append(stream.str());
87
88 return cls_cxx_map_set_val(hctx, key, &new_value);
89 }
90
91 static int mul(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
92 {
93 string key, diff_str;
94
95 bufferlist::iterator iter = in->begin();
96 try {
97 ::decode(key, iter);
98 ::decode(diff_str, iter);
99 } catch (const buffer::error &err) {
100 CLS_LOG(20, "add: invalid decode of input");
101 return -EINVAL;
102 }
103
104 char *end_ptr = 0;
105 double difference = strtod(diff_str.c_str(), &end_ptr);
106
107 if (end_ptr && *end_ptr != '\0') {
108 CLS_ERR("add: invalid input value: %s", diff_str.c_str());
109 return -EINVAL;
110 }
111
112 bufferlist bl;
113 int ret = cls_cxx_map_get_val(hctx, key, &bl);
114
115 double value;
116
117 if (ret == -ENODATA || bl.length() == 0) {
118 value = 0;
119 } else if (ret < 0) {
120 if (ret != -ENOENT) {
121 CLS_ERR("add: error reading omap key %s: %d", key.c_str(), ret);
122 }
123 return ret;
124 } else {
125 std::string stored_value(bl.c_str(), bl.length());
126 end_ptr = 0;
127 value = strtod(stored_value.c_str(), &end_ptr);
128
129 if (end_ptr && *end_ptr != '\0') {
130 CLS_ERR("add: invalid stored value: %s", stored_value.c_str());
131 return -EBADMSG;
132 }
133 }
134
135 value *= difference;
136
137 std::stringstream stream;
138 stream << std::setprecision(DECIMAL_PRECISION) << value;
139
140 bufferlist new_value;
141 new_value.append(stream.str());
142
143 return cls_cxx_map_set_val(hctx, key, &new_value);
144 }
145
146 CLS_INIT(numops)
147 {
148 CLS_LOG(20, "loading cls_numops");
149
150 cls_handle_t h_class;
151 cls_method_handle_t h_add;
152 cls_method_handle_t h_mul;
153
154 cls_register("numops", &h_class);
155
156 cls_register_cxx_method(h_class, "add",
157 CLS_METHOD_RD | CLS_METHOD_WR,
158 add, &h_add);
159
160 cls_register_cxx_method(h_class, "mul",
161 CLS_METHOD_RD | CLS_METHOD_WR,
162 mul, &h_mul);
163 }