diff --git a/MFR/.gitignore b/MFR/.gitignore
new file mode 100644
index 0000000..08cc0a0
--- /dev/null
+++ b/MFR/.gitignore
@@ -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
\ No newline at end of file
diff --git a/MFR/MFR.sln b/MFR/MFR.sln
new file mode 100644
index 0000000..27d7593
--- /dev/null
+++ b/MFR/MFR.sln
@@ -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
diff --git a/MFR/MFR211/MFR211.csproj b/MFR/MFR211/MFR211.csproj
new file mode 100644
index 0000000..b42d2f8
--- /dev/null
+++ b/MFR/MFR211/MFR211.csproj
@@ -0,0 +1,22 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+ ..\Build\obj
+ ..\Build
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MFR/MFR211/Program.cs b/MFR/MFR211/Program.cs
new file mode 100644
index 0000000..9f6c4ef
--- /dev/null
+++ b/MFR/MFR211/Program.cs
@@ -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 MessageList = new List();
+ /// Initializes a new instance of the class.
+ public MessageDatabase(string sFn)
+ {
+ m_sFn = sFn;
+ }
+
+ #region low-level methods
+
+ public List LoadWhole()
+ {
+ List arList = new List();
+ 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(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(sContent);
+ return message;
+ }
+
+ ii++;
+ }
+ }
+
+ return null;
+ }
+
+ public void Save(List 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
+
+ ///
+ /// 1 -> 1
+ ///
+ public IEnumerable Map(
+ Func fnMap,
+ int iTop)
+ {
+ List arList = new List();
+ 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(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
+
+ ///
+ /// 1 -> (0-1)
+ ///
+ ///
+ ///
+ ///
+ public IEnumerable Filter(
+ Func fnFilter,
+ int iTopCount)
+ {
+ List arList = new List();
+ 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(sContent);
+ // -----------
+ bool bAdd = fnFilter(message);
+ if (bAdd) {
+ arList.Add(message);
+ }
+
+ if (arList.Count >= iTopCount) break;
+ }
+ }
+
+ return arList;
+ }
+
+ ///
+ /// 1->1
+ ///
+ ///
+ ///
+ public bool FnFilter(Message arg)
+ {
+ return true;
+ }
+
+ ///
+ /// by condition
+ ///
+ ///
+ ///
+ public bool FnFilterSelf(Message arg)
+ {
+ return (arg.From == arg.To);
+ }
+
+ #endregion
+
+ #region Reduce
+
+ public int Reduce(
+ Func 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(sContent);
+ // -----------
+ acc = fnReduce(message, acc);
+ if (acc < 0) {
+ return -acc;
+ }
+ }
+ }
+
+ return acc;
+ }
+
+ private Dictionary arCounter = new Dictionary() {
+ { "0", 0 },
+ { "1", 0 },
+ { "2", 0 },
+ { "3", 0 },
+ { "4", 0 },
+ };
+
+ ///
+ /// Подсчет сообщений от заданных отправителей,
+ /// но при нахождении больше
+ /// трех от любого из них прекращает счет
+ ///
+ ///
+ ///
+ ///
+ 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 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 ar =
+ md.Map(md.FnMap, 100);
+ foreach (string str in ar) {
+ Console.WriteLine($"[map msg] {str}");
+ }
+
+ // 3.2. FILTER
+ IEnumerable 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}");
+ }
+ }
+}
\ No newline at end of file
diff --git a/MFR/MFR212/MFR212.csproj b/MFR/MFR212/MFR212.csproj
new file mode 100644
index 0000000..b42d2f8
--- /dev/null
+++ b/MFR/MFR212/MFR212.csproj
@@ -0,0 +1,22 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+ ..\Build\obj
+ ..\Build
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MFR/MFR212/Program.cs b/MFR/MFR212/Program.cs
new file mode 100644
index 0000000..a9541da
--- /dev/null
+++ b/MFR/MFR212/Program.cs
@@ -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 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 LoadEvents()
+ {
+ List ar = new List();
+ 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(sContent);
+ ar.Add(pEvent);
+ }
+ }
+
+ return ar;
+ }
+
+ ///
+ /// 1 -> 1 (конвертация)
+ ///
+ ///
+ ///
+ ///
+ public List Map(
+ Func fnMap,
+ int iTopCount)
+ {
+ List ar = new List();
+ 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(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();
+ }
+
+ ///
+ /// * -> мало (фильтрация)
+ ///
+ ///
+ ///
+ ///
+ public List Filter(
+ Func fnFilter,
+ int iTopCount)
+ {
+
+ List ar = new List();
+ 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(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);
+ }
+
+ ///
+ /// * -> 1 (свод)
+ ///
+ ///
+ ///
+ public int Reduce(
+ Func 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(sContent);
+
+ iCounter = fnReduce(pEvent, iCounter);
+ }
+ }
+
+ return iCounter;
+ }
+
+
+ ///
+ /// * -> 1 (свод)
+ ///
+ ///
+ ///
+ public int ReduceWithBreak(
+ Func 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(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 arCount = new Dictionary() {
+ { 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 ar = ev.LoadEvents();
+ foreach (Event pEvent in ar) {
+ Console.WriteLine($"{pEvent.Message}");
+ }
+ // 2. Map, Filter, Reduce
+ // 2.1. MAP
+ List ar2 = ev.Map(ev.fnMap, 100);
+ foreach (string str in ar2) {
+ Console.WriteLine($"{str}, ");
+ }
+
+ // 2.2. FILTER
+ List 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}");
+ }
+ }
+}
\ No newline at end of file
diff --git a/MFR/MFR213/HardWorkProcessor.cs b/MFR/MFR213/HardWorkProcessor.cs
new file mode 100644
index 0000000..e445535
--- /dev/null
+++ b/MFR/MFR213/HardWorkProcessor.cs
@@ -0,0 +1,129 @@
+using System.Text;
+
+namespace ConsoleApp1
+{
+
+ #region CRecordCollection
+
+ public class CRecordCollection
+ {
+ private List 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
+}
\ No newline at end of file
diff --git a/MFR/MFR213/MFR213.csproj b/MFR/MFR213/MFR213.csproj
new file mode 100644
index 0000000..5713d88
--- /dev/null
+++ b/MFR/MFR213/MFR213.csproj
@@ -0,0 +1,18 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+ ..\Build\obj\
+ ..\Build
+
+
+
+
+
+
+
+
+
diff --git a/MFR/MFR213/MFRProcessor.cs b/MFR/MFR213/MFRProcessor.cs
new file mode 100644
index 0000000..d92b1e7
--- /dev/null
+++ b/MFR/MFR213/MFRProcessor.cs
@@ -0,0 +1,111 @@
+
+namespace ConsoleApp1
+{
+ public class CMFRProcessor
+ {
+ #region Map-Filter-Reduce
+ public void Filter(
+ Stream pInStream,
+ Stream pOutStream,
+ Func 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 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 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 ar =
+ new Dictionary() {
+ { '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
+ }
+}
\ No newline at end of file
diff --git a/MFR/MFR213/Program.cs b/MFR/MFR213/Program.cs
new file mode 100644
index 0000000..2844d09
--- /dev/null
+++ b/MFR/MFR213/Program.cs
@@ -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
+
+ ///
+ /// 1 -> (acc++)
+ ///
+ 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}");
+ }
+ }
+
+ ///
+ /// 1 -> (0..1)
+ ///
+ 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");
+ }
+ }
+ }
+
+ ///
+ /// 1 -> 1
+ ///
+ 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
+
+
+ }
+
+}
\ No newline at end of file