Skip to content

Commit

Permalink
Apply refactors and fixes suggested by JetBrains Rider.
Browse files Browse the repository at this point in the history
  • Loading branch information
ShikiSuen committed Feb 13, 2025
1 parent edb28dc commit 3cd1bf6
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 39 deletions.
49 changes: 24 additions & 25 deletions Megrez/src/0_CSharpExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@ public class HybridPriorityQueue<T> : IDisposable
private const int ArrayThreshold = 12; // 快取大小。
private const int InitialCapacity = 16; // 預設容量設為 2 的冪次以優化記憶體對齊。
private T[] _storage; // 改用陣列以減少記憶體間接引用。
private int _count; // 追蹤實際元素數量。
private readonly bool _isReversed;
private bool _usingArray;
private readonly object _syncRoot = new();
Expand All @@ -166,76 +165,76 @@ public class HybridPriorityQueue<T> : IDisposable
public HybridPriorityQueue(bool reversed = false) {
_isReversed = reversed;
_storage = new T[InitialCapacity];
_count = 0;
Count = 0;
_usingArray = true;
}

/// <summary>
/// 取得佇列中的元素數量。
/// </summary>
public int Count => _count;
public int Count { get; private set; }

/// <summary>
/// 檢查佇列是否為空。
/// </summary>
public bool IsEmpty => _count == 0;
public bool IsEmpty => Count == 0;

