From f4289d12910457b7e6ebc96e1defb99c7ac7157d Mon Sep 17 00:00:00 2001 From: Taylor Southwick Date: Wed, 27 Nov 2024 11:37:43 -0800 Subject: [PATCH] make factory struct --- .../Framework/Metadata/ElementFactory.cs | 29 ++---- .../Metadata/ElementFactoryCollection.cs | 92 ++++++------------- 2 files changed, 36 insertions(+), 85 deletions(-) diff --git a/src/DocumentFormat.OpenXml.Framework/Framework/Metadata/ElementFactory.cs b/src/DocumentFormat.OpenXml.Framework/Framework/Metadata/ElementFactory.cs index 3717df7a4..f5c21d35e 100644 --- a/src/DocumentFormat.OpenXml.Framework/Framework/Metadata/ElementFactory.cs +++ b/src/DocumentFormat.OpenXml.Framework/Framework/Metadata/ElementFactory.cs @@ -4,29 +4,12 @@ using System; using System.Diagnostics; -namespace DocumentFormat.OpenXml.Framework.Metadata -{ - [DebuggerDisplay("{QName,nq}")] - internal sealed class ElementFactory - { - private readonly Func _factory; - - public ElementFactory(in OpenXmlSchemaType type, Func factory) - { - Type = type; - _factory = factory; - } - - public OpenXmlSchemaType Type { get; } +namespace DocumentFormat.OpenXml.Framework.Metadata; - public OpenXmlElement Create() => _factory(); - - public static ElementFactory Create() - where T : OpenXmlElement, new() - { - var instance = new T(); +[DebuggerDisplay("{QName,nq}")] +internal readonly struct ElementFactory(OpenXmlSchemaType type, Func factory) +{ + public OpenXmlSchemaType Type => type; - return new ElementFactory(instance.Metadata.Type, static () => new T()); - } - } + public OpenXmlElement Create() => factory(); } diff --git a/src/DocumentFormat.OpenXml.Framework/Framework/Metadata/ElementFactoryCollection.cs b/src/DocumentFormat.OpenXml.Framework/Framework/Metadata/ElementFactoryCollection.cs index 84ee4323d..bd7d5fc03 100644 --- a/src/DocumentFormat.OpenXml.Framework/Framework/Metadata/ElementFactoryCollection.cs +++ b/src/DocumentFormat.OpenXml.Framework/Framework/Metadata/ElementFactoryCollection.cs @@ -1,81 +1,49 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; using System.Collections.Generic; -using System.Linq; -namespace DocumentFormat.OpenXml.Framework.Metadata +namespace DocumentFormat.OpenXml.Framework.Metadata; + +/// +/// A lookup that identifies properties on an and caches the schema information +/// from those elements. +/// +internal class ElementFactoryCollection { - /// - /// A lookup that identifies properties on an and caches the schema information - /// from those elements. - /// - internal class ElementFactoryCollection - { - public static readonly ElementFactoryCollection Empty = new(Enumerable.Empty()); + public static readonly ElementFactoryCollection Empty = new([]); - private readonly ElementFactory[] _data; + private readonly List _data; - public ElementFactoryCollection(IEnumerable lookup) - { - var array = lookup.ToArray(); - - Array.Sort(array, ElementChildNameComparer.Instance); + public ElementFactoryCollection(List lookup) + { + lookup.Sort(ElementChildNameComparer.Instance); + _data = lookup; + } - _data = array; + public OpenXmlElement? Create(in OpenXmlQualifiedName qname) + { + if (_data.Count == 0) + { + return null; } - public int Count => _data.Length; + // This is on a hot-path and using a dictionary adds substantial time to the lookup. Most child lists are small, so using a sorted + // list to store them with a binary search improves overall performance. + var idx = _data.BinarySearch(new ElementFactory(new(qname, default), null!), ElementChildNameComparer.Instance); - public IEnumerable Elements => _data; - - public OpenXmlElement? Create(in OpenXmlQualifiedName qname) + if (idx < 0) { - if (_data.Length == 0) - { - return null; - } - - // This is on a hot-path and using a dictionary adds substantial time to the lookup. Most child lists are small, so using a sorted - // list to store them with a binary search improves overall performance. - var idx = Array.BinarySearch(_data, new ElementFactory(new(qname, default), null!), ElementChildNameComparer.Instance); - - if (idx < 0) - { - return null; - } - - return _data[idx].Create(); + return null; } - private class ElementChildNameComparer : IComparer - { - public static IComparer Instance { get; } = new ElementChildNameComparer(); - - private ElementChildNameComparer() - { - } - - public int Compare(ElementFactory? x, ElementFactory? y) - { - if (x is null && y is null) - { - return 0; - } - - if (x is null) - { - return -1; - } + return _data[idx].Create(); + } - if (y is null) - { - return 1; - } + private sealed class ElementChildNameComparer : IComparer + { + public static IComparer Instance { get; } = new ElementChildNameComparer(); - return x.Type.Name.CompareTo(y.Type.Name); - } - } + public int Compare(ElementFactory x, ElementFactory y) => x.Type.Name.CompareTo(y.Type.Name); } }