Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(277)

Side by Side Diff: third_party/WebKit/Source/wtf/text/CompressibleString.cpp

Issue 1389383003: WIP: Introduce CompressibleString Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase onto crrev.com/1564773002 Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "wtf/text/CompressibleString.h"
6
7 #include "third_party/zlib/google/compression_utils.h"
8 #include "wtf/Assertions.h"
9 #include "wtf/LinkedStack.h"
10 #include "wtf/Partitions.h"
11 #include "wtf/PassOwnPtr.h"
12 #include "wtf/WTFThreadData.h"
13 #include "wtf/text/WTFString.h"
14
15 namespace WTF {
16
17 class CompressibleStringTable {
18 WTF_MAKE_NONCOPYABLE(CompressibleStringTable);
19 public:
20 static CompressibleStringTable* create(WTFThreadData& data)
21 {
22 data.m_compressibleStringTable = new CompressibleStringTable;
23 data.m_compressibleStringTableDestructor = CompressibleStringTable::dest roy;
24 return data.m_compressibleStringTable;
25 }
26
27 void add(CompressibleStringImpl* string)
28 {
29 m_table.add(string);
30 }
31
32 bool contains(CompressibleStringImpl* string) const
33 {
34 return m_table.contains(string);
35 }
36
37 void remove(CompressibleStringImpl* string)
38 {
39 m_table.remove(string);
40 }
41
42 void compressAll()
43 {
44 HashSet<CompressibleStringImpl*>::iterator end = m_table.end();
45 for (HashSet<CompressibleStringImpl*>::iterator iter = m_table.begin(); iter != end; ++iter) {
46 CompressibleStringImpl* string = *iter;
47 if (!string->isCompressed())
48 string->compressString();
49 }
50 }
51
52 private:
53 CompressibleStringTable() { }
54
55 static void destroy(CompressibleStringTable* table)
56 {
57 delete table;
58 }
59
60 HashSet<CompressibleStringImpl*> m_table;
61 };
62
63 static inline CompressibleStringTable& compressibleStringTable()
64 {
65 // Once possible we should make this non-lazy (constructed in WTFThreadData' s constructor).
66 WTFThreadData& data = wtfThreadData();
67 CompressibleStringTable* table = data.compressibleStringTable();
68 if (UNLIKELY(!table))
69 table = CompressibleStringTable::create(data);
70 return *table;
71 }
72
73 void CompressibleStringImpl::purgeMemory()
74 {
75 // TODO(hajimehoshi): Compressing for the current thread is not enough.
76 // Do the same thing on other threads.
77 compressibleStringTable().compressAll();
78 }
79
80 CompressibleStringImpl::CompressibleStringImpl(PassRefPtr<StringImpl> impl)
81 : m_impl(impl)
82 , m_originalLength(m_impl->length())
83 , m_compressedData(nullptr)
84 , m_compressedDataSize(0)
85 , m_is8Bit(m_impl->is8Bit())
86 {
87 ASSERT(m_impl);
88 if (originalContentSizeInBytes() > 100000)
89 compressibleStringTable().add(this);
90 }
91
92 CompressibleStringImpl::~CompressibleStringImpl()
93 {
94 if (compressibleStringTable().contains(this))
95 compressibleStringTable().remove(this);
96 if (m_compressedData)
97 Partitions::fastFree(m_compressedData);
98 }
99
100 unsigned CompressibleStringImpl::originalContentSizeInBytes() const
101 {
102 if (is8Bit())
103 return m_originalLength * sizeof(LChar);
104 return m_originalLength * sizeof(UChar);
105 }
106
107 unsigned CompressibleStringImpl::currentSizeInBytes() const
108 {
109 if (UNLIKELY(isCompressed()))
110 return m_compressedDataSize;
111 return originalContentSizeInBytes();
112 }
113
114 String CompressibleStringImpl::toString()
115 {
116 if (UNLIKELY(isCompressed()))
117 uncompressString();
118 return m_impl.get();
119 }
120
121 const LChar* CompressibleStringImpl::characters8()
122 {
123 return toString().characters8();
124 }
125
126 const UChar* CompressibleStringImpl::characters16()
127 {
128 return toString().characters16();
129 }
130
131 void CompressibleStringImpl::compressString()
132 {
133 // UMA
134 // Count when the tab is background
135
136 ASSERT(m_impl);
137 ASSERT(!isCompressed());
138 ASSERT(!m_compressedDataSize);
139
140 // TODO(hajimehoshi): Now components offers funcitons accepting only
141 // std::strings. This is not efficient. We should offer char* version.
142 std::string in, out;
143 if (m_is8Bit)
144 in = std::string(reinterpret_cast<const char*>(m_impl->characters8()), o riginalContentSizeInBytes());
145 else
146 in = std::string(reinterpret_cast<const char*>(m_impl->characters16()), originalContentSizeInBytes());
147 compression::GzipCompress(in, &out);
148
149 m_impl = nullptr;
150 m_compressedData = Partitions::fastMalloc(out.size(), "CompressibleString");
151 memcpy(m_compressedData, out.c_str(), out.size());
152 m_compressedDataSize = out.size();
153 }
154
155 void CompressibleStringImpl::uncompressString()
156 {
157 // UMA
158 // Count when the tab is background
159
160 ASSERT(m_compressedData);
161 ASSERT(m_compressedDataSize);
162 ASSERT(!m_impl);
163
164 std::string in(static_cast<const char*>(m_compressedData), m_compressedDataS ize);
165 std::string out;
166 compression::GzipUncompress(in, &out);
167
168 if (m_is8Bit) {
169 LChar* data = nullptr;
170 m_impl = StringImpl::createUninitialized(out.size() / sizeof(LChar), dat a);
171 memcpy(data, out.c_str(), out.size());
172 } else {
173 UChar* data = nullptr;
174 m_impl = StringImpl::createUninitialized(out.size() / sizeof(UChar), dat a);
175 memcpy(data, out.c_str(), out.size());
176 }
177
178 Partitions::fastFree(m_compressedData);
179 m_compressedData = nullptr;
180 m_compressedDataSize = 0;
181 ASSERT(m_is8Bit == m_impl->is8Bit());
182 ASSERT(m_originalLength == m_impl->length());
183 }
184
185 CompressibleString::CompressibleString()
186 : m_impl(nullptr)
187 {
188 }
189
190 CompressibleString::CompressibleString(const CompressibleString& rhs)
191 : m_impl(rhs.m_impl)
192 {
193 }
194
195 CompressibleString::CompressibleString(PassRefPtr<StringImpl> impl)
196 : m_impl(impl ? adoptRef(new CompressibleStringImpl(impl)) : nullptr)
197 {
198 }
199
200 void CompressibleString::compressString() const
201 {
202 m_impl->compressString();
203 }
204
205 void CompressibleString::uncompressString() const
206 {
207 m_impl->uncompressString();
208 }
209
210 } // namespace WTF
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/text/CompressibleString.h ('k') | third_party/WebKit/Source/wtf/text/CompressibleStringTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698