-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
frfr no cap
- Loading branch information
Showing
5 changed files
with
142 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,69 +1,39 @@ | ||
namespace StarBreaker.DataCore; | ||
using System.Runtime.InteropServices; | ||
using System.Xml.Linq; | ||
|
||
/// <summary> | ||
/// The strategy to use when resolving repeated references in the data core. | ||
/// </summary> | ||
public enum DataCoreRepeatedReferenceResolutionStrategy | ||
{ | ||
/// <summary> | ||
/// Each instance will be written once per file. Subsequent references will be written as a reference to the original instance. | ||
/// </summary> | ||
PerFile, | ||
|
||
/// <summary> | ||
/// Each instance will be written once per node. References to the original instance will be used when they are children of the original. | ||
/// Otherwise, the instance will be written again. | ||
/// </summary> | ||
PerNode, | ||
} | ||
namespace StarBreaker.DataCore; | ||
|
||
public sealed class DataCoreExtractionContext | ||
{ | ||
private readonly HashSet<(int structIndex, int instanceIndex)> _hashSet; | ||
private readonly Stack<(int structIndex, int instanceIndex)> _stack; | ||
private readonly Dictionary<(int structIndex, int instanceIndex), int> _weakPointerIds; | ||
private int _nextWeakPointerId = 0; | ||
|
||
public Dictionary<(int structIndex, int instanceIndex), XElement> Elements { get; } | ||
|
||
public string FileName { get; } | ||
public DataCoreRepeatedReferenceResolutionStrategy Strategy { get; } | ||
public bool ShouldWriteMetadata { get; } | ||
public bool ShouldWriteNulls { get; } | ||
|
||
public DataCoreExtractionContext(string fileName, DataCoreRepeatedReferenceResolutionStrategy strategy) | ||
public DataCoreExtractionContext(string fileName, bool shouldWriteMetadata = false, bool shouldWriteNulls = false) | ||
{ | ||
_hashSet = []; | ||
_stack = []; | ||
FileName = fileName; | ||
Strategy = strategy; | ||
ShouldWriteMetadata = shouldWriteMetadata; | ||
ShouldWriteNulls = shouldWriteNulls; | ||
Elements = []; | ||
_weakPointerIds = []; | ||
} | ||
|
||
public bool AlreadyWroteInstance(int structIndex, int instanceIndex) | ||
public int AddWeakPointer(int structIndex, int instanceIndex) | ||
{ | ||
return Strategy switch | ||
{ | ||
DataCoreRepeatedReferenceResolutionStrategy.PerFile => _hashSet.Contains((structIndex, instanceIndex)), | ||
DataCoreRepeatedReferenceResolutionStrategy.PerNode => _stack.Contains((structIndex, instanceIndex)), | ||
_ => throw new ArgumentOutOfRangeException() | ||
}; | ||
} | ||
ref var id = ref CollectionsMarshal.GetValueRefOrAddDefault(_weakPointerIds, (structIndex, instanceIndex), out var existed); | ||
|
||
public void Push(int structIndex, int instanceIndex) | ||
{ | ||
switch (Strategy) | ||
{ | ||
case DataCoreRepeatedReferenceResolutionStrategy.PerFile: | ||
_hashSet.Add((structIndex, instanceIndex)); | ||
break; | ||
case DataCoreRepeatedReferenceResolutionStrategy.PerNode: | ||
_stack.Push((structIndex, instanceIndex)); | ||
break; | ||
default: | ||
throw new ArgumentOutOfRangeException(); | ||
} | ||
} | ||
|
||
public void Pop() | ||
{ | ||
if (Strategy == DataCoreRepeatedReferenceResolutionStrategy.PerNode) | ||
_stack.Pop(); | ||
if (!existed) | ||
id = _nextWeakPointerId++; | ||
|
||
// Otherwise, do nothing. | ||
return id; | ||
} | ||
} | ||
|
||
public int GetWeakPointerId(int structIndex, int instanceIndex) => _weakPointerIds[(structIndex, instanceIndex)]; | ||
|
||
public IEnumerable<(int structIndex, int instanceIndex)> GetWeakPointers() => _weakPointerIds.Keys; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using System.Xml.Linq; | ||
|
||
namespace StarBreaker.DataCore; | ||
|
||
public static class XObjectExtensions | ||
{ | ||
public static XElement WithAttribute(this XElement xObject, string name, string value, bool write = true) | ||
{ | ||
if (write) | ||
xObject.Add(new XAttribute(name, value)); | ||
|
||
return xObject; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters