5
5
using System ;
6
6
using System . Collections . Generic ;
7
7
using System . Numerics ;
8
+ using System . Runtime . CompilerServices ;
8
9
using Windows . UI ;
9
10
using Windows . UI . Composition ;
10
11
@@ -283,9 +284,10 @@ internal void EnsureReferenceInfo()
283
284
284
285
// Create a map to store the generated paramNames for each CompObj
285
286
_compObjToParamNameMap = new Dictionary < CompositionObject , string > ( ) ;
287
+ var paramCount = 0u ;
286
288
foreach ( var compObj in compObjects )
287
289
{
288
- string paramName = Guid . NewGuid ( ) . ToUppercaseAsciiLetters ( ) ;
290
+ string paramName = CreateUniqueParamNameFromIndex ( paramCount ++ ) ;
289
291
290
292
_compObjToParamNameMap . Add ( compObj , paramName ) ;
291
293
}
@@ -312,6 +314,37 @@ internal void EnsureReferenceInfo()
312
314
refNode . ParamName = paramName ;
313
315
}
314
316
}
317
+
318
+ // Generates Excel-column-like identifiers, e.g. A, B, ..., Z, AA, BA...
319
+ // This implementation aggregates characters in reverse order to avoid having to
320
+ // precompute the exact number of characters in the resulting string. This is not
321
+ // important in this context as the only critical property to maintain is to have
322
+ // a unique mapping to each input value to the resulting sequence of letters.
323
+ [ SkipLocalsInit ]
324
+ static unsafe string CreateUniqueParamNameFromIndex ( uint i )
325
+ {
326
+ const int alphabetLength = 'Z' - 'A' + 1 ;
327
+
328
+ // The total length of the resulting sequence is guaranteed to always
329
+ // be less than 8, given that log26(4294967295) ≈ 6.8. In this case we
330
+ // are just allocating the immediate next power of two following that.
331
+ // Note: this is using a char* buffer instead of Span<char> as the latter
332
+ // is not referenced here, and we don't want to pull in an extra package.
333
+ char * characters = stackalloc char [ 8 ] ;
334
+
335
+ characters [ 0 ] = ( char ) ( 'A' + ( i % alphabetLength ) ) ;
336
+
337
+ int totalCharacters = 1 ;
338
+
339
+ while ( ( i /= alphabetLength ) > 0 )
340
+ {
341
+ i -- ;
342
+
343
+ characters [ totalCharacters ++ ] = ( char ) ( 'A' + ( i % alphabetLength ) ) ;
344
+ }
345
+
346
+ return new string ( characters , 0 , totalCharacters ) ;
347
+ }
315
348
}
316
349
317
350
/// <summary>
@@ -670,4 +703,4 @@ public ReferenceInfo(string paramName, CompositionObject compObj)
670
703
/// <value>The subchannels.</value>
671
704
protected internal string [ ] Subchannels { get ; set ; }
672
705
}
673
- }
706
+ }
0 commit comments