StringBuilderPool.cs 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  2. using System;
  3. using System.Diagnostics;
  4. using System.Text;
  5. namespace Jint.Pooling
  6. {
  7. /// <summary>
  8. /// Pooling of StringBuilder instances.
  9. /// </summary>
  10. internal sealed class StringBuilderPool
  11. {
  12. private static readonly ConcurrentObjectPool<StringBuilder> _pool;
  13. static StringBuilderPool()
  14. {
  15. _pool = new ConcurrentObjectPool<StringBuilder>(() => new StringBuilder());
  16. }
  17. public static BuilderWrapper Rent()
  18. {
  19. var builder = _pool.Allocate();
  20. Debug.Assert(builder.Length == 0);
  21. return new BuilderWrapper(builder, _pool);
  22. }
  23. internal readonly struct BuilderWrapper : IDisposable
  24. {
  25. public readonly StringBuilder Builder;
  26. private readonly ConcurrentObjectPool<StringBuilder> _pool;
  27. public BuilderWrapper(StringBuilder builder, ConcurrentObjectPool<StringBuilder> pool)
  28. {
  29. Builder = builder;
  30. _pool = pool;
  31. }
  32. public int Length => Builder.Length;
  33. public override string ToString()
  34. {
  35. return Builder.ToString();
  36. }
  37. public void Dispose()
  38. {
  39. var builder = Builder;
  40. // do not store builders that are too large.
  41. if (builder.Capacity <= 1024)
  42. {
  43. builder.Clear();
  44. _pool.Free(builder);
  45. }
  46. else
  47. {
  48. _pool.ForgetTrackedObject(builder);
  49. }
  50. }
  51. }
  52. }
  53. }