/
EvilBeaver
/
OneScript
Обзор
Документация
Войти
/
EvilBeaver
/
OneScript
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop
src/OneScript.StandardLibrary/Collections/ValueTable/CollectionIndexes.cs
186 строк
6 KB
EvilBeaver
Попытка исправить неиндексированный поиск в ТЗ методом Найти
12 апр 2026, 12:53
12 апр 2026, 12:53
144fc70
Код
Авторство
О чём код?
/*---------------------------------------------------------- This Source Code Form is subject to the terms of the Mozilla Public License, v.2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. ----------------------------------------------------------*/ using System.Collections.Generic; using System.Linq; using OneScript.Contexts; using OneScript.Exceptions; using OneScript.StandardLibrary.Collections.Exceptions; using OneScript.StandardLibrary.Collections.Indexes; using OneScript.Values; using ScriptEngine.Machine; using ScriptEngine.Machine.Contexts; namespace OneScript.StandardLibrary.Collections.ValueTable { [ContextClass("ИндексыКоллекции", "CollectionIndexes")] public class CollectionIndexes : AutoCollectionContext<CollectionIndexes, CollectionIndex> { readonly List<CollectionIndex> _indexes = new List<CollectionIndex>(); private readonly IIndexCollectionSource _owner; public CollectionIndexes(IIndexCollectionSource owner) { _owner = owner; } [ContextMethod("Добавить", "Add")] public CollectionIndex Add(string columns) { var newIndex = new CollectionIndex(_owner, BuildFieldList(_owner, columns)); _indexes.Add(newIndex); return newIndex; } [ContextMethod("Количество", "Count")] public override int Count() { return _indexes.Count; } [ContextMethod("Удалить", "Delete")] public void Delete(IValue index) { var idx = GetIndex(index); idx.ExcludeFields(); _indexes.Remove(idx); } [ContextMethod("Очистить", "Clear")] public void Clear() { foreach (var idx in _indexes) idx.ExcludeFields(); _indexes.Clear(); } public override IValue GetIndexedValue(IValue index) { return GetIndex(index); } private CollectionIndex GetIndex(IValue index) { if (index is CollectionIndex collectionIndex) { if (_indexes.Contains(collectionIndex)) { return collectionIndex; } throw RuntimeException.InvalidArgumentValue(); } if (index is BslNumericValue numberValue) { var number = numberValue.AsNumber(); if (number >= 0 && number < _indexes.Count) { return _indexes[decimal.ToInt32(number)]; } throw RuntimeException.InvalidArgumentValue(); } throw RuntimeException.InvalidArgumentType(); } public void Rebuild() { foreach (var index in _indexes) { index.Rebuild(); } } internal void ClearIndexes() { foreach (var index in _indexes) { index.Clear(); } } internal void FieldRemoved(IValue field) { foreach (var index in _indexes) { index.FieldRemoved(field); } } internal void ElementAdded(PropertyNameIndexAccessor element) { foreach (var index in _indexes) { index.ElementAdded(element); } } internal void ElementRemoved(PropertyNameIndexAccessor element) { foreach (var index in _indexes) { index.ElementRemoved(element); } } public CollectionIndex FindSuitableIndex(IEnumerable<IValue> searchFields) { return _indexes.FirstOrDefault(index => index.CanBeUsedFor(searchFields)); } /// <summary> /// Индекс, все поля которого содержатся в <paramref name="searchColumns"/>, /// с максимальным числом полей (более узкий состав ключа — предпочтительнее). /// </summary> public CollectionIndex FindBestContainedIndex(IEnumerable<IValue> searchColumns) { CollectionIndex best = null; var bestFieldCount = -1; foreach (var index in _indexes) { if (!index.CanBeUsedFor(searchColumns)) continue; var n = index.Count(); if (n > bestFieldCount) { bestFieldCount = n; best = index; } } return best; } private static List<IValue> BuildFieldList(IIndexCollectionSource source, string fieldList) { var fields = new List<IValue>(); if (string.IsNullOrEmpty(fieldList)) return fields; var fieldNames = fieldList.Split(',', System.StringSplitOptions.RemoveEmptyEntries); foreach (var fieldName in fieldNames) { var name = fieldName.Trim(); var field = source.GetField(name) ?? throw ColumnException.WrongColumnName(fieldName); fields.Add(field); } return fields; } public override IEnumerator<CollectionIndex> GetEnumerator() { foreach (var item in _indexes) { yield return item; } } } }