public void Enqueue(T element) {
lock (_syncRoot) {
// 確保容量足夠
if (_count == _storage.Length) {
if (Count == _storage.Length) {
Array.Resize(ref _storage, _storage.Length * 2);
}

if (_usingArray) {
if (_count >= ArrayThreshold) {
if (Count >= ArrayThreshold) {
SwitchToHeap();
_storage[_count++] = element;
HeapifyUp(_count - 1);
_storage[Count++] = element;
HeapifyUp(Count - 1);
return;
}

// 使用二分搜尋找到插入點。
int insertIndex = FindInsertionPoint(element);
// 手動移動元素以避免使用 Array.Copy(減少函數呼叫開銷)。
for (int i = _count; i > insertIndex; i--) {
for (int i = Count; i > insertIndex; i--) {
_storage[i] = _storage[i - 1];
}
_storage[insertIndex] = element;
_count++;
Count++;
} else {
_storage[_count] = element;
HeapifyUp(_count++);
_storage[Count] = element;
HeapifyUp(Count++);
}
}
}

public T? Dequeue() {
lock (_syncRoot) {
if (_count == 0) return default;
if (Count == 0) return default;

T result = _storage[0];
_count--;
Count--;

if (_usingArray) {
// 手動移動元素以避免使用 Array.Copy。
for (int i = 0; i < _count; i++) {
for (int i = 0; i < Count; i++) {
_storage[i] = _storage[i + 1];
}
return result;
}

// 堆積模式。
_storage[0] = _storage[_count];
if (_count > 0) HeapifyDown(0);
_storage[0] = _storage[Count];
if (Count > 0) HeapifyDown(0);
return result;
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int FindInsertionPoint(T element) {
int left = 0;
int right = _count;
int right = Count;

while (left < right) {
int mid = left + ((right - left) >> 1);
Expand All @@ -259,16 +258,16 @@ private int FindInsertionPoint(T element) {

private void SwitchToHeap() {
var backupStorage = (T[])_storage.Clone();
var backupCount = _count;
var backupCount = Count;

try {
_usingArray = false;
for (int i = (_count >> 1) - 1; i >= 0; i--) {
for (int i = (Count >> 1) - 1; i >= 0; i--) {
HeapifyDown(i);
}
} catch (Exception) {
_storage = backupStorage;
_count = backupCount;
Count = backupCount;
_usingArray = true;
throw;
}
Expand All @@ -290,7 +289,7 @@ private void HeapifyUp(int index) {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void HeapifyDown(int index) {
T item = _storage[index];
int half = _count >> 1;
int half = Count >> 1;

while (index < half) {
int leftChild = (index << 1) + 1;
Expand All @@ -299,7 +298,7 @@ private void HeapifyDown(int index) {

T leftChildItem = _storage[leftChild];

if (rightChild < _count) {
if (rightChild < Count) {
T rightChildItem = _storage[rightChild];
if (Compare(rightChildItem, leftChildItem) < 0) {
bestChild = rightChild;
Expand Down Expand Up @@ -328,7 +327,7 @@ public void Clear() {
_storage = new T[InitialCapacity];
}
}
_count = 0;
Count = 0;
_usingArray = true;
}

Expand All @@ -354,7 +353,7 @@ public override int GetHashCode() {
unchecked {
int hash = 17;
hash = hash * 23 + _storage.GetHashCode();
hash = hash * 23 + _count.GetHashCode();
hash = hash * 23 + Count.GetHashCode();
hash = hash * 23 + _isReversed.GetHashCode();
hash = hash * 23 + _usingArray.GetHashCode();
return hash;
Expand Down
46 changes: 32 additions & 14 deletions Megrez/src/1_Compositor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,7 @@ public Compositor(Compositor compositor) {
/// 且將已經被插入的索引鍵陣列與幅位單元陣列(包括其內的節點)全部清空。
/// 最近一次的爬軌結果陣列也會被清空。游標跳轉換算表也會被清空。
/// </summary>
public void Clear() {
string oldSeparator = Config.Separator;
Config = new() { Separator = oldSeparator };
}
public void Clear() { Config.Clear(); }

/// <summary>
/// 在游標位置插入給定的索引鍵。
Expand Down Expand Up @@ -431,7 +428,7 @@ private List<string> GetJoinedKeyArray(BRange range) =>
/// <param name="keyArray">指定索引鍵陣列。</param>
/// <returns>拿取的節點。拿不到的話就會是 null。</returns>
private Node? GetNodeAt(int location, int length, List<string> keyArray) {
location = Math.Max(Math.Min(location, Spans.Count - 1), 0); // 防呆。
location = Math.Max(Math.Min(location, Spans.Count), 0); // 防呆。
if (location < 0 || location >= Spans.Count) return null;
if (Spans[location].NodeOf(length) is not {} node) return null;
return node.KeyArray.SequenceEqual(keyArray) ? node : null;
Expand Down Expand Up @@ -483,20 +480,32 @@ public struct CompositorConfig {
/// <summary>
/// 初期化一套組字器組態設定。
/// </summary>
public CompositorConfig(string separator = "") { _separator = separator; }
public CompositorConfig(List<Node>? walkedNodes = null, List<string>? keys = null,
List<Compositor.SpanUnit>? spans = null, int cursor = 0, int maxSpanLength = 10,
int marker = 0, string? separator = null) {
WalkedNodes = walkedNodes ?? new List<Node>();
Keys = keys ?? new List<string>();
Spans = spans ?? new List<Compositor.SpanUnit>();
_cursor = cursor;
_maxSpanLength = maxSpanLength;
_marker = marker;
Separator = separator ?? "";
}

/// <summary>
/// 最近一次爬軌結果。
/// </summary>
public List<Node> WalkedNodes = new();
public List<Node> WalkedNodes { get; set; }

/// <summary>
/// 該組字器已經插入的的索引鍵,以陣列的形式存放。
/// </summary>
public List<string> Keys = new();
public List<string> Keys { get; set; }

/// <summary>
/// 該組字器的幅位單元陣列。
/// </summary>
public List<Compositor.SpanUnit> Spans = new();
public List<Compositor.SpanUnit> Spans { get; set; }

private int _cursor = 0;
/// <summary>
Expand Down Expand Up @@ -529,17 +538,13 @@ public int Marker {
set => _marker = Math.Max(0, Math.Min(value, Length));
}

private string _separator;
/// <summary>
/// 在生成索引鍵字串時用來分割每個索引鍵單位。最好是鍵盤無法直接敲的 ASCII 字元。
/// </summary>
/// <remarks>
/// 更新該內容會同步更新 <see cref="Compositor.TheSeparator"/>;每次初期化一個新的組字器的時候都會覆寫之。
/// </remarks>
public string Separator {
get => _separator;
set => _separator = value;
}
public string Separator { get; set; }

/// <summary>
/// 公開:該組字器的長度。<para/>
Expand Down Expand Up @@ -601,5 +606,18 @@ public override int GetHashCode() {
return hash;
}
}

/// <summary>
/// 重置包括游標在內的各項參數,且清空各種由組字器生成的內部資料。<para/>
/// 且將已經被插入的索引鍵陣列與幅位單元陣列(包括其內的節點)全部清空。
/// 最近一次的爬軌結果陣列也會被清空。游標跳轉換算表也會被清空。
/// </summary>
public void Clear() {
Keys = new();
Spans = new();
WalkedNodes = new();
Cursor = 0;
Marker = 0;
}
}
} // namespace Megrez
5 changes: 5 additions & 0 deletions Megrez/src/6_LangModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ public List<Unigram> UnigramsFor(List<string> keyArray) =>
TheLangModel.UnigramsFor(keyArray).StableSorted((x, y) => y.Score.CompareTo(x.Score));
/// <inheritdoc />
public bool HasUnigramsFor(List<string> keyArray) => TheLangModel.HasUnigramsFor(keyArray);

/// <summary>
///
/// </summary>
/// <returns></returns>
public override int GetHashCode() {
unchecked {
int hash = 17;
Expand Down

0 comments on commit 3cd1bf6

Please sign in to comment.