Skip to content

Commit c073386

Browse files
committed
Добавлен LRU кеш для лямбда выражений
1 parent 3607870 commit c073386

File tree

4 files changed

+168
-69
lines changed

4 files changed

+168
-69
lines changed

packagedef

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Описание.Имя("lambdas")
2-
.Версия("0.3.0")
2+
.Версия("0.3.1")
33
.Автор("Кирилл Черненко")
44
.АдресАвтора("https://github.com/sfaqer")
55
.Описание("API для реализации функциональных интерфейсов для OneScript")

src/internal/Модули/ЛямбдыКешируемыеЗначения.os

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
Перем ЭтоЛямбдаВыражение; // Кеш регулярного выражения лямбда выражения
22
Перем СодержитВозвратЗначения; // Кеш регулярного выражения содержит возврат значения
33

4+
Перем КешСозданныхЛямбд; // LRU кеш созданных лямбд
5+
46
Функция РегулярноеВыражениеЭтоЛямбдаВыражение() Экспорт
57

68
Если ЭтоЛямбдаВыражение = Неопределено Тогда
@@ -24,3 +26,46 @@
2426
Возврат СодержитВозвратЗначения;
2527

2628
КонецФункции
29+
30+
Функция ДостатьИзКеша(Выражение, Интерфейс, Контекст, ЗахватываемыйОбъект) Экспорт
31+
32+
Строки = КешСозданныхЛямбд.НайтиСтроки(
33+
Новый Структура(
34+
"Выражение, Интерфейс, Контекст, ЗахватываемыйОбъект",
35+
Выражение,
36+
Интерфейс,
37+
Контекст,
38+
ЗахватываемыйОбъект
39+
)
40+
);
41+
42+
Если Строки.Количество() = 0 Тогда
43+
Возврат Неопределено;
44+
КонецЕсли;
45+
46+
КешСозданныхЛямбд.Сдвинуть(Строки[0], -КешСозданныхЛямбд.Индекс(Строки[0]));
47+
Возврат Строки[0].Объект;
48+
49+
КонецФункции
50+
51+
Процедура ПоложитьВКеш(Выражение, Интерфейс, Контекст, ЗахватываемыйОбъект, Объект) Экспорт
52+
53+
Строка = КешСозданныхЛямбд.Вставить(0);
54+
Строка.Выражение = Выражение;
55+
Строка.Интерфейс = Интерфейс;
56+
Строка.Контекст = Контекст;
57+
Строка.ЗахватываемыйОбъект = ЗахватываемыйОбъект;
58+
Строка.Объект = Объект;
59+
60+
Если КешСозданныхЛямбд.Количество() > 20 Тогда
61+
КешСозданныхЛямбд.Удалить(КешСозданныхЛямбд.Количество() - 1);
62+
КонецЕсли;
63+
64+
КонецПроцедуры
65+
66+
КешСозданныхЛямбд = Новый ТаблицаЗначений();
67+
КешСозданныхЛямбд.Колонки.Добавить("Выражение");
68+
КешСозданныхЛямбд.Колонки.Добавить("Интерфейс");
69+
КешСозданныхЛямбд.Колонки.Добавить("Контекст");
70+
КешСозданныхЛямбд.Колонки.Добавить("ЗахватываемыйОбъект");
71+
КешСозданныхЛямбд.Колонки.Добавить("Объект");

src/Классы/ЛямбдаВыражение.os

Lines changed: 83 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -141,80 +141,19 @@
141141
// Сценарий - Созданный сценарий
142142
//
143143
Функция ВОбъект() Экспорт
144-
144+
145145
Если Не ЗначениеЗаполнено(мИнтерфейс) Тогда
146146
ОпределитьИнтерфейс();
147147
КонецЕсли;
148148

149-
МетодИнтерфейса = мИнтерфейс.ПолучитьКартуИнтерфейса()[0];
149+
Объект = ЛямбдыКешируемыеЗначения.ДостатьИзКеша(мВыражение, мИнтерфейс, мКонтекст, мОбъект);
150+
ОбработкаДекоратора.СинхронизироватьПоля(мОбъект, Объект);
150151

151-
Метод = Новый Метод(МетодИнтерфейса.Имя)
152-
.Публичный()
153-
.ТелоМетода(РазобранноеВыражение.Тело);
154-
155-
Если Не МетодИнтерфейса.ЭтоФункция Тогда
156-
Метод.ЭтоПроцедура();
152+
Если Не ЗначениеЗаполнено(Объект) Тогда
153+
Объект = СоздатьОбъект();
154+
ЛямбдыКешируемыеЗначения.ПоложитьВКеш(мВыражение, мИнтерфейс, мКонтекст, мОбъект, Объект);
157155
КонецЕсли;
158156

159-
Для Каждого Аннотация Из РазобранноеВыражение.Аннотации Цикл
160-
161-
АннотацияМетода = Новый Аннотация(Аннотация.Имя);
162-
163-
Для Каждого ПараметрАннотации Из Аннотация.Параметры Цикл
164-
АннотацияМетода.Параметр(ПараметрАннотации.Значение, ПараметрАннотации.Имя);
165-
КонецЦикла;
166-
167-
Метод.Аннотация(АннотацияМетода);
168-
169-
КонецЦикла;
170-
171-
Для каждого Параметр Из РазобранноеВыражение.Параметры Цикл
172-
173-
ПараметрМетода = Новый ПараметрМетода(Параметр.Имя);
174-
175-
Для Каждого Аннотация Из Параметр.Аннотации Цикл
176-
177-
АннотацияПараметра = Новый Аннотация(Аннотация.Имя);
178-
179-
Для Каждого ПараметрАннотации Из Аннотация.Параметры Цикл
180-
АннотацияПараметра.Параметр(ПараметрАннотации.Значение, ПараметрАннотации.Имя);
181-
КонецЦикла;
182-
183-
ПараметрМетода.Аннотация(АннотацияПараметра);
184-
185-
КонецЦикла;
186-
187-
Метод.Параметр(ПараметрМетода);
188-
189-
КонецЦикла;
190-
191-
Построитель = Новый ПостроительДекоратора(мОбъект)
192-
.Отладка(Отладка)
193-
.Поле(Новый Поле("Выражение").ЗначениеПоУмолчанию(мВыражение))
194-
.Метод(Метод)
195-
.Метод(
196-
Новый Метод("ОбработкаПолученияПредставления")
197-
.ЭтоПроцедура()
198-
.Параметр(Новый ПараметрМетода("Представление"))
199-
.Параметр(Новый ПараметрМетода("СтандартнаяОбработка"))
200-
.ТелоМетода("СтандартнаяОбработка = Ложь; Представление = Выражение;")
201-
);
202-
203-
Для каждого ПеременнаяИЗначение Из мКонтекст Цикл
204-
205-
Построитель.Поле(
206-
Новый Поле(ПеременнаяИЗначение.Ключ)
207-
.ЗначениеПоУмолчанию(ПеременнаяИЗначение.Значение)
208-
);
209-
210-
КонецЦикла;
211-
212-
Объект = Построитель.Построить();
213-
214-
Рефлектор = Новый РефлекторОбъекта(Объект);
215-
216-
Рефлектор.РеализуетИнтерфейс(мИнтерфейс, Истина);
217-
218157
Возврат Объект;
219158

220159
КонецФункции
@@ -295,14 +234,90 @@
295234

296235
КонецПроцедуры
297236

