Skip to content

Commit 2eff104

Browse files
committed
Multiple performance optimizations
1 parent 5d82376 commit 2eff104

9 files changed

Lines changed: 859 additions & 84 deletions

File tree

cppcms/json.h

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#define CPPCMS_JSON_H
2121

2222
#include <cppcms/defs.h>
23+
#include <cppcms/string_key.h>
2324
#include <booster/copy_ptr.h>
2425
#include <booster/backtrace.h>
2526
#include <vector>
@@ -60,7 +61,7 @@ namespace json {
6061
///
6162
/// The json::object - std::map of json::value's
6263
///
63-
typedef std::map<std::string,value> object;
64+
typedef std::map<string_key,value> object;
6465

6566
#ifdef CPPCMS_DOXYGEN_DOCS
6667

@@ -263,6 +264,14 @@ namespace json {
263264
/// that holds an object { "y" : 10 } and find("foo") would return value of undefined type.
264265
///
265266
value const &find(std::string const &path) const;
267+
///
268+
/// Searches a value in the path \a path
269+
///
270+
/// For example if the json::value represents { "x" : { "y" : 10 } }, then find("x.y") would return
271+
/// a reference to value that hold a number 10, find("x") returns a reference to a value
272+
/// that holds an object { "y" : 10 } and find("foo") would return value of undefined type.
273+
///
274+
value const &find(char const *path) const;
266275

267276
///
268277
/// Searches a value in the path \a path, if not found throw bad_value_cast.
@@ -279,12 +288,32 @@ namespace json {
279288
/// a reference to value that hold a number 10, find("x") returns a reference to a value
280289
/// that holds an object { "y" : 10 } and find("foo") throws
281290
///
291+
value const &at(char const *path) const;
292+
///
293+
/// Searches a value in the path \a path, if not found throw bad_value_cast.
294+
///
295+
/// For example if the json::value represents { "x" : { "y" : 10 } }, then find("x.y") would return
296+
/// a reference to value that hold a number 10, find("x") returns a reference to a value
297+
/// that holds an object { "y" : 10 } and find("foo") throws
298+
///
282299
value &at(std::string const &path);
300+
///
301+
/// Searches a value in the path \a path, if not found throw bad_value_cast.
302+
///
303+
/// For example if the json::value represents { "x" : { "y" : 10 } }, then find("x.y") would return
304+
/// a reference to value that hold a number 10, find("x") returns a reference to a value
305+
/// that holds an object { "y" : 10 } and find("foo") throws
306+
///
307+
value &at(char const *path);
283308

284309
///
285310
/// Sets the value \a v at the path \a path, if the path invalid, creates it.
286311
///
287312
void at(std::string const &path,value const &v);
313+
///
314+
/// Sets the value \a v at the path \a path, if the path invalid, creates it.
315+
///
316+
void at(char const *path,value const &v);
288317

289318

290319
///
@@ -305,6 +334,15 @@ namespace json {
305334
{
306335
return find(path).type();
307336
}
337+
///
338+
/// Returns the type of variable in path, if not found returns undefined
339+
///
340+
/// Same as find(path).type()
341+
///
342+
json_type type(char const *path) const
343+
{
344+
return find(path).type();
345+
}
308346

309347
///
310348
/// Convert an object \a v of type T to a value at specific path, same as at(path,value(v))
@@ -314,6 +352,14 @@ namespace json {
314352
{
315353
at(path,value(v));
316354
}
355+
///
356+
/// Convert an object \a v of type T to a value at specific path, same as at(path,value(v))
357+
///
358+
template<typename T>
359+
void set(char const *path,T const &v)
360+
{
361+
at(path,value(v));
362+
}
317363

318364
///
319365
/// Get a string value from a path \a path. If the path is not invalid or the object
@@ -331,6 +377,22 @@ namespace json {
331377
return def;
332378
}
333379
}
380+
///
381+
/// Get a string value from a path \a path. If the path is not invalid or the object
382+
/// is not of type string at this path, returns \a def instead
383+
///
384+
std::string get(char const *path,char const *def) const
385+
{
386+
value const &v=find(path);
387+
if(v.is_undefined())
388+
return def;
389+
try {
390+
return v.get_value<std::string>();
391+
}
392+
catch(std::bad_cast const &e) {
393+
return def;
394+
}
395+
}
334396

335397
///
336398
/// Get an object of type T from the path \a path. Throws bad_value_cast if such path does not
@@ -341,7 +403,33 @@ namespace json {
341403
{
342404
return at(path).get_value<T>();
343405
}
406+
///
407+
/// Get an object of type T from the path \a path. Throws bad_value_cast if such path does not
408+
/// exists of conversion can't be done
409+
///
410+
template<typename T>
411+
T get(char const *path) const
412+
{
413+
return at(path).get_value<T>();
414+
}
344415

416+
///
417+
/// Get an object of type T from the path \a path. Returns \a def if such path does not
418+
/// exists of conversion can't be done
419+
///
420+
template<typename T>
421+
T get(char const *path,T const &def) const
422+
{
423+
value const &v=find(path);
424+
if(v.is_undefined())
425+
return def;
426+
try {
427+
return v.get_value<T>();
428+
}
429+
catch(std::bad_cast const &e) {
430+
return def;
431+
}
432+
}
345433
///
346434
/// Get an object of type T from the path \a path. Returns \a def if such path does not
347435
/// exists of conversion can't be done

cppcms/steal_buf.h

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
///////////////////////////////////////////////////////////////////////////////
2+
//
3+
// Copyright (C) 2008-2010 Artyom Beilis (Tonkikh) <[email protected]>
4+
//
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU Lesser General Public License as published by
7+
// the Free Software Foundation, either version 3 of the License, or
8+
// (at your option) any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU Lesser General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU Lesser General Public License
16+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
//
18+
///////////////////////////////////////////////////////////////////////////////
19+
#ifndef CPPCMS_STEAL_BUF_H
20+
#define CPPCMS_STEAL_BUF_H
21+
22+
#include <streambuf>
23+
#include <ostream>
24+
#include <stdio.h>
25+
#include <string>
26+
#include <string.h>
27+
#include <stdlib.h>
28+
29+
namespace cppcms {
30+
namespace util {
31+
32+
template<size_t on_stack_size = 128>
33+
class steal_buffer : public std::streambuf {
34+
steal_buffer(steal_buffer const &);
35+
void operator=(steal_buffer const &);
36+
public:
37+
char *begin()
38+
{
39+
return pbase();
40+
}
41+
char *end()
42+
{
43+
return pptr();
44+
}
45+
steal_buffer(std::ostream &out)
46+
{
47+
init();
48+
steal(out);
49+
}
50+
steal_buffer()
51+
{
52+
init();
53+
}
54+
void steal(std::ostream &out)
55+
{
56+
release();
57+
stolen_ = out.rdbuf(this);
58+
stream_ = &out;
59+
}
60+
void release()
61+
{
62+
if(stream_ && stolen_) {
63+
stream_->rdbuf(stolen_);
64+
}
65+
stream_ = 0;
66+
stolen_ = 0;
67+
}
68+
~steal_buffer()
69+
{
70+
release();
71+
free(on_heap_);
72+
}
73+
int overflow(int c)
74+
{
75+
size_t current_size;
76+
size_t new_size;
77+
if(pbase() == on_stack_) {
78+
current_size = on_stack_size;
79+
new_size = on_stack_size * 2;
80+
on_heap_ = (char *)malloc(new_size);
81+
if(!on_heap_)
82+
throw std::bad_alloc();
83+
memcpy(on_heap_,on_stack_,current_size);
84+
}
85+
else {
86+
current_size = pptr() - pbase();
87+
new_size = current_size * 2;
88+
char *new_ptr = (char *)realloc(on_heap_,new_size);
89+
if(!new_ptr)
90+
throw std::bad_alloc();
91+
on_heap_ = new_ptr;
92+
93+
}
94+
setp(on_heap_,on_heap_ + new_size);
95+
pbump(current_size);
96+
if(c!=EOF)
97+
sputc(c);
98+
return 0;
99+
}
100+
private:
101+
void init()
102+
{
103+
on_heap_ = 0;
104+
stolen_ = 0;
105+
stream_ = 0;
106+
setp(on_stack_,on_stack_+on_stack_size);
107+
}
108+
char *on_heap_;
109+
std::streambuf *stolen_;
110+
std::ostream *stream_;
111+
char on_stack_[on_stack_size];
112+
};
113+
114+
} // util
115+
} // cppcms
116+
117+
#endif

0 commit comments

Comments
 (0)