source: libcfa/src/containers/string.cfa @ 7f958c4

ADTast-experimentalpthread-emulationqualifiedEnum
Last change on this file since 7f958c4 was 08ed947, checked in by Michael Brooks <mlbrooks@…>, 2 years ago

Roll up of string changes for performance testing/improvement, and a couple API features supporting them.

String API changes:
Defining a tuning knob to control the heap growth policy (relapaces former 10% hardcode, downgraded to a default)
Implementing findFrom (allowing find-non-first); leaving find as find-first.

String implementation perf improvements:
Calling C-malloc directly instead of via CFA-alloc.
Replacings loops that copy with memmove calls.
Replacings loops that search for a value with memchr calls.

String perf testing realized:
Makefile supporting several prog-*.cfa, chosen by OPERATION value (implies prog.cfa changes to support the adjusted protocol)
Adjusting the starter/accumulater declarations in PEQ and PTA to behave consistently in cfa v cpp.
Adding tests: allocation, find, normalize, pass-by-val, pass-by-x.
Adding helper shell scripts for: generating flame graphs, collecting/crunching allocation stats using Mubeen's malloc wrappers

  • Property mode set to 100644
File size: 7.6 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// string -- variable-length, mutable run of text, with value semantics
8//
9// Author           : Michael L. Brooks
10// Created On       : Fri Sep 03 11:00:00 2021
11// Last Modified By : Michael L. Brooks
12// Last Modified On : Fri Sep 03 11:00:00 2021
13// Update Count     : 1
14//
15
16#include "string.hfa"
17#include "string_res.hfa"
18#include <stdlib.hfa>
19
20
21/*
22Implementation Principle: typical operation translates to the equivalent
23operation on `inner`.  Exceptions are implementing new RAII pattern for value
24semantics and some const-hell handling.
25*/
26
27////////////////////////////////////////////////////////
28// string RAII
29
30
31void ?{}( string & this ) {
32    (this.inner) { malloc() };
33    ?{}( *this.inner );
34}
35
36// private (not in header)
37static void ?{}( string & this, string_res & src, size_t start, size_t end ) {
38    (this.inner) { malloc() };
39    ?{}( *this.inner, src, SHARE_EDITS, start, end );
40}
41
42void ?{}( string & this, const string & other ) {
43    (this.inner) { malloc() };
44    ?{}( *this.inner, *other.inner, COPY_VALUE );
45}
46
47void ?{}( string & this, string & other ) {
48    ?{}( this, (const string &) other );
49}
50
51void ?{}( string & this, const char * val ) {
52    (this.inner) { malloc() };
53    ?{}( *this.inner, val );
54}
55
56void ?{}( string & this, const char* buffer, size_t bsize) {
57    (this.inner) { malloc() };
58    ?{}( *this.inner, buffer, bsize );
59}
60
61void ^?{}( string & this ) {
62    ^(*this.inner){};
63    free( this.inner );
64    this.inner = 0p;
65}
66
67////////////////////////////////////////////////////////
68// Alternate construction: request shared edits
69
70string_WithSharedEdits ?`shareEdits( string & this ) {
71    string_WithSharedEdits ret = { &this };
72    return ret;
73}
74
75void ?{}( string & this, string_WithSharedEdits src ) {
76    ?{}( this, *src.s->inner, 0, src.s->inner->Handle.lnth);
77}
78
79////////////////////////////////////////////////////////
80// Assignment
81
82void ?=?( string & this, const char * val ) {
83    (*this.inner) = val;
84}
85
86void ?=?(string & this, const string & other) {
87    (*this.inner) = (*other.inner);
88}
89
90void ?=?( string & this, char val ) {
91    (*this.inner) = val;
92}
93
94string & ?=?(string & this, string & other) { //// <---- straw man change
95    (*this.inner) = (*other.inner);
96    return this;
97}
98
99
100////////////////////////////////////////////////////////
101// Output
102
103ofstream & ?|?( ofstream & fs, const string & this ) {
104    return fs | (*this.inner);
105}
106
107void ?|?( ofstream & fs, const string & this ) {
108    fs | (*this.inner);
109}
110
111////////////////////////////////////////////////////////
112// Slicing
113
114string ?()( string & this, size_t start, size_t end ) {
115    string ret = { *this.inner, start, end };
116    return ret`shareEdits;
117}
118
119////////////////////////////////////////////////////////
120// Comparison
121
122bool ?==?(const string &s, const string &other) {
123    return *s.inner == *other.inner;
124}
125
126bool ?!=?(const string &s, const string &other) {
127    return *s.inner != *other.inner;
128}
129
130bool ?==?(const string &s, const char* other) {
131    return *s.inner == other;
132}
133
134bool ?!=?(const string &s, const char* other) {
135    return *s.inner != other;
136}
137
138////////////////////////////////////////////////////////
139// Getter
140
141size_t size(const string &s) {
142    return size( * s.inner );
143}
144
145////////////////////////////////////////////////////////
146// Concatenation
147
148void ?+=?(string &s, char other) {
149    (*s.inner) += other;
150}
151
152void ?+=?(string &s, const string &s2) {
153    (*s.inner) += (*s2.inner);
154}
155
156void ?+=?(string &s, const char* other) {
157    (*s.inner) += other;
158}
159
160string ?+?(const string &s, char other) {
161    string ret = s;
162    ret += other;
163    return ret;
164}
165
166string ?+?(const string &s, const string &s2) {
167    string ret = s;
168    ret += s2;
169    return ret;
170}
171
172string ?+?(const char* s1, const char* s2) {
173    string ret = s1;
174    ret += s2;
175    return ret;
176}
177
178string ?+?(const string &s, const char* other) {
179    string ret = s;
180    ret += other;
181    return ret;
182}
183
184////////////////////////////////////////////////////////
185// Repetition
186
187string ?*?(const string &s, size_t factor) {
188    string ret = "";
189    for (factor) ret += s;
190    return ret;
191}
192
193string ?*?(char c, size_t size) {
194    string ret = "";
195    for ((size_t)size) ret += c;
196    return ret;
197}
198
199string ?*?(const char *s, size_t factor) {
200    string ss = s;
201    return ss * factor;
202}
203
204////////////////////////////////////////////////////////
205// Character access
206
207char ?[?](const string &s, size_t index) {
208    return (*s.inner)[index];
209}
210
211string ?[?](string &s, size_t index) {
212    string ret = { *s.inner, index, index + 1 };
213    return ret`shareEdits;
214}
215
216////////////////////////////////////////////////////////
217// Search
218
219bool contains(const string &s, char ch) {
220    return contains( *s.inner, ch );
221}
222
223int find(const string &s, char search) {
224    return find( *s.inner, search );
225}
226
227int find(const string &s, const string &search) {
228    return find( *s.inner, *search.inner );
229}
230
231int find(const string &s, const char* search) {
232    return find( *s.inner, search);
233}
234
235int find(const string &s, const char* search, size_t searchsize) {
236    return find( *s.inner, search, searchsize);
237}
238
239int findFrom(const string &s, size_t fromPos, char search) {
240    return findFrom( *s.inner, fromPos, search );
241}
242
243int findFrom(const string &s, size_t fromPos, const string &search) {
244    return findFrom( *s.inner, fromPos, *search.inner );
245}
246
247int findFrom(const string &s, size_t fromPos, const char* search) {
248    return findFrom( *s.inner, fromPos, search );
249}
250
251int findFrom(const string &s, size_t fromPos, const char* search, size_t searchsize) {
252    return findFrom( *s.inner, fromPos, search, searchsize );
253}
254
255bool includes(const string &s, const string &search) {
256    return includes( *s.inner, *search.inner );
257}
258
259bool includes(const string &s, const char* search) {
260    return includes( *s.inner, search );
261}
262
263bool includes(const string &s, const char* search, size_t searchsize) {
264    return includes( *s.inner, search, searchsize );
265}
266
267bool startsWith(const string &s, const string &prefix) {
268    return startsWith( *s.inner, *prefix.inner );
269}
270
271bool startsWith(const string &s, const char* prefix) {
272    return startsWith( *s.inner, prefix );
273}
274
275bool startsWith(const string &s, const char* prefix, size_t prefixsize) {
276    return startsWith( *s.inner, prefix, prefixsize );
277}
278
279bool endsWith(const string &s, const string &suffix) {
280    return endsWith( *s.inner, *suffix.inner );
281}
282
283bool endsWith(const string &s, const char* suffix) {
284    return endsWith( *s.inner, suffix );
285}
286
287bool endsWith(const string &s, const char* suffix, size_t suffixsize) {
288    return endsWith( *s.inner, suffix, suffixsize );
289}
290
291
292///////////////////////////////////////////////////////////////////////////
293// charclass, include, exclude
294
295void ?{}( charclass & this, const string & chars) {
296    (this.inner) { malloc() };
297    ?{}( *this.inner, *(const string_res *)chars.inner );
298}
299
300void ?{}( charclass & this, const char * chars ) {
301    (this.inner) { malloc() };
302    ?{}( *this.inner, chars );
303}
304
305void ?{}( charclass & this, const char * chars, size_t charssize ) {
306    (this.inner) { malloc() };
307    ?{}( *this.inner, chars, charssize );
308}
309
310void ^?{}( charclass & this ) {
311    ^(*this.inner){};
312    free( this.inner );
313    this.inner = 0p;
314}
315
316
317int exclude(const string &s, const charclass &mask) {
318    return exclude( *s.inner, *mask.inner );
319}
320/*
321StrSlice exclude(string &s, const charclass &mask) {
322}
323*/
324
325int include(const string &s, const charclass &mask) {
326    return include( *s.inner, *mask.inner );
327}
328
329/*
330StrSlice include(string &s, const charclass &mask) {
331}
332*/
333
Note: See TracBrowser for help on using the repository browser.