@@ -18,7 +18,9 @@ public ref struct TableQueryBuilder
1818 /// </summary>
1919 public TableQueryBuilder ( ) { }
2020
21- private Span < char > _currentQuery = [ ] ;
21+ private const int BufferSize = 1024 ;
22+ private Span < char > _bufferQuery = new ( new char [ BufferSize ] ) ;
23+ private int _currentQueryLength = 0 ;
2224 private uint _filterCount = 0 ;
2325 private uint _beginGroupCount = 0 ;
2426 private uint _endGroupCount = 0 ;
@@ -28,21 +30,42 @@ public TableQueryBuilder() { }
2830 /// </summary>
2931 public bool HasFilter => _filterCount > 0 ;
3032
33+ /// <summary>
34+ /// Gets the current query filter.
35+ /// </summary>
36+ public ReadOnlySpan < char > QueryFilter => _bufferQuery . Slice ( 0 , _currentQueryLength ) ;
37+
38+ private void AllocateBuffer ( int lengthToAdd )
39+ {
40+ if ( ( _currentQueryLength + lengthToAdd > _bufferQuery . Length ) )
41+ {
42+ Span < char > newBuffer = stackalloc char [ _bufferQuery . Length + BufferSize ] ;
43+ QueryFilter . CopyTo ( newBuffer ) ;
44+ _bufferQuery = new Span < char > ( [ ..newBuffer ] ) ;
45+ }
46+ }
47+
3148 private void AppendCondition ( ReadOnlySpan < char > condition )
3249 {
33- if ( _currentQuery . IsEmpty )
50+ int segmentLength = condition . Length + 2 ;
51+
52+ if ( _currentQueryLength <= 0 )
3453 {
35- _currentQuery = new Span < char > ( [ '(' , .. condition , ')' ] ) ;
54+ _bufferQuery [ 0 ] = '(' ;
55+ condition . CopyTo ( _bufferQuery [ 1 ..] ) ;
56+ _bufferQuery [ ^ 1 ] = ')' ;
3657 }
3758 else
3859 {
39- Span < char > temp = stackalloc char [ _currentQuery . Length + condition . Length + 2 ] ;
40- _currentQuery . CopyTo ( temp ) ;
41- temp [ _currentQuery . Length ] = '(' ;
42- condition . CopyTo ( temp [ ( _currentQuery . Length + 1 ) ..] ) ;
60+ Span < char > temp = stackalloc char [ _currentQueryLength + segmentLength ] ;
61+ AllocateBuffer ( segmentLength ) ;
62+ QueryFilter . CopyTo ( temp ) ;
63+ temp [ _currentQueryLength ] = '(' ;
64+ condition . CopyTo ( temp [ ( _currentQueryLength + 1 ) ..] ) ;
4365 temp [ ^ 1 ] = ')' ;
44- _currentQuery = new Span < char > ( temp . ToArray ( ) ) ;
66+ temp . CopyTo ( _bufferQuery ) ;
4567 }
68+ _currentQueryLength += segmentLength ;
4669 _filterCount ++ ;
4770 _beginGroupCount ++ ;
4871 _endGroupCount ++ ;
@@ -137,43 +160,53 @@ public TableQueryBuilder GroupAll()
137160
138161 private void AppendBeginGroup ( )
139162 {
140- Span < char > temp = stackalloc char [ _currentQuery . Length + 1 ] ;
141- _currentQuery . CopyTo ( temp ) ;
163+ AllocateBuffer ( 1 ) ;
164+ Span < char > temp = stackalloc char [ _currentQueryLength + 1 ] ;
165+ QueryFilter . CopyTo ( temp ) ;
142166 temp [ ^ 1 ] = '(' ;
143- _currentQuery = new Span < char > ( temp . ToArray ( ) ) ;
167+ temp . CopyTo ( _bufferQuery ) ;
168+ _currentQueryLength ++ ;
144169 _beginGroupCount ++ ;
145170 }
146171
147172 private void AppendEndGroup ( )
148173 {
149174 ThrowIfNoFilter ( ) ;
150- Span < char > temp = stackalloc char [ _currentQuery . Length + 1 ] ;
151- _currentQuery . CopyTo ( temp ) ;
175+ AllocateBuffer ( 1 ) ;
176+ Span < char > temp = stackalloc char [ _currentQueryLength + 1 ] ;
177+ QueryFilter . CopyTo ( temp ) ;
152178 temp [ ^ 1 ] = ')' ;
153- _currentQuery = new Span < char > ( temp . ToArray ( ) ) ;
179+ temp . CopyTo ( _bufferQuery ) ;
180+ _currentQueryLength ++ ;
154181 _endGroupCount ++ ;
155182 }
156183
157184 private void PrependAppendGroupAll ( )
158185 {
159186 ThrowIfNoFilter ( ) ;
160- Span < char > temp = stackalloc char [ _currentQuery . Length + 2 ] ;
187+ AllocateBuffer ( 2 ) ;
188+ Span < char > temp = stackalloc char [ _currentQueryLength + 2 ] ;
161189 temp [ 0 ] = '(' ;
162- _currentQuery . CopyTo ( temp [ 1 ..] ) ;
190+ QueryFilter . CopyTo ( temp [ 1 ..] ) ;
163191 _beginGroupCount ++ ;
164192 temp [ ^ 1 ] = ')' ;
165193 _endGroupCount ++ ;
166- _currentQuery = new Span < char > ( temp . ToArray ( ) ) ;
194+ temp . CopyTo ( _bufferQuery ) ;
195+ _currentQueryLength += 2 ;
167196 }
168197
169198 private void AppendTableOperator ( TableOperator tableOperator )
170199 {
171200 ThrowIfNoFilter ( ) ;
172201 ReadOnlySpan < char > tableOperatorSpan = $ " { TableOperators . GetOperator ( tableOperator ) } ". AsSpan ( ) ;
173- Span < char > temp = stackalloc char [ _currentQuery . Length + tableOperatorSpan . Length ] ;
174- _currentQuery . CopyTo ( temp ) ;
175- tableOperatorSpan . CopyTo ( temp [ _currentQuery . Length ..] ) ;
176- _currentQuery = new Span < char > ( temp . ToArray ( ) ) ;
202+ int segmentLength = tableOperatorSpan . Length ;
203+ AllocateBuffer ( segmentLength ) ;
204+
205+ Span < char > temp = stackalloc char [ _currentQueryLength + segmentLength ] ;
206+ QueryFilter . CopyTo ( temp ) ;
207+ tableOperatorSpan . CopyTo ( temp [ _currentQueryLength ..] ) ;
208+ temp . CopyTo ( _bufferQuery ) ;
209+ _currentQueryLength += segmentLength ;
177210 }
178211
179212 private void ThrowIfNoFilter ( )
@@ -190,7 +223,7 @@ private void ThrowIfNoFilter()
190223 /// <returns>Returns an Odata Azure Table Storage query or an empty string</returns>
191224 public override string ToString ( )
192225 {
193- return _currentQuery . ToString ( ) ;
226+ return QueryFilter . ToString ( ) ;
194227 }
195228 }
196229}
0 commit comments