Skip to content

Commit f4b8b27

Browse files
authored
Merge pull request #1635 from Mr-Rm/v2/vt_refl
V2: оптимизация ТаблицыЗначений и Рефлектора
2 parents 0a18df3 + 186a8bf commit f4b8b27

File tree

10 files changed

+225
-171
lines changed

10 files changed

+225
-171
lines changed

src/OneScript.StandardLibrary/Collections/Indexes/CollectionIndex.cs

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,28 @@ public class CollectionIndex : AutoCollectionContext<CollectionIndex, IValue>
2121
private readonly List<IValue> _fields = new List<IValue>();
2222
private readonly IIndexCollectionSource _source;
2323

24-
private readonly IDictionary<CollectionIndexKey, HashSet<IValue>> _data =
24+
private readonly Dictionary<CollectionIndexKey, HashSet<IValue>> _data =
2525
new Dictionary<CollectionIndexKey, HashSet<IValue>>();
2626

2727
public CollectionIndex(IIndexCollectionSource source, IEnumerable<IValue> fields)
2828
{
29+
foreach (var field in fields)
30+
{
31+
if (field is ValueTable.ValueTableColumn column)
32+
column.AddToIndex();
33+
_fields.Add(field);
34+
}
35+
2936
_source = source;
30-
_fields.AddRange(fields);
37+
foreach (var value in _source)
38+
{
39+
ElementAdded(value);
40+
}
3141
}
3242

3343
internal bool CanBeUsedFor(IEnumerable<IValue> searchFields)
3444
{
35-
return _fields.Any() && _fields.ToHashSet().IsSubsetOf(searchFields.ToHashSet());
45+
return _fields.Count > 0 && _fields.All(f => searchFields.Contains(f));
3646
}
3747

3848
private CollectionIndexKey IndexKey(PropertyNameIndexAccessor source)
@@ -55,11 +65,26 @@ internal void FieldRemoved(IValue field)
5565
{
5666
if (_fields.Contains(field))
5767
{
58-
while (_fields.Contains(field)) _fields.Remove(field);
68+
while (_fields.Contains(field))
69+
{
70+
if (field is ValueTable.ValueTableColumn column)
71+
column.DeleteFromIndex();
72+
73+
_fields.Remove(field);
74+
}
5975
Rebuild();
6076
}
6177
}
6278

79+
internal void ExcludeFields()
80+
{
81+
foreach (var field in _fields)
82+
{
83+
if (field is ValueTable.ValueTableColumn column)
84+
column.DeleteFromIndex();
85+
}
86+
}
87+
6388
internal void ElementAdded(PropertyNameIndexAccessor element)
6489
{
6590
var key = CollectionIndexKey.Extract(element, _fields);
@@ -82,10 +107,7 @@ internal void ElementRemoved(PropertyNameIndexAccessor element)
82107
}
83108
}
84109

85-
internal void Clear()
86-
{
87-
_data.Clear();
88-
}
110+
internal void Clear() => _data.Clear();
89111

90112
internal void Rebuild()
91113
{

src/OneScript.StandardLibrary/Collections/ValueTable/CollectionIndexes.cs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,26 +32,30 @@ public CollectionIndexes(IIndexCollectionSource owner)
3232
public CollectionIndex Add(string columns)
3333
{
3434
var newIndex = new CollectionIndex(_owner, BuildFieldList(_owner, columns));
35-
newIndex.Rebuild();
3635
_indexes.Add(newIndex);
3736
return newIndex;
3837
}
3938

4039
[ContextMethod("Количество", "Count")]
4140
public override int Count()
4241
{
43-
return _indexes.Count();
42+
return _indexes.Count;
4443
}
4544

4645
[ContextMethod("Удалить", "Delete")]
4746
public void Delete(IValue index)
4847
{
49-
_indexes.Remove(GetIndex(index));
48+
var idx = GetIndex(index);
49+
idx.ExcludeFields();
50+
_indexes.Remove(idx);
5051
}
5152

5253
[ContextMethod("Очистить", "Clear")]
5354
public void Clear()
5455
{
56+
foreach (var idx in _indexes)
57+
idx.ExcludeFields();
58+
5559
_indexes.Clear();
5660
}
5761

@@ -130,21 +134,18 @@ public CollectionIndex FindSuitableIndex(IEnumerable<IValue> searchFields)
130134
return _indexes.FirstOrDefault(index => index.CanBeUsedFor(searchFields));
131135
}
132136

133-
private static IList<IValue> BuildFieldList(IIndexCollectionSource source, string fieldList)
137+
private static List<IValue> BuildFieldList(IIndexCollectionSource source, string fieldList)
134138
{
135139
var fields = new List<IValue>();
136-
var fieldNames = fieldList.Split(',');
140+
if (string.IsNullOrEmpty(fieldList))
141+
return fields;
142+
143+
var fieldNames = fieldList.Split(',', System.StringSplitOptions.RemoveEmptyEntries);
137144
foreach (var fieldName in fieldNames)
138-
{
139-
if (!string.IsNullOrWhiteSpace(fieldName))
140-
{
141-
var field = source.GetField(fieldName.Trim());
142-
if (field == null)
143-
{
144-
throw ColumnException.WrongColumnName(fieldName);
145-
}
146-
fields.Add(field);
147-
}
145+
{
146+
var name = fieldName.Trim();
147+
var field = source.GetField(name) ?? throw ColumnException.WrongColumnName(fieldName);
148+
fields.Add(field);
148149
}
149150

150151
return fields;

src/OneScript.StandardLibrary/Collections/ValueTable/ValueTable.cs

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ public ValueTable()
3535
Columns = new ValueTableColumnCollection(this);
3636
_rows = new List<ValueTableRow>();
3737
Indexes = new CollectionIndexes(this);
38-
}
39-
38+
}
39+
4040
/// <summary>
4141
/// Коллекция колонок
4242
/// </summary>
@@ -70,7 +70,8 @@ public ValueTableRow Add()
7070
{
7171
var row = new ValueTableRow(this);
7272
_rows.Add(row);
73-
Indexes.ElementAdded(row);
73+
if (Indexes.Count() > 0)
74+
Indexes.ElementAdded(row);
7475
return row;
7576
}
7677

@@ -83,13 +84,14 @@ public ValueTableRow Add()
8384
[ContextMethod("Вставить", "Insert")]
8485
public ValueTableRow Insert(int index)
8586
{
86-
var row = new ValueTableRow(this);
8787
if (index < 0 || index > _rows.Count)
88-
_rows.Add(row); // для совместимости с 1С, хотя логичней было бы исключение
89-
else
90-
_rows.Insert(index, row);
88+
return Add(); // для совместимости с 1С, хотя логичней было бы исключение
9189

92-
Indexes.ElementAdded(row);
90+
var row = new ValueTableRow(this);
91+
_rows.Insert(index, row);
92+
93+
if (Indexes.Count() > 0)
94+
Indexes.ElementAdded(row);
9395
return row;
9496
}
9597

@@ -157,7 +159,7 @@ public ArrayImpl UnloadColumn(IValue column)
157159
return result;
158160
}
159161

160-
private List<ValueTableColumn> GetProcessingColumnList(string columnNames, bool emptyListInCaseOfNull = false)
162+
private List<ValueTableColumn> GetProcessingColumnList(string columnNames, bool emptyListInCaseOfNull = false)
161163
{
162164
var processing_list = new List<ValueTableColumn>();
163165
if (string.IsNullOrEmpty(columnNames)) // Передали пустую строку вместо списка колонок
@@ -312,16 +314,18 @@ public IValue Find(IValue value, string columnNames = null)
312314
}
313315
}
314316
return ValueFactory.Create();
315-
}
317+
}
318+
319+
private ValueTableColumn GetColumnOrThrow(string column_name)
320+
=> this.Columns.FindColumnByName(column_name)
321+
?? throw ColumnException.WrongColumnName(column_name);
322+
316323

317324
private bool CheckFilterCriteria(ValueTableRow Row, StructureImpl Filter)
318325
{
319326
foreach (var kv in Filter)
320327
{
321-
var Column = Columns.FindColumnByName(kv.Key.ToString());
322-
if (Column == null)
323-
throw ColumnException.WrongColumnName(kv.Key.ToString());
324-
328+
var Column = GetColumnOrThrow(kv.Key.ToString());
325329
IValue current = Row.Get(Column);
326330
if (!current.StrictEquals(kv.Value))
327331
return false;
@@ -344,7 +348,7 @@ public ArrayImpl FindRows(StructureImpl filter)
344348

345349
var mapped = ColumnsMap(filter);
346350
var suitableIndex = Indexes.FindSuitableIndex(mapped.Keys());
347-
var dataToScan = suitableIndex != null ? suitableIndex.GetData(mapped) : _rows;
351+
var dataToScan = suitableIndex?.GetData(mapped) ?? _rows;
348352

349353
foreach (var element in dataToScan)
350354
{
@@ -361,10 +365,7 @@ private MapImpl ColumnsMap(StructureImpl filter)
361365
var result = new MapImpl();
362366
foreach (var kv in filter)
363367
{
364-
var key = Columns.FindColumnByName(kv.Key.ToString());
365-
if (key == null)
366-
throw ColumnException.WrongColumnName(kv.Key.ToString());
367-
368+
var key = GetColumnOrThrow(kv.Key.ToString());
368369
result.Insert(key, kv.Value);
369370
}
370371

@@ -653,10 +654,7 @@ private List<ValueTableSortRule> GetSortRules(string Columns)
653654
if (description.Length > 2)
654655
throw RuntimeException.InvalidNthArgumentValue(1);
655656

656-
var sortColumn = this.Columns.FindColumnByName(description[0]);
657-
if (sortColumn == null)
658-
throw ColumnException.WrongColumnName(description[0]);
659-
657+
var sortColumn = GetColumnOrThrow(description[0]);
660658
var rule = new ValueTableSortRule
661659
{
662660
Column = sortColumn,

src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumn.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,21 @@ namespace OneScript.StandardLibrary.Collections.ValueTable
2020
public class ValueTableColumn : AutoContext<ValueTableColumn>
2121
{
2222
private string _title;
23-
private string _name;
24-
private TypeDescription _valueType;
23+
private string _name;
24+
private readonly TypeDescription _valueType;
2525
private readonly WeakReference _owner;
26-
private readonly int _id;
27-
28-
public ValueTableColumn(ValueTableColumnCollection owner, int id, string name, string title, TypeDescription type, int width)
26+
27+
private int _indicesCount = 0;
28+
public bool IsIndexable => _indicesCount != 0;
29+
public void AddToIndex() { _indicesCount++; }
30+
public void DeleteFromIndex() { if (_indicesCount != 0) _indicesCount--; }
31+
32+
public ValueTableColumn(ValueTableColumnCollection owner, string name, string title, TypeDescription type, int width)
2933
{
3034
_name = name;
3135
_title = title;
3236
_valueType = type ?? new TypeDescription();
3337
Width = width;
34-
_id = id;
3538

3639
_owner = new WeakReference(owner);
3740
}
@@ -65,7 +68,6 @@ public string Name
6568
_title = value;
6669

6770
_name = value;
68-
6971
}
7072
}
7173
/// <summary>

src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableColumnCollection.cs

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,40 @@ namespace OneScript.StandardLibrary.Collections.ValueTable
2525
[ContextClass("КоллекцияКолонокТаблицыЗначений", "ValueTableColumnCollection")]
2626
public class ValueTableColumnCollection : AutoContext<ValueTableColumnCollection>, ICollectionContext<ValueTableColumn>, IDebugPresentationAcceptor
2727
{
28+
private static readonly StringComparer _namesComparer = StringComparer.OrdinalIgnoreCase;
29+
2830
private readonly List<ValueTableColumn> _columns = new List<ValueTableColumn>();
29-
private readonly StringComparer _namesComparer = StringComparer.OrdinalIgnoreCase;
3031
private readonly ValueTable _owner;
31-
private int maxColumnId = 0;
3232

3333
public ValueTableColumnCollection(ValueTable owner)
3434
{
3535
_owner = owner;
3636
}
3737

38+
public ValueTableColumn AddUnchecked(string name, string title, TypeDescription type = null)
39+
{
40+
var column = new ValueTableColumn(this, name, title, type, 0);
41+
_columns.Add(column);
42+
return column;
43+
}
44+
45+
public ValueTableColumn AddUnchecked(string name, string title = null)
46+
{
47+
var column = new ValueTableColumn(this, name, title ?? name, null, 0);
48+
_columns.Add(column);
49+
return column;
50+
}
51+
52+
53+
private void CheckColumnName(string name)
54+
{
55+
if (!Utils.IsValidIdentifier(name))
56+
throw ColumnException.WrongColumnName(name);
57+
58+
if (FindColumnByName(name) != null)
59+
throw ColumnException.DuplicatedColumnName(name);
60+
}
61+
3862
/// <summary>
3963
/// Добавляет колонку в таблицу значений
4064
/// </summary>
@@ -46,13 +70,9 @@ public ValueTableColumnCollection(ValueTable owner)
4670
[ContextMethod("Добавить", "Add")]
4771
public ValueTableColumn Add(string name, TypeDescription type = null, string title = null, int width = 0)
4872
{
49-
if (!Utils.IsValidIdentifier(name))
50-
throw ColumnException.WrongColumnName(name);
73+
CheckColumnName(name);
5174

52-
if (FindColumnByName(name) != null)
53-
throw ColumnException.DuplicatedColumnName(name);
54-
55-
var column = new ValueTableColumn(this, ++maxColumnId, name, title, type, width);
75+
var column = new ValueTableColumn(this, name, title, type, width);
5676
_columns.Add(column);
5777

5878
return column;
@@ -70,13 +90,9 @@ public ValueTableColumn Add(string name, TypeDescription type = null, string tit
7090
[ContextMethod("Вставить", "Insert")]
7191
public ValueTableColumn Insert(int index, string name, TypeDescription type = null, string title = null, int width = 0)
7292
{
73-
if (!Utils.IsValidIdentifier(name))
74-
throw ColumnException.WrongColumnName(name);
75-
76-
if (FindColumnByName(name) != null)
77-
throw ColumnException.DuplicatedColumnName(name);
93+
CheckColumnName(name);
7894

79-
ValueTableColumn column = new ValueTableColumn(this, ++maxColumnId, name, title, type, width);
95+
ValueTableColumn column = new ValueTableColumn(this, name, title, type, width);
8096
_columns.Insert(index, column);
8197

8298
return column;
@@ -113,10 +129,7 @@ public int Count()
113129
[ContextMethod("Найти", "Find")]
114130
public IValue Find(string name)
115131
{
116-
ValueTableColumn Column = FindColumnByName(name);
117-
if (Column == null)
118-
return ValueFactory.Create();
119-
return Column;
132+
return FindColumnByName(name) ?? ValueFactory.Create();
120133
}
121134

122135
/// <summary>

src/OneScript.StandardLibrary/Collections/ValueTable/ValueTableRow.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,8 @@ public ValueTableRow(ValueTable owner)
2424
_owner = owner;
2525
}
2626

27-
public int Count()
28-
{
29-
return _owner.Columns.Count();
30-
}
31-
27+
public int Count() => _owner.Columns.Count();
28+
3229
public int Count(IBslProcess process) => Count();
3330

3431
/// <summary>
@@ -89,9 +86,14 @@ public void Set(IValue index, IValue value)
8986

9087
public void Set(ValueTableColumn column, IValue value)
9188
{
92-
_owner.Indexes.ElementRemoved(this);
93-
_data[column] = column.ValueType.AdjustValue(value);
94-
_owner.Indexes.ElementAdded(this);
89+
if (column.IsIndexable)
90+
{
91+
_owner.Indexes.ElementRemoved(this);
92+
_data[column] = column.ValueType.AdjustValue(value);
93+
_owner.Indexes.ElementAdded(this);
94+
}
95+
else
96+
_data[column] = column.ValueType.AdjustValue(value);
9597
}
9698

9799
public void OnOwnerColumnRemoval(ValueTableColumn column)

0 commit comments

Comments
 (0)