237+
Функция СоздатьОбъект()
238+
239+
МетодИнтерфейса = мИнтерфейс.ПолучитьКартуИнтерфейса()[0];
240+
241+
Метод = Новый Метод(МетодИнтерфейса.Имя)
242+
.Публичный()
243+
.ТелоМетода(РазобранноеВыражение.Тело);
244+
245+
Если Не МетодИнтерфейса.ЭтоФункция Тогда
246+
Метод.ЭтоПроцедура();
247+
КонецЕсли;
248+
249+
Для Каждого Аннотация Из РазобранноеВыражение.Аннотации Цикл
250+
251+
АннотацияМетода = Новый Аннотация(Аннотация.Имя);
252+
253+
Для Каждого ПараметрАннотации Из Аннотация.Параметры Цикл
254+
АннотацияМетода.Параметр(ПараметрАннотации.Значение, ПараметрАннотации.Имя);
255+
КонецЦикла;
256+
257+
Метод.Аннотация(АннотацияМетода);
258+
259+
КонецЦикла;
260+
261+
Для каждого Параметр Из РазобранноеВыражение.Параметры Цикл
262+
263+
ПараметрМетода = Новый ПараметрМетода(Параметр.Имя);
264+
265+
Для Каждого Аннотация Из Параметр.Аннотации Цикл
266+
267+
АннотацияПараметра = Новый Аннотация(Аннотация.Имя);
268+
269+
Для Каждого ПараметрАннотации Из Аннотация.Параметры Цикл
270+
АннотацияПараметра.Параметр(ПараметрАннотации.Значение, ПараметрАннотации.Имя);
271+
КонецЦикла;
272+
273+
ПараметрМетода.Аннотация(АннотацияПараметра);
274+
275+
КонецЦикла;
276+
277+
Метод.Параметр(ПараметрМетода);
278+
279+
КонецЦикла;
280+
281+
Построитель = Новый ПостроительДекоратора(мОбъект)
282+
.Отладка(Отладка)
283+
.Поле(Новый Поле("Выражение").ЗначениеПоУмолчанию(мВыражение))
284+
.Метод(Метод)
285+
.Метод(
286+
Новый Метод("ОбработкаПолученияПредставления")
287+
.ЭтоПроцедура()
288+
.Параметр(Новый ПараметрМетода("Представление"))
289+
.Параметр(Новый ПараметрМетода("СтандартнаяОбработка"))
290+
.ТелоМетода("СтандартнаяОбработка = Ложь; Представление = Выражение;")
291+
);
292+
293+
Контекст = ?(ЗначениеЗаполнено(мКонтекст), мКонтекст, Новый Структура());
294+
295+
Для каждого ПеременнаяИЗначение Из Контекст Цикл
296+
297+
Построитель.Поле(
298+
Новый Поле(ПеременнаяИЗначение.Ключ)
299+
.ЗначениеПоУмолчанию(ПеременнаяИЗначение.Значение)
300+
);
301+
302+
КонецЦикла;
303+
304+
Объект = Построитель.Построить();
305+
306+
Рефлектор = Новый РефлекторОбъекта(Объект);
307+
308+
Рефлектор.РеализуетИнтерфейс(мИнтерфейс, Истина);
309+
310+
Возврат Объект;
311+
312+
КонецФункции
313+
298314
Процедура ПриСозданииОбъекта(Выражение)
299315

300316
РазобранноеВыражение = Новый Структура(
301317
"Аннотации, Параметры, Тело"
302318
);
303319

304320
мВыражение = Выражение;
305-
мКонтекст = Новый Структура();
306321
Отладка = Ложь;
307322

308323
РазобратьВыражение(Выражение);

tests/ЛямбдаВыражение.os

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,45 @@
571571

572572
КонецПроцедуры
573573

574+
&Тест
575+
Процедура ОбъектыЛямбдаВыраженийКешируются() Экспорт
576+
577+
// Дано
578+
ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> х = х + 1");
579+
Объект = ЛямбдаВыражение.ВОбъект();
580+
581+
ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> х = х + 1");
582+
583+
// Когда
584+
Результат = ЛямбдаВыражение.ВОбъект();
585+
586+
// Тогда
587+
Ожидаем.Что(Результат).Равно(Объект);
588+
589+
КонецПроцедуры
590+
591+
&Тест
592+
Процедура ОбъектыЛямбдаВыраженийВытесняютсяИзКеша() Экспорт
593+
594+
// Дано
595+
ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> х = х + 1");
596+
Объект = ЛямбдаВыражение.ВОбъект();
597+
598+
Для Сч = 2 По 22 Цикл // Вытесним из кеша
599+
_ = Новый ЛямбдаВыражение("х -> х = х + " + Сч)
600+
.ВОбъект();
601+
КонецЦикла;
602+
603+
ЛямбдаВыражение = Новый ЛямбдаВыражение("х -> х = х + 1");
604+
605+
// Когда
606+
Результат = ЛямбдаВыражение.ВОбъект();
607+
608+
// Тогда
609+
Ожидаем.Что(Результат).Не_().Равно(Объект);
610+
611+
КонецПроцедуры
612+
574613
Функция ЗахватываемыйОбъект()
575614

576615
Возврат Новый ПостроительДекоратора()

0 commit comments

Comments
 (0)