public List <BusinessCode> ReadAll() { _sempaphore.Wait(); try { List <BusinessCode> result = new List <BusinessCode>(20); byte[] bytes = new byte[BusinessCode.BYTES_LENGTH]; foreach (var index in _indexQueue.ToArray()) { _dataFS.Seek(index.Position, SeekOrigin.Begin); _dataFS.Read(bytes, 0, bytes.Length); var code = new BusinessCode(bytes); if (code.ApplicationId != index.ApplicationID || code.CodeType != index.CodeType) { _logger.LogError($"Data file invalid. index info: applicationId={index.ApplicationID}, codeType={index.CodeType}"); } result.Add(code); } return(result); } catch { return(new List <BusinessCode>()); } finally { _sempaphore.Release(); } }
public async Task WriteAsync(BusinessCode codeToFlush, long globalVersion) { if (codeToFlush == null) { return; } _sempaphore.Wait(); try { byte[] dataBytes = new byte[BusinessCode.BYTES_LENGTH]; var code = new BusinessCode(codeToFlush.ToBytes());// 防止2次读取不一致 var existsCodeIndex = _indexQueue.FirstOrDefault(m => m.ApplicationID == code.ApplicationId && m.CodeType == code.CodeType); if (existsCodeIndex == null) { _dataFS.Seek(0, SeekOrigin.End); var indexPosition = _dataFS.Position; dataBytes = code.ToBytes(); await _dataFS.WriteAsync(dataBytes, 0, dataBytes.Length); var codeIndex = new BusinessCodeIndex { ApplicationID = code.ApplicationId, CodeType = code.CodeType, Position = indexPosition }; var codeIndexBytes = codeIndex.ToBytes(); await _indexFS.WriteAsync(codeIndexBytes, 0, codeIndexBytes.Length); _indexQueue.Enqueue(codeIndex); } else { _dataFS.Seek(existsCodeIndex.Position, SeekOrigin.Begin); _dataFS.Read(dataBytes, 0, dataBytes.Length); var currentCode = new BusinessCode(dataBytes); if (code.ApplicationId != currentCode.ApplicationId || code.CodeType != currentCode.CodeType) { _logger.LogError($"Bad file {_dataFileName}, applicationId={codeToFlush.ApplicationId}, codeType={codeToFlush.CodeType}"); throw new InvalidDataException($"Bad file {_dataFileName}"); } if (code.ApplicationId == currentCode.ApplicationId && code.CodeType == currentCode.CodeType) { if (code.VersionId < currentCode.VersionId) { _logger.LogError($"Bad file {_dataFileName}, version is invalid, applicationId={codeToFlush.ApplicationId}, codeType={codeToFlush.CodeType}, versionId={codeToFlush.VersionId}"); throw new InvalidDataException($"Bad file {_dataFileName}"); } if (code.Infix != currentCode.Infix || code.Sequence != currentCode.Sequence) { if (code.Infix == currentCode.Infix && code.Sequence < currentCode.Sequence) { _logger.LogError($"Bad file {_dataFileName}, sequence is invalid, applicationId={codeToFlush.ApplicationId}, codeType={codeToFlush.CodeType}, sequence={codeToFlush.Sequence}"); throw new InvalidDataException($"Bad file {_dataFileName}"); } _dataFS.Seek(existsCodeIndex.Position, SeekOrigin.Begin); dataBytes = code.ToBytes(); await _dataFS.WriteAsync(dataBytes, 0, dataBytes.Length); } } } // 写入全局版本号 _dataFS.Seek(0, SeekOrigin.Begin); await _dataFS.WriteAsync(BitConverter.GetBytes(globalVersion), 0, 8); } catch (Exception ex) { _logger.LogError($"Write fail: {ex.Message}, applicationId={codeToFlush.ApplicationId}, codeType={codeToFlush.CodeType}", ex); throw; } finally { _sempaphore.Release(); } }