10 changed files with 1291 additions and 0 deletions
@ -0,0 +1,265 @@ |
|||
# ---> Node |
|||
# Logs |
|||
logs |
|||
*.log |
|||
npm-debug.log* |
|||
yarn-debug.log* |
|||
yarn-error.log* |
|||
lerna-debug.log* |
|||
|
|||
# Diagnostic reports (https://nodejs.org/api/report.html) |
|||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json |
|||
|
|||
# Runtime data |
|||
pids |
|||
*.pid |
|||
*.seed |
|||
*.pid.lock |
|||
|
|||
# Directory for instrumented libs generated by jscoverage/JSCover |
|||
lib-cov |
|||
|
|||
# Coverage directory used by tools like istanbul |
|||
coverage |
|||
*.lcov |
|||
|
|||
# nyc test coverage |
|||
.nyc_output |
|||
|
|||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) |
|||
.grunt |
|||
|
|||
# Bower dependency directory (https://bower.io/) |
|||
bower_components |
|||
|
|||
# node-waf configuration |
|||
.lock-wscript |
|||
|
|||
# Compiled binary addons (https://nodejs.org/api/addons.html) |
|||
build/Release |
|||
|
|||
# Dependency directories |
|||
node_modules/ |
|||
jspm_packages/ |
|||
|
|||
# Snowpack dependency directory (https://snowpack.dev/) |
|||
web_modules/ |
|||
|
|||
# TypeScript cache |
|||
*.tsbuildinfo |
|||
|
|||
# Optional npm cache directory |
|||
.npm |
|||
|
|||
# Optional eslint cache |
|||
.eslintcache |
|||
|
|||
# Microbundle cache |
|||
.rpt2_cache/ |
|||
.rts2_cache_cjs/ |
|||
.rts2_cache_es/ |
|||
.rts2_cache_umd/ |
|||
|
|||
# Optional REPL history |
|||
.node_repl_history |
|||
|
|||
# Output of 'npm pack' |
|||
*.tgz |
|||
|
|||
# Yarn Integrity file |
|||
.yarn-integrity |
|||
|
|||
# dotenv environment variables file |
|||
.env |
|||
.env.test |
|||
|
|||
# parcel-bundler cache (https://parceljs.org/) |
|||
.cache |
|||
.parcel-cache |
|||
|
|||
# Next.js build output |
|||
.next |
|||
out |
|||
|
|||
# Nuxt.js build / generate output |
|||
.nuxt |
|||
dist |
|||
|
|||
# Gatsby files |
|||
.cache/ |
|||
# Comment in the public line in if your project uses Gatsby and not Next.js |
|||
# https://nextjs.org/blog/next-9-1#public-directory-support |
|||
# public |
|||
|
|||
# vuepress build output |
|||
.vuepress/dist |
|||
|
|||
# Serverless directories |
|||
.serverless/ |
|||
|
|||
# FuseBox cache |
|||
.fusebox/ |
|||
|
|||
# DynamoDB Local files |
|||
.dynamodb/ |
|||
|
|||
# TernJS port file |
|||
.tern-port |
|||
|
|||
# Stores VSCode versions used for testing VSCode extensions |
|||
.vscode-test |
|||
|
|||
# yarn v2 |
|||
.yarn/cache |
|||
.yarn/unplugged |
|||
.yarn/build-state.yml |
|||
.yarn/install-state.gz |
|||
.pnp.* |
|||
|
|||
# ---> Node |
|||
# Logs |
|||
logs |
|||
*.log |
|||
npm-debug.log* |
|||
yarn-debug.log* |
|||
yarn-error.log* |
|||
|
|||
# Runtime data |
|||
pids |
|||
*.pid |
|||
*.seed |
|||
*.pid.lock |
|||
|
|||
# Directory for instrumented libs generated by jscoverage/JSCover |
|||
lib-cov |
|||
|
|||
# Coverage directory used by tools like istanbul |
|||
coverage/ |
|||
|
|||
# nyc test coverage |
|||
.nyc_output |
|||
|
|||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) |
|||
.grunt |
|||
|
|||
# Bower dependency directory (https://bower.io/) |
|||
bower_components |
|||
|
|||
# node-waf configuration |
|||
.lock-wscript |
|||
|
|||
# Compiled binary addons (https://nodejs.org/api/addons.html) |
|||
build/ |
|||
|
|||
# Dependency directories |
|||
node_modules/ |
|||
jspm_packages/ |
|||
|
|||
# TypeScript v1 declaration files |
|||
typings/ |
|||
|
|||
# Optional npm cache directory |
|||
.npm |
|||
|
|||
# Optional eslint cache |
|||
.eslintcache |
|||
|
|||
# Optional REPL history |
|||
.node_repl_history |
|||
|
|||
# Output of 'npm pack' |
|||
*.tgz |
|||
|
|||
# Yarn Integrity file |
|||
.yarn-integrity |
|||
|
|||
# dotenv environment variables file |
|||
.env |
|||
|
|||
# parcel-bundler cache (https://parceljs.org/) |
|||
.cache |
|||
|
|||
# next.js build output |
|||
.next |
|||
|
|||
# Serverless directories |
|||
.serverless |
|||
|
|||
# FuseBox cache |
|||
.fusebox/ |
|||
|
|||
# Idea files |
|||
.idea |
|||
|
|||
# VSCode files |
|||
.vscode |
|||
|
|||
# DevExpress Code clean |
|||
.cr |
|||
|
|||
# Build results |
|||
[Bb]uild.[Uu]nit[Tt]est/ |
|||
[Dd]ebug/ |
|||
[Dd]ebugPublic/ |
|||
[Rr]elease/ |
|||
[Rr]eleases/ |
|||
x64/ |
|||
x86/ |
|||
[Ww][Ii][Nn]32/ |
|||
[Aa][Rr][Mm]/ |
|||
[Aa][Rr][Mm]64/ |
|||
bld/ |
|||
[Bb]uild/ |
|||
[Bb]in/ |
|||
[Oo]bj/ |
|||
[Ll]og/ |
|||
[Ll]ogs/ |
|||
.vs/ |
|||
|
|||
# NuGet Packages |
|||
*.nupkg |
|||
# NuGet Symbol Packages |
|||
*.snupkg |
|||
# The packages folder can be ignored because of Package Restore |
|||
**/[Pp]ackages/* |
|||
# except build/, which is used as an MSBuild target. |
|||
!**/[Pp]ackages/build/ |
|||
# Uncomment if necessary however generally it will be regenerated when needed |
|||
#!**/[Pp]ackages/repositories.config |
|||
# NuGet v3's project.json files produces more ignorable files |
|||
*.nuget.props |
|||
*.nuget.targets |
|||
|
|||
# Files built by Visual Studio |
|||
*_i.c |
|||
*_p.c |
|||
*_h.h |
|||
*.ilk |
|||
*.meta |
|||
*.obj |
|||
*.iobj |
|||
*.pch |
|||
*.pdb |
|||
*.ipdb |
|||
*.pgc |
|||
*.pgd |
|||
*.rsp |
|||
*.sbr |
|||
*.tlb |
|||
*.tli |
|||
*.tlh |
|||
*.tmp |
|||
*.tmp_proj |
|||
*_wpftmp.csproj |
|||
*.log |
|||
*.vspscc |
|||
*.vssscc |
|||
.builds |
|||
*.pidb |
|||
*.svclog |
|||
*.scc |
|||
*.user |
|||
*.pubxml.user |
|||
FakesAssemblies |
|||
|
|||
package-lock.json |
|||
@ -0,0 +1,37 @@ |
|||
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00 |
|||
# Visual Studio Version 17 |
|||
VisualStudioVersion = 17.3.32929.385 |
|||
MinimumVisualStudioVersion = 10.0.40219.1 |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MFR211", "MFR211\MFR211.csproj", "{E2355FDA-05E6-4F5C-B544-3AE7E1527F97}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MFR212", "MFR212\MFR212.csproj", "{388ABD3C-7D8A-47C2-B60F-5C2E40B7B3BD}" |
|||
EndProject |
|||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MFR213", "MFR213\MFR213.csproj", "{43900D04-E330-4EFF-990B-709374318002}" |
|||
EndProject |
|||
Global |
|||
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
|||
Debug|Any CPU = Debug|Any CPU |
|||
Release|Any CPU = Release|Any CPU |
|||
EndGlobalSection |
|||
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
|||
{E2355FDA-05E6-4F5C-B544-3AE7E1527F97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{E2355FDA-05E6-4F5C-B544-3AE7E1527F97}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{E2355FDA-05E6-4F5C-B544-3AE7E1527F97}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{E2355FDA-05E6-4F5C-B544-3AE7E1527F97}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{388ABD3C-7D8A-47C2-B60F-5C2E40B7B3BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{388ABD3C-7D8A-47C2-B60F-5C2E40B7B3BD}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{388ABD3C-7D8A-47C2-B60F-5C2E40B7B3BD}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{388ABD3C-7D8A-47C2-B60F-5C2E40B7B3BD}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{43900D04-E330-4EFF-990B-709374318002}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{43900D04-E330-4EFF-990B-709374318002}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{43900D04-E330-4EFF-990B-709374318002}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{43900D04-E330-4EFF-990B-709374318002}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
EndGlobalSection |
|||
GlobalSection(SolutionProperties) = preSolution |
|||
HideSolutionNode = FALSE |
|||
EndGlobalSection |
|||
GlobalSection(ExtensibilityGlobals) = postSolution |
|||
SolutionGuid = {537644CB-355C-4D29-BCAE-7C1177924702} |
|||
EndGlobalSection |
|||
EndGlobal |
|||
@ -0,0 +1,22 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<OutputType>Exe</OutputType> |
|||
<TargetFramework>net6.0</TargetFramework> |
|||
<ImplicitUsings>enable</ImplicitUsings> |
|||
<Nullable>enable</Nullable> |
|||
<BaseIntermediateOutputPath>..\Build\obj</BaseIntermediateOutputPath> |
|||
<BaseOutputPath>..\Build</BaseOutputPath> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<Compile Remove="obj\**" /> |
|||
<EmbeddedResource Remove="obj\**" /> |
|||
<None Remove="obj\**" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,299 @@ |
|||
using System.Text; |
|||
using System.Text.Json.Serialization; |
|||
using Newtonsoft.Json; |
|||
|
|||
namespace MFR211 |
|||
{ |
|||
internal class Program |
|||
{ |
|||
public class Message |
|||
{ |
|||
public string From; |
|||
public string To; |
|||
public string Content; |
|||
|
|||
public string AsString() |
|||
{ |
|||
return JsonConvert.SerializeObject(this); |
|||
} |
|||
} |
|||
|
|||
public class MessageDatabase |
|||
{ |
|||
private readonly string m_sFn; |
|||
|
|||
// private List<Message> MessageList = new List<Message>();
|
|||
/// <summary>Initializes a new instance of the <see cref="T:System.Object" /> class.</summary>
|
|||
public MessageDatabase(string sFn) |
|||
{ |
|||
m_sFn = sFn; |
|||
} |
|||
|
|||
#region low-level methods
|
|||
|
|||
public List<Message> LoadWhole() |
|||
{ |
|||
List<Message> arList = new List<Message>(); |
|||
using (Stream pStream = File.OpenRead(m_sFn)) { |
|||
while (pStream.Position < pStream.Length) { |
|||
byte[] btHeader = new byte[0] { }; |
|||
pStream.Read(btHeader, 0, 1); |
|||
byte[] btContent = new byte[btHeader[0]]; |
|||
pStream.Read(btContent, 0, btContent.Length); |
|||
string sContent = Encoding.UTF8.GetChars(btContent).ToString(); |
|||
Message message = JsonConvert.DeserializeObject<Message>(sContent); |
|||
arList.Add(message); |
|||
} |
|||
} |
|||
|
|||
return arList; |
|||
} |
|||
|
|||
public Message LoadByIndex(int iIndex) |
|||
{ |
|||
int ii = 0; |
|||
using (Stream pStream = File.OpenRead(m_sFn)) { |
|||
while (pStream.Position < pStream.Length) { |
|||
byte[] btHeader = new byte[0] { }; |
|||
pStream.Read(btHeader, 0, 1); |
|||
byte[] btContent = new byte[btHeader[0]]; |
|||
pStream.Read(btContent, 0, btContent.Length); |
|||
if (ii == iIndex) { |
|||
string sContent = Encoding.UTF8.GetChars(btContent).ToString(); |
|||
Message message = JsonConvert.DeserializeObject<Message>(sContent); |
|||
return message; |
|||
} |
|||
|
|||
ii++; |
|||
} |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
public void Save(List<Message> messageList) |
|||
{ |
|||
using (Stream pStream = File.OpenWrite(m_sFn)) { |
|||
StreamWriter pStreamWriter = new StreamWriter(pStream); |
|||
foreach (Message message in messageList) { |
|||
string sMsg = message.AsString(); |
|||
pStreamWriter.Write((char)sMsg.Length); |
|||
pStreamWriter.Write(sMsg); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public int GetCount() |
|||
{ |
|||
int ii = 0; |
|||
using (Stream pStream = File.OpenRead(m_sFn)) { |
|||
while (pStream.Position < pStream.Length) { |
|||
byte[] btHeader = new byte[0] { }; |
|||
pStream.Read(btHeader, 0, 1); |
|||
byte[] btContent = new byte[btHeader[0]]; |
|||
pStream.Read(btContent, 0, btContent.Length); |
|||
ii++; |
|||
} |
|||
} |
|||
|
|||
return ii; |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Map
|
|||
|
|||
/// <summary>
|
|||
/// 1 -> 1
|
|||
/// </summary>
|
|||
public IEnumerable<string> Map( |
|||
Func<Message, string> fnMap, |
|||
int iTop) |
|||
{ |
|||
List<string> arList = new List<string>(); |
|||
using (Stream pStream = File.OpenRead(m_sFn)) { |
|||
while (pStream.Position < pStream.Length) { |
|||
byte[] btHeader = new byte[0] { }; |
|||
pStream.Read(btHeader, 0, 1); |
|||
byte[] btContent = new byte[btHeader[0]]; |
|||
pStream.Read(btContent, 0, btContent.Length); |
|||
string sContent = Encoding.UTF8.GetChars(btContent).ToString(); |
|||
Message message = JsonConvert.DeserializeObject<Message>(sContent); |
|||
// -----------
|
|||
string sResult = fnMap(message); |
|||
arList.Add(sResult); |
|||
if (arList.Count >= iTop) break; |
|||
} |
|||
} |
|||
|
|||
return arList; |
|||
} |
|||
|
|||
|
|||
public string FnMap(Message arg) |
|||
{ |
|||
return $"{arg.From} / {arg.Content.Length}"; |
|||
} |
|||
|
|||
public string FnMap2(Message arg) |
|||
{ |
|||
return $"{arg.From}"; |
|||
} |
|||
|
|||
|
|||
#endregion
|
|||
|
|||
#region Filter
|
|||
|
|||
/// <summary>
|
|||
/// 1 -> (0-1)
|
|||
/// </summary>
|
|||
/// <param name="fnFilter"></param>
|
|||
/// <param name="iTopCount"></param>
|
|||
/// <returns></returns>
|
|||
public IEnumerable<Message> Filter( |
|||
Func<Message, bool> fnFilter, |
|||
int iTopCount) |
|||
{ |
|||
List<Message> arList = new List<Message>(); |
|||
using (Stream pStream = File.OpenRead(m_sFn)) { |
|||
while (pStream.Position < pStream.Length) { |
|||
byte[] btHeader = new byte[0] { }; |
|||
pStream.Read(btHeader, 0, 1); |
|||
byte[] btContent = new byte[btHeader[0]]; |
|||
pStream.Read(btContent, 0, btContent.Length); |
|||
string sContent = Encoding.UTF8.GetChars(btContent).ToString(); |
|||
Message message = JsonConvert.DeserializeObject<Message>(sContent); |
|||
// -----------
|
|||
bool bAdd = fnFilter(message); |
|||
if (bAdd) { |
|||
arList.Add(message); |
|||
} |
|||
|
|||
if (arList.Count >= iTopCount) break; |
|||
} |
|||
} |
|||
|
|||
return arList; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 1->1
|
|||
/// </summary>
|
|||
/// <param name="arg"></param>
|
|||
/// <returns></returns>
|
|||
public bool FnFilter(Message arg) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// by condition
|
|||
/// </summary>
|
|||
/// <param name="arg"></param>
|
|||
/// <returns></returns>
|
|||
public bool FnFilterSelf(Message arg) |
|||
{ |
|||
return (arg.From == arg.To); |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Reduce
|
|||
|
|||
public int Reduce( |
|||
Func<Message, int, int> fnReduce) |
|||
{ |
|||
int acc = 0; |
|||
using (Stream pStream = File.OpenRead(m_sFn)) { |
|||
while (pStream.Position < pStream.Length) { |
|||
byte[] btHeader = new byte[0] { }; |
|||
pStream.Read(btHeader, 0, 1); |
|||
byte[] btContent = new byte[btHeader[0]]; |
|||
pStream.Read(btContent, 0, btContent.Length); |
|||
string sContent = Encoding.UTF8.GetChars(btContent).ToString(); |
|||
Message message = JsonConvert.DeserializeObject<Message>(sContent); |
|||
// -----------
|
|||
acc = fnReduce(message, acc); |
|||
if (acc < 0) { |
|||
return -acc; |
|||
} |
|||
} |
|||
} |
|||
|
|||
return acc; |
|||
} |
|||
|
|||
private Dictionary<string, int> arCounter = new Dictionary<string, int>() { |
|||
{ "0", 0 }, |
|||
{ "1", 0 }, |
|||
{ "2", 0 }, |
|||
{ "3", 0 }, |
|||
{ "4", 0 }, |
|||
}; |
|||
|
|||
/// <summary>
|
|||
/// Подсчет сообщений от заданных отправителей,
|
|||
/// но при нахождении больше
|
|||
/// трех от любого из них прекращает счет
|
|||
/// </summary>
|
|||
/// <param name="arg1"></param>
|
|||
/// <param name="iAcc"></param>
|
|||
/// <returns></returns>
|
|||
public int FnReduce( |
|||
Message arg1, int iAcc) |
|||
{ |
|||
if (arCounter.ContainsKey(arg1.From)) { |
|||
arCounter[arg1.From]++; |
|||
iAcc++; |
|||
if (arCounter[arg1.From] > 3) { |
|||
return -iAcc; |
|||
} |
|||
} |
|||
return iAcc; |
|||
} |
|||
|
|||
|
|||
public int FnReduce2( |
|||
Message arg1, int iAcc) |
|||
{ |
|||
return iAcc + arg1.Content.Length; |
|||
} |
|||
|
|||
#endregion
|
|||
} |
|||
|
|||
static void Main(string[] args) |
|||
{ |
|||
const string sFn = "1.txt"; |
|||
MessageDatabase md = new MessageDatabase(sFn); |
|||
// 1. Whole load
|
|||
//List<Message> arList = md.LoadWhole(sFn);
|
|||
// 2. load one by one
|
|||
int iiCount = md.GetCount(); |
|||
for (int ii = 0; ii < iiCount; ii++) { |
|||
Message msg = md.LoadByIndex(ii); |
|||
Console.WriteLine($"[loaded msg] {msg.From}"); |
|||
} |
|||
// 3. Map - Filter - Reduce
|
|||
// 3.1. MAP
|
|||
IEnumerable<string> ar = |
|||
md.Map(md.FnMap, 100); |
|||
foreach (string str in ar) { |
|||
Console.WriteLine($"[map msg] {str}"); |
|||
} |
|||
|
|||
// 3.2. FILTER
|
|||
IEnumerable<Message> ar2 = |
|||
md.Filter(md.FnFilterSelf, 100); |
|||
foreach (Message msg in ar2) { |
|||
Console.WriteLine($"[filter msg] {msg.Content.Length}"); |
|||
} |
|||
|
|||
// 3.3. REDUCE
|
|||
int iCnt = |
|||
md.Reduce(md.FnReduce); |
|||
Console.WriteLine($"[reducemsg] {iCnt}"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<OutputType>Exe</OutputType> |
|||
<TargetFramework>net6.0</TargetFramework> |
|||
<ImplicitUsings>enable</ImplicitUsings> |
|||
<Nullable>enable</Nullable> |
|||
<BaseIntermediateOutputPath>..\Build\obj</BaseIntermediateOutputPath> |
|||
<BaseOutputPath>..\Build</BaseOutputPath> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<Compile Remove="obj\**" /> |
|||
<EmbeddedResource Remove="obj\**" /> |
|||
<None Remove="obj\**" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,316 @@ |
|||
using System.Diagnostics.Metrics; |
|||
using System.Diagnostics.Tracing; |
|||
using System.Reflection.Metadata; |
|||
using System.Security.Cryptography.X509Certificates; |
|||
using System.Text; |
|||
using Newtonsoft.Json; |
|||
|
|||
namespace MFR212 |
|||
{ |
|||
public class Event |
|||
{ |
|||
public DateTime EventDate; |
|||
public string Message; |
|||
public int Type; |
|||
} |
|||
|
|||
|
|||
// 1. Данных много: они не умещаются в память
|
|||
// 2. Возможность распараллеливания обработки
|
|||
// 3.
|
|||
public class EventManager |
|||
{ |
|||
private readonly string m_sFilename; |
|||
|
|||
public EventManager(string sFilename) |
|||
{ |
|||
m_sFilename = sFilename; |
|||
} |
|||
|
|||
public void SaveEvents(List<Event> arEvents) |
|||
{ |
|||
using (Stream pOutputStream = |
|||
File.OpenWrite(m_sFilename)) { |
|||
using (StreamWriter pSw = |
|||
new StreamWriter(pOutputStream, Encoding.UTF8)) { |
|||
foreach (Event pEvent in arEvents) { |
|||
string sEvent = JsonConvert.SerializeObject(pEvent); |
|||
pSw.Write((byte)sEvent.Length); |
|||
pSw.Write(sEvent); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
public List<Event> LoadEvents() |
|||
{ |
|||
List<Event> ar = new List<Event>(); |
|||
using (Stream pStream = |
|||
File.OpenRead(m_sFilename)) { |
|||
while (pStream.Length > pStream.Position) { |
|||
byte[] btHeader = new byte[1]; |
|||
pStream.Read(btHeader, 0, 1); |
|||
|
|||
byte[] btContent = new byte[btHeader[0]]; |
|||
pStream.Read(btContent, 0, btContent.Length); |
|||
string sContent = Encoding.UTF8.GetString(btContent); |
|||
Event pEvent = JsonConvert.DeserializeObject<Event>(sContent); |
|||
ar.Add(pEvent); |
|||
} |
|||
} |
|||
|
|||
return ar; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 1 -> 1 (конвертация)
|
|||
/// </summary>
|
|||
/// <param name="fnMap"></param>
|
|||
/// <param name="iTopCount"></param>
|
|||
/// <returns></returns>
|
|||
public List<string> Map( |
|||
Func<Event, string> fnMap, |
|||
int iTopCount) |
|||
{ |
|||
List<string> ar = new List<string>(); |
|||
using (Stream pStream = |
|||
File.OpenRead(m_sFilename)) { |
|||
while (pStream.Length > pStream.Position) { |
|||
byte[] btHeader = new byte[1]; |
|||
pStream.Read(btHeader, 0, 1); |
|||
|
|||
byte[] btContent = new byte[btHeader[0]]; |
|||
pStream.Read(btContent, 0, btContent.Length); |
|||
string sContent = Encoding.UTF8.GetString(btContent); |
|||
Event pEvent = JsonConvert.DeserializeObject<Event>(sContent); |
|||
ar.Add(fnMap(pEvent)); |
|||
if (ar.Count >= iTopCount) break; |
|||
} |
|||
} |
|||
|
|||
return ar; |
|||
|
|||
|
|||
} |
|||
|
|||
public string fnMap(Event arg) |
|||
{ |
|||
return arg.Message; |
|||
} |
|||
|
|||
public string fnMap2(Event arg) |
|||
{ |
|||
return arg.EventDate.ToShortTimeString(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// * -> мало (фильтрация)
|
|||
/// </summary>
|
|||
/// <param name="fnFilter"></param>
|
|||
/// <param name="iTopCount"></param>
|
|||
/// <returns></returns>
|
|||
public List<Event> Filter( |
|||
Func<Event, bool> fnFilter, |
|||
int iTopCount) |
|||
{ |
|||
|
|||
List<Event> ar = new List<Event>(); |
|||
using (Stream pStream = |
|||
File.OpenRead(m_sFilename)) { |
|||
while (pStream.Length > pStream.Position) { |
|||
byte[] btHeader = new byte[1]; |
|||
pStream.Read(btHeader, 0, 1); |
|||
|
|||
byte[] btContent = new byte[btHeader[0]]; |
|||
pStream.Read(btContent, 0, btContent.Length); |
|||
string sContent = Encoding.UTF8.GetString(btContent); |
|||
Event pEvent = JsonConvert.DeserializeObject<Event>(sContent); |
|||
if (fnFilter(pEvent)) { |
|||
ar |
|||
.Add(pEvent); |
|||
if (ar.Count >= iTopCount) break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
return ar; |
|||
} |
|||
|
|||
public bool fnFilter(Event arg) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
public bool fnFilterToday(Event arg) |
|||
{ |
|||
return (arg.EventDate >= DateTime.Today); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// * -> 1 (свод)
|
|||
/// </summary>
|
|||
/// <param name="fnReduce"></param>
|
|||
/// <returns></returns>
|
|||
public int Reduce( |
|||
Func<Event, int, int> fnReduce) |
|||
{ |
|||
int iCounter = 0; |
|||
using (Stream pStream = |
|||
File.OpenRead(m_sFilename)) { |
|||
while (pStream.Length > pStream.Position) { |
|||
byte[] btHeader = new byte[1]; |
|||
pStream.Read(btHeader, 0, 1); |
|||
|
|||
byte[] btContent = new byte[btHeader[0]]; |
|||
pStream.Read(btContent, 0, btContent.Length); |
|||
string sContent = Encoding.UTF8.GetString(btContent); |
|||
Event pEvent = JsonConvert.DeserializeObject<Event>(sContent); |
|||
|
|||
iCounter = fnReduce(pEvent, iCounter); |
|||
} |
|||
} |
|||
|
|||
return iCounter; |
|||
} |
|||
|
|||
|
|||
/// <summary>
|
|||
/// * -> 1 (свод)
|
|||
/// </summary>
|
|||
/// <param name="fnReduce"></param>
|
|||
/// <returns></returns>
|
|||
public int ReduceWithBreak( |
|||
Func<Event, int, int> fnReduce) |
|||
{ |
|||
int iCounter = 0; |
|||
using (Stream pStream = |
|||
File.OpenRead(m_sFilename)) { |
|||
while (pStream.Length > pStream.Position) { |
|||
byte[] btHeader = new byte[1]; |
|||
pStream.Read(btHeader, 0, 1); |
|||
|
|||
byte[] btContent = new byte[btHeader[0]]; |
|||
pStream.Read(btContent, 0, btContent.Length); |
|||
string sContent = Encoding.UTF8.GetString(btContent); |
|||
Event pEvent = JsonConvert.DeserializeObject<Event>(sContent); |
|||
|
|||
iCounter = fnReduce(pEvent, iCounter); |
|||
if (iCounter < 0) return -iCounter; |
|||
} |
|||
} |
|||
|
|||
return iCounter; |
|||
} |
|||
|
|||
|
|||
public int fnReduceErrorsToday( |
|||
Event pObject, |
|||
int iAccumulator) |
|||
{ |
|||
if (pObject.Type == 2 |
|||
&& pObject.EventDate > DateTime.Today |
|||
&& pObject.EventDate < DateTime.Today.AddDays(+1)) { |
|||
return iAccumulator + 1; |
|||
} |
|||
|
|||
return iAccumulator; |
|||
} |
|||
|
|||
|
|||
public int fnReduceErrorsTodayMax( |
|||
Event pObject, |
|||
int iAccumulator, |
|||
int iMax) |
|||
{ |
|||
if (pObject.Type == 2 |
|||
&& pObject.EventDate > DateTime.Today |
|||
&& pObject.EventDate < DateTime.Today.AddDays(+1)) { |
|||
|
|||
if (iAccumulator >= iMax - 1) { |
|||
return -(iAccumulator + 1); |
|||
} |
|||
|
|||
return iAccumulator + 1; |
|||
} |
|||
|
|||
return iAccumulator; |
|||
} |
|||
|
|||
private Dictionary<int, int> arCount = new Dictionary<int, int>() { |
|||
{ 0, 0 }, |
|||
{ 1, 0 }, |
|||
{ 2, 0 }, |
|||
}; |
|||
|
|||
|
|||
public int fnReduceBreak( |
|||
Event pObject, |
|||
int iAccumulator) |
|||
{ |
|||
if (arCount.ContainsKey(pObject.Type)) { |
|||
arCount[pObject.Type]++; |
|||
if (arCount[pObject.Type] > 3) { |
|||
return -pObject.Type; |
|||
} |
|||
} |
|||
|
|||
return iAccumulator; |
|||
} |
|||
|
|||
|
|||
public int fnReduce( |
|||
Event pObject, |
|||
int iAccumulator, |
|||
int iMax) |
|||
{ |
|||
if (pObject.Type == 2 |
|||
&& pObject.EventDate > DateTime.Today |
|||
&& pObject.EventDate < DateTime.Today.AddDays(+1)) { |
|||
|
|||
if (iAccumulator >= iMax - 1) { |
|||
return -(iAccumulator + 1); |
|||
} |
|||
|
|||
return iAccumulator + 1; |
|||
} |
|||
|
|||
return iAccumulator; |
|||
} |
|||
|
|||
|
|||
} |
|||
|
|||
|
|||
internal class Program |
|||
{ |
|||
static void Main(string[] args) |
|||
{ |
|||
// 1. Working with whole content in memory
|
|||
EventManager ev = new EventManager("1.txt"); |
|||
List<Event> ar = ev.LoadEvents(); |
|||
foreach (Event pEvent in ar) { |
|||
Console.WriteLine($"{pEvent.Message}"); |
|||
} |
|||
// 2. Map, Filter, Reduce
|
|||
// 2.1. MAP
|
|||
List<string> ar2 = ev.Map(ev.fnMap, 100); |
|||
foreach (string str in ar2) { |
|||
Console.WriteLine($"{str}, "); |
|||
} |
|||
|
|||
// 2.2. FILTER
|
|||
List<Event> ar3 = ev.Filter( |
|||
ev.fnFilterToday, 100); |
|||
foreach (Event pEvent in ar3) { |
|||
Console.WriteLine($"{pEvent.Message}, "); |
|||
} |
|||
|
|||
// 2.3. REDUCE
|
|||
int iCount = ev.Reduce(ev.fnReduceErrorsToday); |
|||
Console.WriteLine($"{iCount}"); |
|||
int iCount2 = ev.ReduceWithBreak( |
|||
ev.fnReduceBreak); |
|||
Console.WriteLine($"{iCount2}"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,129 @@ |
|||
using System.Text; |
|||
|
|||
namespace ConsoleApp1 |
|||
{ |
|||
|
|||
#region CRecordCollection
|
|||
|
|||
public class CRecordCollection |
|||
{ |
|||
private List<CRecord> RecordList; |
|||
|
|||
public void Serialize(Stream pOutStream) |
|||
{ |
|||
foreach (CRecord pRecord in RecordList) { |
|||
byte[] btRecord = pRecord.GetBytes(); |
|||
pOutStream.Write(btRecord); |
|||
} |
|||
} |
|||
|
|||
public void Deserialize(Stream pInStream) |
|||
{ |
|||
pInStream.Seek(0, SeekOrigin.Begin); |
|||
while (pInStream.Position < pInStream.Length) { |
|||
byte[] btHeader = new byte[1]; |
|||
pInStream.Read(btHeader, 0, 1); |
|||
byte[] btContent = new byte[btHeader[0]]; |
|||
pInStream.Read(btContent, 0, btContent.Length); |
|||
string sName = Encoding.UTF8.GetChars(btContent).ToString(); |
|||
RecordList.Add(new CRecord() { Name = sName }); |
|||
} |
|||
} |
|||
|
|||
public CRecord Deserialize2(Stream pInStream, int iRecordId) |
|||
{ |
|||
pInStream.Seek(0, SeekOrigin.Begin); |
|||
int ii = 0; |
|||
while (pInStream.Position < pInStream.Length) { |
|||
byte[] btHeader = new byte[1]; |
|||
pInStream.Read(btHeader, 0, 1); |
|||
byte[] btContent = new byte[btHeader[0]]; |
|||
pInStream.Read(btContent, 0, btContent.Length); |
|||
string sName = Encoding.UTF8.GetChars(btContent).ToString(); |
|||
if (ii == iRecordId) return new CRecord() { Name = sName }; |
|||
ii++; |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
public int DeserializeCount(Stream pInStream) |
|||
{ |
|||
pInStream.Seek(0, SeekOrigin.Begin); |
|||
int ii = 0; |
|||
while (pInStream.Position < pInStream.Length) { |
|||
byte[] btHeader = new byte[1]; |
|||
pInStream.Read(btHeader, 0, 1); |
|||
byte[] btContent = new byte[btHeader[0]]; |
|||
pInStream.Read(btContent, 0, btContent.Length); |
|||
ii++; |
|||
} |
|||
|
|||
return ii; |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Record
|
|||
|
|||
public class CRecord |
|||
{ |
|||
public string Name; |
|||
|
|||
public byte[] GetBytes() |
|||
{ |
|||
byte[] btInnerContent = Encoding.UTF8.GetBytes(Name); |
|||
byte[] btHeader = new byte[] { (byte)btInnerContent.Length }; |
|||
byte[] btOut = new byte[btInnerContent.Length + btHeader.Length]; |
|||
for (int ii = 0; ii < btHeader.Length; ii++) { |
|||
btOut[ii] = btHeader[ii]; |
|||
} |
|||
|
|||
int iShift = btHeader.Length; |
|||
for (int ii = 0; ii < btInnerContent.Length; ii++) { |
|||
btOut[ii + iShift] = btInnerContent[ii]; |
|||
} |
|||
|
|||
return btOut; |
|||
} |
|||
|
|||
|
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
#endregion
|
|||
|
|||
#region CHardWorkProcessor
|
|||
|
|||
public class CHardWorkProcessor |
|||
{ |
|||
#region public methods
|
|||
|
|||
public void StepThrough() |
|||
{ |
|||
using (Stream pIn = File.OpenRead("1.txt")) { |
|||
CRecordCollection pR = new CRecordCollection(); |
|||
int iCount = pR.DeserializeCount(pIn); |
|||
for (int ii = 0; ii < iCount; ii++) { |
|||
CRecord pRecord = pR.Deserialize2(pIn, ii); |
|||
Console.WriteLine(pRecord.Name); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public void GetWhole() |
|||
{ |
|||
using (Stream pIn = File.OpenRead("1.txt")) { |
|||
CRecordCollection pR = new CRecordCollection(); |
|||
pR.Deserialize(pIn); |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
} |
|||
|
|||
#endregion
|
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<OutputType>Exe</OutputType> |
|||
<TargetFramework>net6.0</TargetFramework> |
|||
<ImplicitUsings>enable</ImplicitUsings> |
|||
<Nullable>enable</Nullable> |
|||
<BaseIntermediateOutputPath>..\Build\obj\</BaseIntermediateOutputPath> |
|||
<BaseOutputPath>..\Build</BaseOutputPath> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<Compile Remove="obj\**" /> |
|||
<EmbeddedResource Remove="obj\**" /> |
|||
<None Remove="obj\**" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,111 @@ |
|||
|
|||
namespace ConsoleApp1 |
|||
{ |
|||
public class CMFRProcessor |
|||
{ |
|||
#region Map-Filter-Reduce
|
|||
public void Filter( |
|||
Stream pInStream, |
|||
Stream pOutStream, |
|||
Func<byte, bool> fnFilter) |
|||
{ |
|||
pInStream.Seek(0, SeekOrigin.Begin); |
|||
|
|||
byte[] bt = new byte[1]; |
|||
while (pInStream.Position < pInStream.Length) { |
|||
pInStream.Read(bt, 0, 1); |
|||
bool bIsNeeded = fnFilter(bt[0]); |
|||
if (bIsNeeded) { |
|||
pOutStream.Write(bt, 0, 1); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
public void Map( |
|||
Stream pInStream, |
|||
Stream pOutStream, |
|||
|
|||
Func<byte, byte> fnMap) |
|||
{ |
|||
|
|||
pInStream.Seek(0, SeekOrigin.Begin); |
|||
|
|||
byte[] bt = new byte[1]; |
|||
while (pInStream.Position < pInStream.Length) { |
|||
pInStream.Read(bt, 0, 1); |
|||
byte[] btOut = new[] { fnMap(bt[0]) }; |
|||
pOutStream.Write(btOut, 0, 1); |
|||
} |
|||
} |
|||
|
|||
public int Reduce( |
|||
Stream pStream, |
|||
Func<int, byte, int> fnReduce) |
|||
{ |
|||
pStream.Seek(0, SeekOrigin.Begin); |
|||
|
|||
byte[] bt = new byte[1]; |
|||
int ii = 0; |
|||
while (pStream.Position < pStream.Length) { |
|||
pStream.Read(bt, 0, 1); |
|||
ii = fnReduce(ii, bt[0]); |
|||
if (ii < 0) return -ii; |
|||
} |
|||
|
|||
return ii; |
|||
} |
|||
|
|||
|
|||
#endregion
|
|||
|
|||
#region delegates "implementation"
|
|||
|
|||
private Dictionary<char, int> ar = |
|||
new Dictionary<char, int>() { |
|||
{ '0', 0 }, |
|||
{ '1', 0 }, |
|||
{ '2', 0 }, |
|||
{ '3', 0 }, |
|||
}; |
|||
|
|||
|
|||
public int FnReduceDictionary(int iCounter, byte btValue) |
|||
{ |
|||
char ch = (char)btValue; |
|||
if (ar.ContainsKey(ch)) { |
|||
ar[ch]++; |
|||
if (ar[ch] > 3) { |
|||
return -btValue; |
|||
} |
|||
} |
|||
return iCounter; |
|||
} |
|||
|
|||
|
|||
public int FnReduce(int iCounter, byte btValue) |
|||
{ |
|||
if (btValue == '0') { |
|||
iCounter++; |
|||
} |
|||
|
|||
if (iCounter >= 3) { |
|||
return -iCounter; |
|||
} |
|||
return iCounter; |
|||
} |
|||
|
|||
public bool FnFilter(byte arg) |
|||
{ |
|||
return arg == '0'; |
|||
} |
|||
|
|||
public byte FnMap(byte arg) |
|||
{ |
|||
return arg; |
|||
} |
|||
|
|||
|
|||
#endregion
|
|||
} |
|||
} |
|||
@ -0,0 +1,72 @@ |
|||
using System.IO.Pipes; |
|||
using System.Reflection.Metadata; |
|||
using System.Text; |
|||
|
|||
namespace ConsoleApp1 |
|||
{ |
|||
|
|||
public class Program |
|||
{ |
|||
public static void Main() |
|||
{ |
|||
//// hard work demo
|
|||
//CHardWorkProcessor pProc = new CHardWorkProcessor();
|
|||
//pProc.GetWhole();
|
|||
//pProc.StepThrough();
|
|||
|
|||
// map - filter - reduce demo
|
|||
h_StepMap(); |
|||
h_StepFilter(); |
|||
h_StepReduce(); |
|||
|
|||
|
|||
} |
|||
|
|||
#region demo methods
|
|||
|
|||
/// <summary>
|
|||
/// 1 -> (acc++)
|
|||
/// </summary>
|
|||
private static void h_StepReduce() |
|||
{ |
|||
using (Stream pIn = File.OpenRead("1.txt")) { |
|||
CMFRProcessor pProc = new CMFRProcessor(); |
|||
int iCount = pProc.Reduce(pIn, pProc.FnReduceDictionary); |
|||
Console.WriteLine($"{iCount}"); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 1 -> (0..1)
|
|||
/// </summary>
|
|||
private static void h_StepFilter() |
|||
{ |
|||
using (Stream pIn = File.OpenRead("1.txt")) { |
|||
using (Stream poUT = File.OpenWrite("2.txt")) { |
|||
CMFRProcessor pProc = new CMFRProcessor(); |
|||
pProc.Filter(pIn, poUT, pProc.FnFilter); |
|||
Console.WriteLine($"Done"); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 1 -> 1
|
|||
/// </summary>
|
|||
private static void h_StepMap() |
|||
{ |
|||
using (Stream pIn = File.OpenRead("1.txt")) { |
|||
using (Stream poUT = File.OpenWrite("2.txt")) { |
|||
CMFRProcessor pProc = new CMFRProcessor(); |
|||
pProc.Map(pIn, poUT, pProc.FnMap); |
|||
Console.WriteLine($"Done"); |
|||
} |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
|
|||
} |
|||
|
|||
} |
|||
Loading…
Reference in new issue