Skip to content

Commit be53c40

Browse files
committed
Revert "make factory struct"
This reverts commit 37c39894c115ed73a69d9ef222e81974d948e9b8.
1 parent d6e48cc commit be53c40

File tree

2 files changed

+85
-36
lines changed

2 files changed

+85
-36
lines changed

src/DocumentFormat.OpenXml.Framework/Framework/Metadata/ElementFactory.cs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,29 @@
44
using System;
55
using System.Diagnostics;
66

7-
namespace DocumentFormat.OpenXml.Framework.Metadata;
8-
9-
[DebuggerDisplay("{QName,nq}")]
10-
internal readonly struct ElementFactory(OpenXmlSchemaType type, Func<OpenXmlElement> factory)
7+
namespace DocumentFormat.OpenXml.Framework.Metadata
118
{
12-
public OpenXmlSchemaType Type => type;
9+
[DebuggerDisplay("{QName,nq}")]
10+
internal sealed class ElementFactory
11+
{
12+
private readonly Func<OpenXmlElement> _factory;
13+
14+
public ElementFactory(in OpenXmlSchemaType type, Func<OpenXmlElement> factory)
15+
{
16+
Type = type;
17+
_factory = factory;
18+
}
19+
20+
public OpenXmlSchemaType Type { get; }
21+
22+
public OpenXmlElement Create() => _factory();
23+
24+
public static ElementFactory Create<T>()
25+
where T : OpenXmlElement, new()
26+
{
27+
var instance = new T();
1328

14-
public OpenXmlElement Create() => factory();
29+
return new ElementFactory(instance.Metadata.Type, static () => new T());
30+
}
31+
}
1532
}
Lines changed: 62 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,81 @@
11
// Copyright (c) Microsoft. All rights reserved.
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

4+
using System;
45
using System.Collections.Generic;
6+
using System.Linq;
57

6-
namespace DocumentFormat.OpenXml.Framework.Metadata;
7-
8-
/// <summary>
9-
/// A lookup that identifies properties on an <see cref="OpenXmlElement"/> and caches the schema information
10-
/// from those elements.
11-
/// </summary>
12-
internal class ElementFactoryCollection
8+
namespace DocumentFormat.OpenXml.Framework.Metadata
139
{
14-
public static readonly ElementFactoryCollection Empty = new([]);
15-
16-
private readonly List<ElementFactory> _data;
17-
18-
public ElementFactoryCollection(List<ElementFactory> lookup)
10+
/// <summary>
11+
/// A lookup that identifies properties on an <see cref="OpenXmlElement"/> and caches the schema information
12+
/// from those elements.
13+
/// </summary>
14+
internal class ElementFactoryCollection
1915
{
20-
lookup.Sort(ElementChildNameComparer.Instance);
21-
_data = lookup;
22-
}
16+
public static readonly ElementFactoryCollection Empty = new(Enumerable.Empty<ElementFactory>());
2317

24-
public OpenXmlElement? Create(in OpenXmlQualifiedName qname)
25-
{
26-
if (_data.Count == 0)
18+
private readonly ElementFactory[] _data;
19+
20+
public ElementFactoryCollection(IEnumerable<ElementFactory> lookup)
2721
{
28-
return null;
22+
var array = lookup.ToArray();
23+
24+
Array.Sort(array, ElementChildNameComparer.Instance);
25+
26+
_data = array;
2927
}
3028

31-
// 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
32-
// list to store them with a binary search improves overall performance.
33-
var idx = _data.BinarySearch(new ElementFactory(new(qname, default), null!), ElementChildNameComparer.Instance);
29+
public int Count => _data.Length;
3430

35-
if (idx < 0)
31+
public IEnumerable<ElementFactory> Elements => _data;
32+
33+
public OpenXmlElement? Create(in OpenXmlQualifiedName qname)
3634
{
37-
return null;
35+
if (_data.Length == 0)
36+
{
37+
return null;
38+
}
39+
40+
// 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
41+
// list to store them with a binary search improves overall performance.
42+
var idx = Array.BinarySearch(_data, new ElementFactory(new(qname, default), null!), ElementChildNameComparer.Instance);
43+
44+
if (idx < 0)
45+
{
46+
return null;
47+
}
48+
49+
return _data[idx].Create();
3850
}
3951

40-
return _data[idx].Create();
41-
}
52+
private class ElementChildNameComparer : IComparer<ElementFactory>
53+
{
54+
public static IComparer<ElementFactory> Instance { get; } = new ElementChildNameComparer();
4255

43-
private sealed class ElementChildNameComparer : IComparer<ElementFactory>
44-
{
45-
public static IComparer<ElementFactory> Instance { get; } = new ElementChildNameComparer();
56+
private ElementChildNameComparer()
57+
{
58+
}
4659

47-
public int Compare(ElementFactory x, ElementFactory y) => x.Type.Name.CompareTo(y.Type.Name);
60+
public int Compare(ElementFactory? x, ElementFactory? y)
61+
{
62+
if (x is null && y is null)
63+
{
64+
return 0;
65+
}
66+
67+
if (x is null)
68+
{
69+
return -1;
70+
}
71+
72+
if (y is null)
73+
{
74+
return 1;
75+
}
76+
77+
return x.Type.Name.CompareTo(y.Type.Name);
78+
}
79+
}
4880
}
4981
}

0 commit comments

Comments
 (0)