forked from TwinkmrMask/BookShop
-
Notifications
You must be signed in to change notification settings - Fork 0
/
PlatformDataBase.cs
130 lines (114 loc) · 7.43 KB
/
PlatformDataBase.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
using Platform.Disposables;
using Platform.Collections.Stacks;
using Platform.Converters;
using Platform.Memory;
using Platform.Data;
using Platform.Data.Numbers.Raw;
using Platform.Data.Doublets;
using Platform.Data.Doublets.Decorators;
using Platform.Data.Doublets.Unicode;
using Platform.Data.Doublets.Sequences.Walkers;
using Platform.Data.Doublets.Sequences.Converters;
using Platform.Data.Doublets.CriterionMatchers;
using Platform.Data.Doublets.Memory.Split.Specific;
using TLinkAddress = System.UInt32;
using System.Windows;
using System.Collections.Generic;
namespace task_14._04
{
//Part of the code, along with comments, is taken from https://github.com/linksplatform/Comparisons.SQLiteVSDoublets/commit/289cf361c82ab605b9ba0d1621496b3401e432f7
public class PlatformDataBase : DisposableBase, IDefaultSettings
{
string indexFileName;
string dataFileName;
private readonly TLinkAddress _meaningRoot;
private readonly TLinkAddress _unicodeSymbolMarker;
private readonly TLinkAddress _unicodeSequenceMarker;
private uint _bookMarker;
private readonly RawNumberToAddressConverter<TLinkAddress> _numberToAddressConverter;
private readonly AddressToRawNumberConverter<TLinkAddress> _addressToNumberConverter;
private readonly IConverter<string, TLinkAddress> _stringToUnicodeSequenceConverter;
private readonly IConverter<TLinkAddress, string> _unicodeSequenceToStringConverter;
private readonly ILinks<TLinkAddress> _disposableLinks;
private readonly ILinks<TLinkAddress> links;
public PlatformDataBase(string indexFileName, string dataFileName)
{
this.indexFileName = indexFileName;
this.dataFileName = dataFileName;
var dataMemory = new FileMappedResizableDirectMemory(this.dataFileName);
var indexMemory = new FileMappedResizableDirectMemory(this.indexFileName);
var linksConstants = new LinksConstants<TLinkAddress>(enableExternalReferencesSupport: true);
// Init the links storage
this._disposableLinks = new UInt32SplitMemoryLinks(dataMemory, indexMemory, UInt32SplitMemoryLinks.DefaultLinksSizeStep, linksConstants); // Low-level logic
this.links = new UInt32Links(_disposableLinks); // Main logic in the combined decorator
// Set up constant links (markers, aka mapped links)
TLinkAddress currentMappingLinkIndex = 1;
this._meaningRoot = GerOrCreateMeaningRoot(currentMappingLinkIndex++);
this._unicodeSymbolMarker = GetOrCreateNextMapping(currentMappingLinkIndex++);
this._unicodeSequenceMarker = GetOrCreateNextMapping(currentMappingLinkIndex++);
this._bookMarker = GetOrCreateNextMapping(currentMappingLinkIndex++);
// Create converters that are able to convert link's address (UInt64 value) to a raw number represented with another UInt64 value and back
this._numberToAddressConverter = new RawNumberToAddressConverter<TLinkAddress>();
this._addressToNumberConverter = new AddressToRawNumberConverter<TLinkAddress>();
// Create converters that are able to convert string to unicode sequence stored as link and back
var balancedVariantConverter = new BalancedVariantConverter<TLinkAddress>(links);
var unicodeSymbolCriterionMatcher = new TargetMatcher<TLinkAddress>(links, _unicodeSymbolMarker);
var unicodeSequenceCriterionMatcher = new TargetMatcher<TLinkAddress>(links, _unicodeSequenceMarker);
var charToUnicodeSymbolConverter = new CharToUnicodeSymbolConverter<TLinkAddress>(links, _addressToNumberConverter, _unicodeSymbolMarker);
var unicodeSymbolToCharConverter = new UnicodeSymbolToCharConverter<TLinkAddress>(links, _numberToAddressConverter, unicodeSymbolCriterionMatcher);
var sequenceWalker = new RightSequenceWalker<TLinkAddress>(links, new DefaultStack<TLinkAddress>(), unicodeSymbolCriterionMatcher.IsMatched);
this._stringToUnicodeSequenceConverter = new CachingConverterDecorator<string, TLinkAddress>(new StringToUnicodeSequenceConverter<TLinkAddress>(links, charToUnicodeSymbolConverter, balancedVariantConverter, _unicodeSequenceMarker));
this._unicodeSequenceToStringConverter = new CachingConverterDecorator<TLinkAddress, string>(new UnicodeSequenceToStringConverter<TLinkAddress>(links, unicodeSequenceCriterionMatcher, sequenceWalker, unicodeSymbolToCharConverter));
}
private TLinkAddress GerOrCreateMeaningRoot(TLinkAddress meaningRootIndex) => links.Exists(meaningRootIndex) ? meaningRootIndex : links.CreatePoint();
private TLinkAddress GetOrCreateNextMapping(TLinkAddress currentMappingIndex) => links.Exists(currentMappingIndex) ? currentMappingIndex : links.CreateAndUpdate(_meaningRoot, links.Constants.Itself);
public string ConvertToString(TLinkAddress sequence) => _unicodeSequenceToStringConverter.Convert(sequence);
public TLinkAddress ConvertToSequence(string @string) => _stringToUnicodeSequenceConverter.Convert(@string);
public void Delete(TLinkAddress link) => links.Delete(link);
public void AddBooks(string id, string author, string title, string year) =>
this.links.GetOrCreate(_bookMarker,
this.links.GetOrCreate(
this.links.GetOrCreate(ConvertToSequence(id), ConvertToSequence(author)),
this.links.GetOrCreate(ConvertToSequence(title), ConvertToSequence(year))));
private bool isLinks(Link<TLinkAddress> query) {
if (this.links.Count(query) == 0)
return false;
else return true;
}
public List<Book> EachBooks(List<Book> books)
{
string id = "", author = "", title = "", year = "";
var query = new Link<TLinkAddress>(this.links.Constants.Any, _bookMarker, this.links.Constants.Any);
if (!isLinks(query))
{
var result = MessageBox.Show("База данных пуста\nЗаполнить?", "Предупреждение", MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
{
using (Handler xml = new Handler())
xml.SetData(indexFileName, dataFileName);
}
else books.Add(default);
}
this.links.Each((link) =>
{
var doubletOfDoublets = link[this.links.Constants.TargetPart];
var IdAuthor = this.links.GetSource(doubletOfDoublets);
var TitleYear = this.links.GetTarget(doubletOfDoublets);
id = ConvertToString(this.links.GetSource(IdAuthor));
author = ConvertToString(this.links.GetTarget(IdAuthor));
title = ConvertToString(this.links.GetSource(TitleYear));
year = ConvertToString(this.links.GetTarget(TitleYear));
books.Add(new Book { id = int.Parse(id), author = author, title = title, year = int.Parse(year) });
return this.links.Constants.Continue;
}, query);
return books;
}
protected override void Dispose(bool manual, bool wasDisposed)
{
if (!wasDisposed)
{
_disposableLinks.DisposeIfPossible();
}
}
}
}