DataMapper 개선, MQTTPipeLine 개발 중
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
#nullable enable
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
|
||||
namespace UVC.Data
|
||||
{
|
||||
@@ -10,15 +13,23 @@ namespace UVC.Data
|
||||
// 직접적인 변경이 있었던 키를 저장하는 리스트
|
||||
protected List<string> changedProperies = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 변경된 속성의 키 목록을 읽기 전용으로 반환합니다.
|
||||
/// </summary>
|
||||
public ReadOnlyCollection<string> ChangedProperies => changedProperies.AsReadOnly();
|
||||
|
||||
// 기존에 있던 속성 키를 추적하기 위한 집합
|
||||
private HashSet<string> existingProperties = new HashSet<string>();
|
||||
|
||||
public DataObject()
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// 기본 생성자입니다. 빈 데이터 객체를 생성합니다.
|
||||
/// </summary>
|
||||
public DataObject() {}
|
||||
|
||||
/// <summary>
|
||||
/// JObject로부터 데이터 객체를 생성합니다.
|
||||
/// </summary>
|
||||
/// <param name="other">복사할 JObject 객체</param>
|
||||
public DataObject(JObject other)
|
||||
{
|
||||
// JObject로부터 속성을 복사
|
||||
@@ -30,7 +41,10 @@ namespace UVC.Data
|
||||
}
|
||||
}
|
||||
|
||||
// Dictionary로 초기화하는 생성자 추가
|
||||
/// <summary>
|
||||
/// Dictionary로 데이터 객체를 초기화합니다.
|
||||
/// </summary>
|
||||
/// <param name="dictionary">초기화에 사용할 Dictionary 객체</param>
|
||||
public DataObject(Dictionary<string, object> dictionary) : base(dictionary)
|
||||
{
|
||||
// 생성자에서 초기 속성들을 기존 속성으로 등록
|
||||
@@ -40,7 +54,11 @@ namespace UVC.Data
|
||||
}
|
||||
}
|
||||
|
||||
// JToken을 실제 객체로 변환하는 헬퍼 메서드
|
||||
/// <summary>
|
||||
/// JToken을 적절한 C# 객체 타입으로 변환하는 헬퍼 메서드입니다.
|
||||
/// </summary>
|
||||
/// <param name="token">변환할 JToken 객체</param>
|
||||
/// <returns>변환된 C# 객체</returns>
|
||||
private object ConvertJTokenToObject(JToken token)
|
||||
{
|
||||
switch (token.Type)
|
||||
@@ -65,28 +83,20 @@ namespace UVC.Data
|
||||
|
||||
/// <summary>
|
||||
/// 모든 프로퍼티를 변경된 것으로 표시합니다.
|
||||
/// 전체 데이터가 갱신되었을 때 사용합니다.
|
||||
/// </summary>
|
||||
public void ChangeAll()
|
||||
public void InitData()
|
||||
{
|
||||
changedProperies.Clear();
|
||||
|
||||
foreach (var key in this.Keys)
|
||||
{
|
||||
changedProperies.Add(key);
|
||||
}
|
||||
changedProperies.AddRange(this.Keys);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 변경된 키 목록을 초기화합니다.
|
||||
/// </summary>
|
||||
public void ClearChangedKeys()
|
||||
{
|
||||
changedProperies.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 속성이 변경될 때 호출되는 메서드입니다.
|
||||
/// 파생 클래스에서 오버라이드하여 추가 동작을 정의할 수 있습니다.
|
||||
/// </summary>
|
||||
/// <param name="propertyName">변경된 속성의 이름</param>
|
||||
protected virtual void OnPropertyChanged(string propertyName)
|
||||
{
|
||||
// 기존에 존재하던 속성인 경우에만 변경된 것으로 추적
|
||||
@@ -107,6 +117,8 @@ namespace UVC.Data
|
||||
/// <summary>
|
||||
/// 새 속성을 추가할 때 이벤트 연결을 처리합니다.
|
||||
/// </summary>
|
||||
/// <param name="propertyName">추가할 속성의 이름</param>
|
||||
/// <param name="value">속성의 값</param>
|
||||
public new void Add(string propertyName, object value)
|
||||
{
|
||||
// 추가하기 전에 확인 - 속성이 이미 있는지 확인
|
||||
@@ -124,6 +136,7 @@ namespace UVC.Data
|
||||
|
||||
/// <summary>
|
||||
/// 인덱서를 통한 속성 설정을 처리합니다.
|
||||
/// 속성 변경 시 변경 사항을 자동으로 추적합니다.
|
||||
/// </summary>
|
||||
public new object this[string key]
|
||||
{
|
||||
@@ -154,6 +167,7 @@ namespace UVC.Data
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int GetInt(string propertyName, int defaultValue = 0)
|
||||
{
|
||||
if (TryGetValue(propertyName, out object value) && value != null)
|
||||
@@ -165,7 +179,7 @@ namespace UVC.Data
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public string GetString(string propertyName, string defaultValue = "")
|
||||
public string? GetString(string propertyName, string? defaultValue = null)
|
||||
{
|
||||
if (TryGetValue(propertyName, out object value) && value != null)
|
||||
{
|
||||
@@ -229,7 +243,7 @@ namespace UVC.Data
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public DataArray GetDataArray(string propertyName, DataArray? defaultValue = null)
|
||||
public DataArray? GetDataArray(string propertyName, DataArray? defaultValue = null)
|
||||
{
|
||||
if (TryGetValue(propertyName, out object value) && value != null)
|
||||
{
|
||||
@@ -241,7 +255,7 @@ namespace UVC.Data
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public DataObject GetDataObject(string propertyName, DataObject? defaultValue = null)
|
||||
public DataObject? GetDataObject(string propertyName, DataObject? defaultValue = null)
|
||||
{
|
||||
if (TryGetValue(propertyName, out object value) && value != null)
|
||||
{
|
||||
@@ -258,6 +272,8 @@ namespace UVC.Data
|
||||
/// <summary>
|
||||
/// 속성이 제거될 때 기존 속성 목록에서도 제거합니다.
|
||||
/// </summary>
|
||||
/// <param name="key">제거할 속성의 키</param>
|
||||
/// <returns>제거 성공 여부</returns>
|
||||
public new bool Remove(string key)
|
||||
{
|
||||
bool result = base.Remove(key);
|
||||
@@ -280,8 +296,9 @@ namespace UVC.Data
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// JObject로 변환
|
||||
/// 현재 DataObject를 JObject로 변환합니다.
|
||||
/// </summary>
|
||||
/// <returns>현재 객체의 데이터를 담은 JObject</returns>
|
||||
public JObject ToJObject()
|
||||
{
|
||||
JObject result = new JObject();
|
||||
@@ -292,10 +309,16 @@ namespace UVC.Data
|
||||
return result;
|
||||
}
|
||||
|
||||
public void SetDifferent(DataObject other)
|
||||
/// <summary>
|
||||
/// 다른 DataObject와 현재 객체를 비교하여 다른 부분만 설정합니다.
|
||||
/// 변경된 키는 자동으로 추적됩니다.
|
||||
/// </summary>
|
||||
/// <param name="other">비교할 DataObject</param>
|
||||
public void UpdateDifferent(IDataObject other)
|
||||
{
|
||||
if (other == null || other is not DataObject) return;
|
||||
changedProperies.Clear();
|
||||
foreach (var keyValue in other)
|
||||
foreach (var keyValue in (DataObject)other)
|
||||
{
|
||||
if(!this.ContainsKey(keyValue.Key) || !this[keyValue.Key].Equals(keyValue.Value))
|
||||
{
|
||||
@@ -304,6 +327,91 @@ namespace UVC.Data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 업데이트된 속성만 포함하는 새로운 DataObject를 반환합니다.
|
||||
/// </summary>
|
||||
/// <returns>업데이트 된 항목만 가지고 있는 DataObject</returns>
|
||||
public IDataObject GetUpdatedObject()
|
||||
{
|
||||
DataObject updated = new DataObject();
|
||||
foreach (var key in changedProperies)
|
||||
{
|
||||
if (this.ContainsKey(key))
|
||||
{
|
||||
updated[key] = this[key];
|
||||
}
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Join(", ", this.Select(kvp => $"{kvp.Key}:{kvp.Value}"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// DataObject 인스턴스를 재사용하기 위한 객체 풀 클래스입니다.
|
||||
/// 메모리 할당과 가비지 컬렉션을 최소화하기 위해 DataObject 인스턴스를 관리합니다.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 객체 풀링은 자주 생성 및 삭제되는 객체의 성능을 향상시키는 패턴입니다.
|
||||
/// 사용이 끝난 객체를 삭제하는 대신 풀에 반환하고, 새 객체가 필요할 때 풀에서 꺼내 재사용합니다.
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // 객체 풀에서 DataObject 가져오기
|
||||
/// DataObject obj = DataObjectPool.GetDataObjectFromPool();
|
||||
///
|
||||
/// // 객체 사용
|
||||
/// obj["name"] = "홍길동";
|
||||
/// obj["age"] = 30;
|
||||
///
|
||||
/// // 작업 완료 후 풀에 반환
|
||||
/// DataObjectPool.ReturnToPool(obj);
|
||||
/// </code>
|
||||
/// </example>
|
||||
public static class DataObjectPool
|
||||
{
|
||||
/// <summary>
|
||||
/// DataObject 인스턴스를 저장하는 큐입니다.
|
||||
/// </summary>
|
||||
private static Queue<DataObject> dataObjectPool = new Queue<DataObject>();
|
||||
/// <summary>
|
||||
/// 풀의 최대 크기입니다. 이 크기를 초과하는 객체는 풀에 저장되지 않습니다.
|
||||
/// </summary>
|
||||
private static int maxPoolSize = 1000;
|
||||
|
||||
/// <summary>
|
||||
/// 풀에서 DataObject 인스턴스를 가져옵니다.
|
||||
/// 풀이 비어있으면 새 인스턴스를 생성하여 반환합니다.
|
||||
/// </summary>
|
||||
/// <returns>재사용 가능한 DataObject 인스턴스</returns>
|
||||
public static DataObject GetDataObjectFromPool()
|
||||
{
|
||||
if (dataObjectPool.Count > 0)
|
||||
{
|
||||
return dataObjectPool.Dequeue();
|
||||
}
|
||||
return new DataObject();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 사용이 완료된 DataObject를 풀에 반환합니다.
|
||||
/// 객체는 반환 전에 초기화되어 모든 속성이 제거됩니다.
|
||||
/// </summary>
|
||||
/// <param name="obj">풀에 반환할 DataObject 인스턴스</param>
|
||||
public static void ReturnToPool(DataObject obj)
|
||||
{
|
||||
if (obj != null && dataObjectPool.Count < maxPoolSize)
|
||||
{
|
||||
obj.RemoveAll(); // 재사용 전 정리
|
||||
dataObjectPool.Enqueue(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user