Skip to content

Commit d743ced

Browse files
committed
shared-string: further reduce memory consumption of json-writer
... by allocating repeatedly used strings in a global set
1 parent b83a71c commit d743ced

File tree

5 files changed

+168
-8
lines changed

5 files changed

+168
-8
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ add_library(cs STATIC
3838
instream.cc
3939
json-parser.cc
4040
json-writer.cc
41+
shared-string.cc
4142
version.cc
4243
)
4344

json-writer.cc

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,17 @@
1919

2020
#include "json-writer.hh"
2121

22+
#include "shared-string-ptree.hh"
23+
2224
#include <queue>
2325

2426
#include <boost/foreach.hpp>
2527
#include <boost/iostreams/filtering_stream.hpp>
2628
#include <boost/iostreams/filter/regex.hpp>
2729
#include <boost/property_tree/json_parser.hpp>
2830

31+
typedef SharedStringPTree PTree;
32+
2933
struct JsonWriter::Private {
3034
std::ostream &str;
3135
std::queue<Defect> defQueue;
@@ -54,13 +58,13 @@ void JsonWriter::setScanProps(const TScanProps &scanProps) {
5458
d->scanProps = scanProps;
5559
}
5660

57-
void appendDefectNode(boost::property_tree::ptree &dst, const Defect &def) {
61+
void appendDefectNode(PTree &dst, const Defect &def) {
5862
using std::string;
5963

6064
// go through events
61-
boost::property_tree::ptree evtList;
65+
PTree evtList;
6266
BOOST_FOREACH(const DefEvent &evt, def.events) {
63-
boost::property_tree::ptree evtNode;
67+
PTree evtNode;
6468

6569
// describe the location
6670
evtNode.put<string>("file_name", evt.fileName);
@@ -78,7 +82,7 @@ void appendDefectNode(boost::property_tree::ptree &dst, const Defect &def) {
7882
}
7983

8084
// create a node for a single defect
81-
boost::property_tree::ptree defNode;
85+
PTree defNode;
8286
defNode.put<string>("checker", def.checker);
8387
if (!def.annotation.empty())
8488
defNode.put<string>("annotation", def.annotation);
@@ -123,18 +127,18 @@ void JsonWriter::flush() {
123127
str.push(d->str);
124128

125129
// encode scan properties if we have some
126-
boost::property_tree::ptree root;
130+
PTree root;
127131
if (!d->scanProps.empty()) {
128-
boost::property_tree::ptree scan;
132+
PTree scan;
129133
BOOST_FOREACH(TScanProps::const_reference prop, d->scanProps)
130134
scan.put<std::string>(prop.first, prop.second);
131135

132136
root.put_child("scan", scan);
133137
}
134138

135139
// node representing the list of defects
136-
root.put_child("defects", boost::property_tree::ptree());
137-
boost::property_tree::ptree &defects = root.get_child("defects");
140+
root.put_child("defects", PTree());
141+
PTree &defects = root.get_child("defects");
138142

139143
// go through the queue and move defects one by one to the property tree
140144
for (; !d->defQueue.empty(); d->defQueue.pop())

shared-string-ptree.hh

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright (C) 2018 Red Hat, Inc.
3+
*
4+
* This file is part of csdiff.
5+
*
6+
* csdiff is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* any later version.
10+
*
11+
* csdiff is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with csdiff. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
#ifndef H_GUARD_SHARED_STRING_PTREE_H
21+
#define H_GUARD_SHARED_STRING_PTREE_H
22+
23+
#include "shared-string.hh"
24+
25+
#include <boost/property_tree/ptree.hpp>
26+
27+
template <typename T>
28+
struct SharedStrTrans {
29+
typedef SharedStr internal_type;
30+
typedef SharedStr external_type;
31+
32+
boost::optional<SharedStr> put_value(const T &val) const {
33+
const SharedStr ss(val);
34+
return ss;
35+
}
36+
37+
boost::optional<T> get_value(const SharedStr &ss) const {
38+
T val;
39+
ss.writeOut(&val);
40+
return val;
41+
}
42+
};
43+
44+
namespace boost {
45+
namespace property_tree {
46+
template <typename T>
47+
struct translator_between<SharedStr, T> {
48+
typedef SharedStrTrans<T> type;
49+
};
50+
}
51+
}
52+
53+
typedef boost::property_tree::basic_ptree<std::string, SharedStr>
54+
SharedStringPTree;
55+
56+
#endif /* H_GUARD_SHARED_STRING_PTREE_H */

shared-string.cc

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright (C) 2018 Red Hat, Inc.
3+
*
4+
* This file is part of csdiff.
5+
*
6+
* csdiff is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* any later version.
10+
*
11+
* csdiff is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with csdiff. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
#include "shared-string.hh"
21+
22+
#include <sstream>
23+
24+
SharedStr::TStor SharedStr::stor_;
25+
26+
SharedStr::SharedStr():
27+
iter_(stor_.end())
28+
{
29+
}
30+
31+
void SharedStr::swap(SharedStr &ref)
32+
{
33+
std::swap(iter_, ref.iter_);
34+
}
35+
36+
void SharedStr::hashStr(const std::string &str)
37+
{
38+
iter_ = stor_.insert(str).first;
39+
}
40+
41+
SharedStr::SharedStr(const int i)
42+
{
43+
std::ostringstream ss;
44+
ss << i;
45+
this->hashStr(ss.str());
46+
}
47+
48+
SharedStr::SharedStr(const std::string &str)
49+
{
50+
this->hashStr(str);
51+
}
52+
53+
void SharedStr::writeOut(std::string *pDst) const {
54+
if (stor_.end() == iter_)
55+
pDst->clear();
56+
else
57+
*pDst = *iter_;
58+
}

shared-string.hh

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (C) 2018 Red Hat, Inc.
3+
*
4+
* This file is part of csdiff.
5+
*
6+
* csdiff is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* any later version.
10+
*
11+
* csdiff is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with csdiff. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
#ifndef H_GUARD_SHARED_STRING_H
21+
#define H_GUARD_SHARED_STRING_H
22+
23+
#include <set>
24+
#include <string>
25+
26+
class SharedStr {
27+
public:
28+
SharedStr();
29+
SharedStr(int i);
30+
SharedStr(const std::string &str);
31+
void writeOut(std::string *pDst) const;
32+
void swap(SharedStr &);
33+
34+
private:
35+
typedef std::set<std::string> TStor;
36+
static TStor stor_;
37+
TStor::iterator iter_;
38+
void hashStr(const std::string &);
39+
};
40+
41+
#endif /* H_GUARD_SHARED_STRING_H */

0 commit comments

Comments
 (0)