![]() |
|
Механизмы платформенной сериализации | ☑ | ||
---|---|---|---|---|
0
Tateossian
12.02.18
✎
14:31
|
​Коллеги, всем привет! Это будет пост для размышления и обсуждения следующей проблемы. Мне не нравятся существующий стек технологий интеграции между 1С. Ни XML/JSON/свойTXT. Ни COM не нравится. Разве что веб-сервисы. Но интересуют именно коробочные, нативные решения. А вот почему. Я являюсь разработчиком на J2EE в нагрузку к 1С и там есть такая технология - встроенная сериализация в binary-формате. Почему 1С не сделает такой? Вот ежли брать классические текстовые форматы - они очень много весят. До упаковки в zip. И долго разбираются парсером. Каждый день ввиду специфики приходится грузить в базу 80Гб xml. Он грузится в 16 фоновых заданий и занимает процесс все равно около 1-1,5 часа. А вот такая проблема - я использую свою систему версионирования. Для хранения ссылок используется метод ЗначениеВСтрокуВнутр(); так как это поле нужно для поиска - оно индексируемое, а лимит на строковый индекс - 442 символа, а бывают отборы на 900 и более строк. Ок, для быстрого поиска я юзаю хэш-ключи, удобно многомерные сущности создавать, эти механизмы ускорили проведение расчета себестоимости с 30 до 5 минут. Но у хэша есть обратная проблема - из жэша нельзя получить искомые сущности. Так вот вопрос: как придумать свою компактную систему сериализации, чтобы быстро работала и весила не много. Может есть готовые советы. FastInfoSet не предлагать. Делал через поток в памяти скрестить с zip архиватором, но там не обойтись без вывода в файл, а нужен быстрый способ чтения/записи, без временных файлов. Какие есть варианты?
|
|||
44
H A D G E H O G s
12.02.18
✎
15:27
|
Но ты можешь расширить альфавит и писать base128 или base256, зная, что у тебя используется только кириллица, тогда строка будет еще короче. Только придется самому писать функцию.
|
|||
45
Tateossian
12.02.18
✎
15:29
|
(42) Все верно, но не лучше ли заставить работать zip архиватор? Короче, переформулирую: как строку закодировать в строку, чтобы она была короче исходной и подвергалась десериализации?
|
|||
46
Tateossian
12.02.18
✎
15:29
|
(44) Не вопрос. Есть предположение, что это будет работать очень универсально и быстро?
|
|||
47
Tateossian
12.02.18
✎
15:31
|
(41) Вот, у меня такая функция есть для кодирования в хэш
Функция ПолучитьХэш(МассивОбъектов, Знач Метод = "ХешФункция.SHA256", Знач БинарныйФормат = Истина) Экспорт Перем ДД, ДДСтрокой; Ф = ?(ТипЗнч(Метод) = Тип("Строка"), ПредопределенноеЗначение(Метод), Метод); Если Не ТипЗнч(МассивОбъектов) = Тип("Массив") Тогда ЛокМассив = Новый Массив; ЛокМассив.Добавить(МассивОбъектов); КонецЕсли; ФОбъекты = Новый ФиксированныйМассив(МассивОбъектов); ПростыеТипы = Новый ОписаниеТипов("Строка,Число,Булево,Дата"); СсылочныеТипы = Новый ОписаниеТипов(Документы.ТипВсеСсылки(), Справочники.ТипВсеСсылки().Типы()); СсылочныеТипы = Новый ОписаниеТипов(СсылочныеТипы, Перечисления.ТипВсеСсылки().Типы()); СсылочныеТипы = Новый ОписаниеТипов(СсылочныеТипы, ПланыВидовХарактеристик.ТипВсеСсылки().Типы()); СсылочныеТипы = Новый ОписаниеТипов(СсылочныеТипы, ПланыСчетов.ТипВсеСсылки().Типы()); СсылочныеТипы = Новый ОписаниеТипов(СсылочныеТипы, ПланыВидовРасчета.ТипВсеСсылки().Типы()); СсылочныеТипы = Новый ОписаниеТипов(СсылочныеТипы, БизнесПроцессы.ТипВсеСсылки().Типы()); СсылочныеТипы = Новый ОписаниеТипов(СсылочныеТипы, БизнесПроцессы.ТипВсеСсылкиТочекМаршрутаБизнесПроцессов().Типы()); СсылочныеТипы = Новый ОписаниеТипов(СсылочныеТипы, Задачи.ТипВсеСсылки().Типы()); СсылочныеТипы = Новый ОписаниеТипов(СсылочныеТипы, ПланыОбмена.ТипВсеСсылки().Типы()); Хеширование = Новый ХешированиеДанных(Ф); Получатели = Новый Массив; Получатели.Добавить("XMLСтрока(Эл)"); Получатели.Добавить("СокращенноДанныеИнформационнойБазыСтрокой(Эл)"); Получатели.Добавить("ДанныеИнформационнойБазыСтрокой(Эл)"); Кейс = Новый ФиксированныйМассив(Получатели); Для Каждого Эл Из ФОбъекты Цикл Флаг = ЧислоИзДвоичнойСтроки("0b" + ПолучитьФлаг(Не ПростыеТипы.СодержитТип(ТипЗнч(Эл))) + ПолучитьФлаг(Не СсылочныеТипы.СодержитТип(ТипЗнч(Эл))))-1; ТекстовыйИД = Вычислить(Получатели[Флаг]); Хеширование.Добавить(ТекстовыйИД); КонецЦикла; Если Ф = ХешФункция.CRC32 Тогда Буф = Новый БуферДвоичныхДанных(8); Буф.ЗаписатьЦелое64(0, Хеширование.ХешСумма); ДД = ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(Буф); Иначе ДД = Хеширование.ХешСумма; КонецЕсли; Если Не БинарныйФормат Тогда ДДСтрокой = ПолучитьHexСтрокуИзДвоичныхДанных(ДД); КонецЕсли; Возврат ?(БинарныйФормат, ДД, ДДСтрокой); КонецФункции |
|||
48
H A D G E H O G s
12.02.18
✎
15:38
|
(47) попробуй сначало base64
|
|||
49
H A D G E H O G s
12.02.18
✎
15:42
|
sha256 - 32 байта данных. В base64 это будет 43 символа. Или 86 байт данных в виде строки в 1С
|
|||
50
Fragster
гуру
12.02.18
✎
15:46
|
(49) в utf-8 первые 128 символов таблицы весят 1 байт
|
|||
51
Fragster
гуру
12.02.18
✎
15:49
|
хотя глянул, в мсскуле не utf-8
|
|||
52
Tateossian
12.02.18
✎
15:52
|
(51) Только начиная с 16 поддержка UTF реализована
|
|||
53
H A D G E H O G s
12.02.18
✎
15:54
|
"Капитан сказал большому старине Джо Генри: Здесь, где-то здесь валяется старый молоток.
Возьми этот отбойный молоток и начинай работу! И пусть он стучит! Стучит! Бьет сталь до дыр! Пусть стучит, стучит, бьет сталь до дыр!" Короче, работайте, братья. |
|||
54
Tateossian
12.02.18
✎
16:02
|
(53) Смотри, есть такой пример. Ключ регистра в значении стр внутр:
{"#",767bf336-1fa8-4283-be31-fee83ee3c286,{2,{"D",00010101000000},0:00000000000000000000000000000000,2,{"#",a86305d7-b8a1-4312-901f-2ade3efdb351,135:911aee3a33f0f6be4ac5d0f44f4481f9},{"#",39cb59ea-9735-433b-bf1d-8eb9e4b96cc0,153:8ad2005056920edd11deebd9d3a8033e},0,0}} 270 символов потом его переводим в бин-данные: ДД = ПолучитьДвоичныеДанныеИзСтроки(СтрокаКлючи); Выход = Base64Строка(ДД) На выходе вот это eyIjIiw3NjdiZjMzNi0xZmE4LTQyODMtYmUzMS1mZWU4M2VlM2MyODYsezIseyJE IiwwMDAxMDEwMTAwMDAwMH0sMDowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMCwyLHsiIyIsYTg2MzA1ZDctYjhhMS00MzEyLTkwMWYtMmFkZTNlZmRiMzUx LDEzNTo5MTFhZWUzYTMzZjBmNmJlNGFjNWQwZjQ0ZjQ0ODFmOX0seyIjIiwzOWNi NTllYS05NzM1LTQzM2ItYmYxZC04ZWI5ZTRiOTZjYzAsMTUzOjhhZDIwMDUwNTY5 MjBlZGQxMWRlZWJkOWQzYTgwMzNlfSwwLDB9fQoK (370 символов) еще больше стало... Но идея у меня была такая же, надо отсюда копать. |
|||
55
Вафель
12.02.18
✎
16:05
|
так бы и говорил, что тебе нужна архивация.
Но эта проблема уже решена давно |
|||
56
Вафель
12.02.18
✎
16:06
|
Например rar умеет входщие данные брать из stdin
|
|||
57
ptiz
12.02.18
✎
16:06
|
(0)
Я так делаю, когда надо объекты 1С гонять: объект 1С (например, структура с кучей таблиц значений) - в хранилище со сжатием: Хранилище = Новый ХранилищеЗначения(МояСтруктура, Новый СжатиеДанных(9)); хранилище - сериализую: КомандаСтрокой = СериализоватьЗначениеВXML(Хранилище); Функция СериализоватьЗначениеВXML(Значение) Экспорт ЗаписьXML = Новый ЗаписьXML(); ЗаписьXML.УстановитьСтроку(); СериализаторXDTO.ЗаписатьXML(ЗаписьXML, Значение); СтрокаXML = ЗаписьXML.Закрыть(); Возврат СтрокаXML; КонецФункции // СериализоватьЗначениеВXML() Ну и потом - обратная операция. |
|||
58
Tateossian
12.02.18
✎
16:06
|
(55) Как, расскажи. Вот ищу тебя, друг!
|
|||
59
Tateossian
12.02.18
✎
16:10
|
(57)
Хранилище = Новый ХранилищеЗначения(Стр, Новый СжатиеДанных(9)); Выход = ТиповыеОтчеты.СериализоватьОбъектXDTO(Хранилище); Возвращает еще больше строк чем было)) Уж лучше не сериализовать, ибо это тот же бейс64 <ValueStorage xmlns="http://v8.1c.ru/8.1/data/core" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AgFTS2/0iI3BTqDV67a9oKcN7ZDBTQUxDEQRxy/9JsI1luw4ycbLlQ6oII6dJlZb GYdfEi0QVuKGRAM8+ziekef1+eni8+NxhPcQwxHCSwhxq5tO5go0e4OcGoM6E0z3 xu48UqvxSHHJ35YcEemaizPijn8Qr9vvqN4qY7ENtHWCzJRAkCakbs4+TblQJC67 EPUV3Zknzqqe+yiGM+e1jaacP44sQ4t4B9m4LEdW0EkGzVU8q9QxMFLhvXVLiAVL lYRuRmTuamLcGzL7eiTied5v99t/L7/3Es4v</ValueStorage> |
|||
60
Tateossian
12.02.18
✎
16:12
|
(56) Представляю теперь потери на запуск стороннего процесса чтобы 100 символов засунуть в архив.
Уж проще переписать функцию архивирования на 1С:))) |
|||
61
Вафель
12.02.18
✎
16:12
|
бейс64 много избыточности добавляет. ибо он нечитаемые символы приводит к читаемым. а тебе это не нунжно
|
|||
62
H A D G E H O G s
12.02.18
✎
16:13
|
(54) Мы до этого говорили о хэше, а не о данных. Откуда у тебя данные вылезли внезапно?
|
|||
63
Tateossian
12.02.18
✎
16:14
|
(61) Да, идеальный вариант - это хэширование. Но это процесс одностороний... Почему я про зип заговорил, потому как 80Гб файл текста превращается в 100Мб, так как тест очень сильно архивируется. У него избыточность большая.
|
|||
64
Tateossian
12.02.18
✎
16:15
|
(62) Я говорил о сериализации и десериализации.
|
|||
65
Вафель
12.02.18
✎
16:16
|
все смешалось в доме Облонских
|
|||
66
Cyberhawk
12.02.18
✎
16:21
|
(63) А чем тебе уменьшение 80 Гб до 100 Мб не подходит?
|
|||
67
Tateossian
12.02.18
✎
16:21
|
(65) Не знаю как там у них, а у меня вопрос вполне понятен.
Как сжимать строки не теряя строковой сути? |
|||
68
Tateossian
12.02.18
✎
16:27
|
(66) Смотри, есть специальный регистр по версиям. Он в отдельной базе. Он умеет хранить спарвочники, документы и независимые регистры сведений, всю историю. У необъектных сущностей используются ключи, которые состоят из отборов. При сериализации ключ может занимать очень много места, более 900 символов. Хочу сократить это (сейчас строка дробится на две части, 442 символа и все остальное).
И вторая цель - небольшие кусочки данных в прикладном коде использовать в своем формате. Для большого файла это удобно, а для маленьких операций очень затратно открывать zip архиватор. |
|||
69
Cyberhawk
12.02.18
✎
16:34
|
(68) Справочник ключей не предлагать? :)
|
|||
70
Tateossian
12.02.18
✎
16:34
|
(69) Нет, так как там сделано все на третьей нормальной форме на уровне SQL-я.
|
|||
71
Cyberhawk
12.02.18
✎
16:35
|
"небольшие кусочки данных в прикладном коде использовать в своем формате ... для маленьких операций очень затратно открывать zip архиватор" // Кастую TormozIT в ветку
|
|||
72
Tateossian
12.02.18
✎
16:36
|
(71) Да, я пользуюсь его инструментами разработчика, крутая штукенция. Там внутри можно хватить удар:) Но сериализация там у него стандартная. Зип+XDTO
|
|||
73
Cyberhawk
12.02.18
✎
16:36
|
(70) Ты хочешь, чтоб длинную строку можно было сделать короче 900 символов и чтоб обратно из этого упакованного вида еще делать можно было?
|
|||
74
Tateossian
12.02.18
✎
16:36
|
(73) ДА!
|
|||
75
Cyberhawk
12.02.18
✎
16:37
|
(74) Но ты же понимаешь, что когда-то этому настанет предел и очередная длинная строка не влезет в ограничение по длине 900? Или такого не предвидится (кодируемые строки не растут со временем)?
|
|||
76
Tateossian
12.02.18
✎
16:38
|
(73) Почему я так хочу - да потому что zip даже на 400 символов потом весит в пять раз меньше. Но файловую систему использовать для этого кощунственно - у меня кластер по 64Кб. Каждый файл на 10 байт - это минус 64Кб.
|
|||
77
Cyberhawk
12.02.18
✎
16:39
|
(76) Был тут на форуме кто-то кто строковый ГУИД превращал в ЕАН13 :)
|
|||
78
Cyberhawk
12.02.18
✎
16:40
|
С потерями что ли тока
|
|||
79
Cyberhawk
12.02.18
✎
16:40
|
Ну т.е. с коллизиями
|
|||
80
Tateossian
12.02.18
✎
16:40
|
(75) Да это я взял лимит на индекс в байтах в SQL. В идеале нужна другая сериализация. Самый простой вариант - упакованная XML строка в двоичный данные и потом в виде HEX строки хранимая)
|
|||
81
Tateossian
12.02.18
✎
16:41
|
(78) Ну zip же может текст и без потерь сжимать. По крайней мере на практике не разу не бывало чтоб xml из zip не прочитался.
|
|||
82
Cyberhawk
12.02.18
✎
16:42
|
(81) Я так понял что тебя устроит алгоритм zip-сжатия, если он будет выполняться в памяти (без задействования диска)?
|
|||
83
Tateossian
12.02.18
✎
16:42
|
(82) Да.
|
|||
84
Cool_Profi
12.02.18
✎
16:42
|
(81) Зип с потерями сжимать не может. по алгоритму
|
|||
85
Tateossian
12.02.18
✎
16:42
|
(82) Я пытался потоки прикрутить 1С, но там на выход только можно поток, на вход нельзя.
|
|||
86
Cyberhawk
12.02.18
✎
16:44
|
(85) Нативную компоненту напиши какую-нибудь, на вход ей подаешь строку или поток, она там уже в памяти шуршит и делает. Или нативные компоненты 1С так не умеют (с памятью работать) в силу каких-нибудь архитектурных ограничений?
|
|||
87
Tateossian
12.02.18
✎
16:44
|
(82) ЗаписьZipФайла (ZipFileWriter)
Методы: Добавить (Add) Записать (Write) Открыть (Open) ПолучитьДвоичныеДанные (GetBinaryData) <================= вот это Конструкторы: На основании имени файла На основании потока Формирование неинициализированного объекта Описание: Предназначен для записи в ZIP-архив. Доступность: Тонкий клиент, сервер, толстый клиент, внешнее соединение. ----------------- Можно кончено и через средства ОС запускать zip, но это не принесет особого эффекта на небольших операциях, очевидно. |
|||
88
H A D G E H O G s
12.02.18
✎
16:45
|
ЗаписьZipФайла (ZipFileWriter)
На основании потока Синтаксис: Новый ЗаписьZipФайла(<Поток>, <Пароль>, <Комментарий>, <МетодСжатия>, <УровеньСжатия>, <МетодШифрования>) |
|||
89
Buster007
12.02.18
✎
16:45
|
(22) "И очень я считаю красиво." я так понимаю, это ты придумал эту схему?)
|
|||
90
Tateossian
12.02.18
✎
16:45
|
(88) Тут есть подвох:
ПолучитьДвоичныеДанные(<Пароль>, <Комментарий>, <МетодСжатия>, <УровеньСжатия>, <МетодШифрования>) Параметры: <Пароль> (необязательный) Тип: Строка. Пароль, который будет назначен архиву. Если пароль не назначен или является пустой строкой, то шифрование не происходит. <Комментарий> (необязательный) Тип: Строка. Комментарий, описывающий ZIP-файл. <МетодСжатия> (необязательный) Тип: МетодСжатияZIP. Метод сжатия, которым будет сжиматься архив. Значение по умолчанию: Сжатие. <УровеньСжатия> (необязательный) Тип: УровеньСжатияZIP. Уровень сжатия данных. Значение по умолчанию: Оптимальный. <МетодШифрования> (необязательный) Тип: МетодШифрованияZIP. Метод шифрования, которым будет зашифрован архив. Значение по умолчанию: Zip20. Возвращаемое значение: Тип: ДвоичныеДанные. Описание: Получает ZIP-архив в виде двоичных данных и закрывает файл. При использовании данного метода объект ЗаписьZipФайла должен быть создан с помощью конструктора без параметров. <========================= При этом открывать архив явно с помощью метода Открыть не требуется. При завершении работы данный метод закрывает архив, аналогично методу Записать. |
|||
91
H A D G E H O G s
12.02.18
✎
16:46
|
Но я все равно нихера не понимаю, что хочет автор.
Зачем в ключи поиска писать данные? В ключи поиска нужно писать хэш данных. Данные нужно писать в неиндексируемые поля. |
|||
92
Tateossian
12.02.18
✎
16:46
|
(89) Да, я.
|
|||
93
Tateossian
12.02.18
✎
16:47
|
(91) А как ты историю по регистру будешь смотреть? Час сидеть, ждать SEEk LOOP когда выполнится? Напоминаю, база с версионированием - одна таблица более 100Гб. Там миллиард строк.
|
|||
94
H A D G E H O G s
12.02.18
✎
16:49
|
(93) Я ты часто данные смотришь?
|
|||
95
H A D G E H O G s
12.02.18
✎
16:49
|
(93) Ты имел ввиду key lookup ? Так он быстр.
|
|||
96
Tateossian
12.02.18
✎
16:49
|
(91) Можно и не писать, для этого есть хэширование. Но хэш ты потом не загрузишь в другую базу.
|
|||
97
Tateossian
12.02.18
✎
16:50
|
(94) Очень. Все этим пользуются, без него никак. А на ссылку там стоит строка или ЗначениеВСтрокуВнутр()
|
|||
98
Tateossian
12.02.18
✎
16:52
|
(95) на миллиарде записей нужно полминуты иногда ждать отклика. Но отчет точечный работает быстро. Только по ссылочной сущности.
|
|||
99
Buster007
12.02.18
✎
16:52
|
(92) подскажи "Ок, для быстрого поиска я юзаю хэш-ключи, удобно многомерные сущности создавать, эти механизмы ускорили проведение расчета себестоимости с 30 до 5 минут" Что за расчет себестоимости? Что за сущности ты объединил?
|
|||
100
Tateossian
12.02.18
✎
16:53
|
Почему я хочу такое - да потому что у JVM есть и работает это круто. .bin выгрузка занимает десяток-другой байт. Это не прожорливый xml. И потом его можно на другой виртуальной машине распаковать.
|
|||
101
Tateossian
12.02.18
✎
17:03
|
(99) Смотри, в УПП какой кусок кода есть.
|
|||
102
Tateossian
12.02.18
✎
17:07
|
(101)
Процедура РассчитатьСписаниеПоСредней(ТаблицаТоваров, ДатаНач, ДатаКон, СтруктураДопПараметров) // Основное допущение данного метода - игнорирование замкнутой цепочки перемещений между состояниями ("холостого хода"): // считаем, что если товар в ходе перемещений снова попал в исходное состояние, то он как бы не перемещался, // это движение можно исключить из общего оборота, а стоимость движения принять равной 0. Цепочки перемещений // таким образом размыкаются, что позволяет рассчитать стоимости движений, начиная от конца цепочки. // Получим все состояния для товара, которые он принимал за период в виде таблицы // --------------------------------------------------------------------------------------------------------------------------------- // |Состояние 1 (Источник) |Состояние 2 (Приемник)| Перемещаемое количество| Стоимость (нужна для упрощения последующей корректировки) // Последовательно обходя состояния, выделим контуры (пути, начала и концы которых совпадают) // В каждом контуре найдем количество, которое совершило перемещение по замкнутому кругу ("холостой ход"), // и уменьшим каждое движение из контура на данное количество. // Будем выбирать другие состояния для получения всех контуров и применим к ним то же правило. // После нахождения контуров в графах перемещений и сокращения "холостого хода" получаем совокупность разомкнутых // путей перехода товара между состояниями (остовные деревья). Внутри каждой такой цепочки выполняем расчет. // Важно: в общем случае результат сокращения зависит от последовательности обхода контуров, поэтому // для повторяемости результата она должна подчиняться какому-либо правилу (например, чтобы сводные перемещения // упорядочивались по возрастанию даты первого перемещения) // Получим таблицу перемещений, содержащую суммарные перемещения между состояниями // Получаемая таблица должна содержать колонку "Количество", "Стоимость" и колонки, описывающие старое и новое состояние, // причем имена колонок нового состояния заканчиваются на ПрефиксПараметровНовогоСостояния ПрефиксПараметровНовогоСостояния="_НовоеСостояние"; Таб = ПолучитьТаблицуПеремещений(ТаблицаТоваров, ДатаНач, ДатаКон, ПрефиксПараметровНовогоСостояния, СтруктураДопПараметров); СтруктураДопПараметров.Вставить("ТаблицаСписанныхПартийСпецодежды", ПолучитьСтруктруТаблицыСписанныхПартийСпецодежды(СтруктураДопПараметров.Учет)); //1. Приведем переданную таблицу перемещений к требуемому виду: // Таблица имеет колонки Источник, Приемник, Количество // строка таблицы соответствует перемещению из состояния 1 в состояние 2, перемещения не повторяются. // Количество колонок без ПрефиксПараметровНовогоСостояния должно быть равно количеству колонок с ПрефиксПараметровНовогоСостояния // Сформируем также структуру, которая содержит параметры состояния товара СтруктураСостояния = Новый Структура; МассивСумм = Неопределено; СтруктураДопПараметров.Свойство("МассивСумм", МассивСумм); Если ТипЗнч(МассивСумм) <> Тип("Массив") Тогда МассивСумм = Новый Массив; МассивСумм.Добавить("Стоимость"); КонецЕсли; // То же самое, но в соответствии - для удобства поиска СоотвСумм = Новый Соответствие; Для Каждого ЭлементСумм Из МассивСумм Цикл СоотвСумм.Вставить(ЭлементСумм, ЭлементСумм); КонецЦикла; Инд=0; Пока Инд< Таб.Колонки.Количество() Цикл Колонка = Таб.Колонки[Инд]; // Имя колонки не совпадает с количеством и колонками стоимости Если ВРег(Колонка.Имя) <> ВРег("Количество") Тогда // Это колонка суммы Если СоотвСумм[Колонка.Имя] <> Неопределено Тогда Инд = Инд+1; Продолжить; КонецЕсли; // Колонки, оканчивающиеся на ПрефиксПараметровНовогоСостояния - правые (новое состояние), им должны соответствовать такие же левые, оканчивающиеся на ПрефиксПараметровНовогоСостояния Если Прав(Колонка.Имя, СтрДлина(ПрефиксПараметровНовогоСостояния)) = ПрефиксПараметровНовогоСостояния Тогда ИмяСоответствующейКолонки=Лев(Колонка.Имя, СтрДлина(Колонка.Имя)-СтрДлина(ПрефиксПараметровНовогоСостояния)); Если Таб.Колонки.Найти(ИмяСоответствующейКолонки)=Неопределено Тогда Таб.Колонки.Добавить(ИмяСоответствующейКолонки, Колонка.ТипЗначения) КонецЕсли; // И наоборот, колонки, не оканчивающиеся на ПрефиксПараметровНовогоСостояния - левые (новое состояние), им должны соответствовать такие же правые, оканчивающиеся на ПрефиксПараметровНовогоСостояния Иначе ИмяСоответствующейКолонки=Колонка.Имя+ПрефиксПараметровНовогоСостояния; Если Таб.Колонки.Найти(ИмяСоответствующейКолонки)=Неопределено Тогда Таб.Колонки.Добавить(ИмяСоответствующейКолонки, Колонка.ТипЗначения) КонецЕсли; СтруктураСостояния.Вставить(Колонка.Имя); КонецЕсли; КонецЕсли; Инд=Инд+1; КонецЦикла; // В таблице перемещений заменим параметры состояний индексами состояний, сами параметры будут храниться в СоотвПараметровСостояний //*15.01.2017 ******** 1456 { //Таб.Колонки.Добавить("Источник", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(9,0))); //Таб.Колонки.Добавить("Приемник", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(9,0))); Таб.Колонки.Добавить("Источник", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(9,0, ДопустимыйЗнак.Неотрицательный))); Таб.Колонки.Добавить("Приемник", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(9,0, ДопустимыйЗнак.Неотрицательный))); //**15.01.2017 ******** 1456 } СоотвПараметровСостояний = Новый Соответствие; //*15.01.2017 ******** 1456 { _СоотвПараметровСостояний = Новый Соответствие; _СоответствиеНумератор = Новый Соответствие; Для Каждого Строка Из Таб Цикл Хеширование = Новый ХешированиеДанных(ХешФункция.SHA256); Для Каждого Элемент Из СтруктураСостояния Цикл Если Элемент.Ключ = "ВременнаяРазница" или Элемент.Ключ = "ПостояннаяРазница" тогда Продолжить; КонецЕсли; Если ОбщегоНазначения.ЭтоСсылка(ТипЗнч(Строка[Элемент.Ключ])) Тогда Хеширование.Добавить(ИдентификаторСсылки(Строка[Элемент.Ключ])); Иначе Хеширование.Добавить(XMLСтрока(Строка[Элемент.Ключ])); КонецЕсли; КонецЦикла; Хэш = Хеширование.ХешСумма; Если _СоотвПараметровСостояний.Получить(Хэш) = Неопределено Тогда ИндексСостояния = _СоотвПараметровСостояний.Количество(); _СоответствиеНумератор.Вставить(Хэш, ИндексСостояния); _СоотвПараметровСостояний.Вставить(Хэш, Строка); СтрСост = Новый Структура; Для Каждого Элемент Из СтруктураСостояния Цикл Если Элемент.Ключ = "ВременнаяРазница" или Элемент.Ключ = "ПостояннаяРазница" тогда Продолжить; КонецЕсли; СтрСост.Вставить(Элемент.Ключ, Строка[Элемент.Ключ]); КонецЦикла; СоотвПараметровСостояний.Вставить(ИндексСостояния, СтрСост); Иначе ИндексСостояния = _СоответствиеНумератор.Получить(Хэш); КонецЕсли; Строка.Источник = ИндексСостояния; Хеширование = Новый ХешированиеДанных(ХешФункция.SHA256); Для Каждого Элемент Из СтруктураСостояния Цикл Если Элемент.Ключ = "ВременнаяРазница" или Элемент.Ключ = "ПостояннаяРазница" тогда Продолжить; КонецЕсли; Если ОбщегоНазначения.ЭтоСсылка(ТипЗнч(Строка[Элемент.Ключ+ПрефиксПараметровНовогоСостояния])) Тогда Хеширование.Добавить(ИдентификаторСсылки(Строка[Элемент.Ключ+ПрефиксПараметровНовогоСостояния])); Иначе Хеширование.Добавить(XMLСтрока(Строка[Элемент.Ключ+ПрефиксПараметровНовогоСостояния])); КонецЕсли; КонецЦикла; Хэш = Хеширование.ХешСумма; Если _СоотвПараметровСостояний.Получить(Хэш) = Неопределено Тогда ИндексСостояния = _СоотвПараметровСостояний.Количество(); _СоответствиеНумератор.Вставить(Хэш, ИндексСостояния); _СоотвПараметровСостояний.Вставить(Хэш, Строка); СтрСост = Новый Структура; Для Каждого Элемент Из СтруктураСостояния Цикл Если Элемент.Ключ = "ВременнаяРазница" или Элемент.Ключ = "ПостояннаяРазница" тогда Продолжить; КонецЕсли; СтрСост.Вставить(Элемент.Ключ, Строка[Элемент.Ключ+ПрефиксПараметровНовогоСостояния]); КонецЦикла; СоотвПараметровСостояний.Вставить(ИндексСостояния, СтрСост); Иначе ИндексСостояния = _СоответствиеНумератор.Получить(Хэш); КонецЕсли; Строка.Приемник = ИндексСостояния; КонецЦикла; //**15.01.2017 ******** 1456 } ////Для Каждого Строка Из Таб Цикл // поиск выплняется полным перебором //// //// // Состояния-источники //// // Найдем состояние в соответсвии //// НайденоСостояние=Ложь; //// Для Каждого ЭлементСостояние Из СоотвПараметровСостояний Цикл //// //// НайденоСостояние=Истина; //// Для Каждого Элемент Из СтруктураСостояния Цикл //// //// Если Элемент.Ключ = "ВременнаяРазница" или Элемент.Ключ = "ПостояннаяРазница" тогда //// Продолжить; //// КонецЕсли; //// Если НЕ (ЭлементСостояние.Значение[Элемент.Ключ] = Строка[Элемент.Ключ]) Тогда //// //// НайденоСостояние = Ложь; // состояния различны //// //// Прервать; // дальше можно не проверять //// КонецЕсли; //// КонецЦикла; //// //// Если НайденоСостояние Тогда //// Прервать; //// КонецЕсли; //// КонецЦикла; //// //// Если НайденоСостояние Тогда //// ИндексСостояния = ЭлементСостояние.Ключ; //// Иначе //// // Переносим в соответствие //// СтрСост = Новый Структура; //// Для Каждого Элемент Из СтруктураСостояния Цикл //// Если Элемент.Ключ = "ВременнаяРазница" или Элемент.Ключ = "ПостояннаяРазница" тогда //// Продолжить; //// КонецЕсли; //// СтрСост.Вставить(Элемент.Ключ, Строка[Элемент.Ключ]); //// КонецЦикла; //// //// ИндексСостояния = СоотвПараметровСостояний.Количество(); //// СоотвПараметровСостояний.Вставить(ИндексСостояния, СтрСост); //// КонецЕсли; //// //// // Оставим в таблице ссылку на состояние //// Строка.Источник = ИндексСостояния; //// //// //// // То же самое для состояний-приемников //// // Найдем состояние в соответсвии //// НайденоСостояние=Ложь; //// Для Каждого ЭлементСостояние Из СоотвПараметровСостояний Цикл //// //// НайденоСостояние=Истина; //// Для Каждого Элемент Из СтруктураСостояния Цикл //// //// Если Элемент.Ключ = "ВременнаяРазница" или Элемент.Ключ = "ПостояннаяРазница" тогда //// Продолжить; //// КонецЕсли; //// //// Если НЕ (ЭлементСостояние.Значение[Элемент.Ключ] = Строка[Элемент.Ключ+ПрефиксПараметровНовогоСостояния]) Тогда //// //// НайденоСостояние = Ложь; // состояния различны //// //// Прервать; // дальше можно не проверять //// КонецЕсли; //// КонецЦикла; //// //// Если НайденоСостояние Тогда //// Прервать; //// КонецЕсли; //// КонецЦикла; //// //// Если НайденоСостояние Тогда //// ИндексСостояния = ЭлементСостояние.Ключ; //// Иначе //// // Переносим в соответствие //// СтрСост = Новый Структура; //// Для Каждого Элемент Из СтруктураСостояния Цикл //// СтрСост.Вставить(Элемент.Ключ, Строка[Элемент.Ключ+ПрефиксПараметровНовогоСостояния]); //// КонецЦикла; //// //// ИндексСостояния = СоотвПараметровСостояний.Количество(); //// СоотвПараметровСостояний.Вставить(ИндексСостояния, СтрСост); //// КонецЕсли; //// //// // Оставим в таблице ссылку на состояние //// Строка.Приемник = ИндексСостояния; //// ////КонецЦикла; // "Свернем" встречные перемещения: вместо двух перемещений типа 1->2 и 2->1 оставим одно // с количеством |Кол12 - Кол21| в направлении большего перемещения. // Проведем следующее преобразование: повернем пары так, чтобы количество перемещения стало положительным Для Каждого Строка Из Таб Цикл Если Строка.Количество<0 Тогда Буф=Строка.Приемник; Строка.Приемник = Строка.Источник; Строка.Источник = Буф; Строка.Количество = - Строка.Количество; Для Каждого КолСумма Из МассивСумм Цикл Строка[КолСумма] = - Строка[КолСумма]; КонецЦикла; КонецЕсли; КонецЦикла; // "Свертка" встречных перемещений Инд=0; КолВо = Таб.Количество(); //*15.01.2017 ******** 1456 { МИсточник = Новый ФиксированныйМассив(Таб.ВыгрузитьКолонку("Источник")); МПриемник = Новый ФиксированныйМассив(Таб.ВыгрузитьКолонку("Приемник")); МассивТаб = Новый Массив; Для Каждого Строка Из Таб Цикл МассивТаб.Вставить(Таб.Индекс(Строка), Строка); КонецЦикла; ФиксМассив = Новый ФиксированныйМассив(МассивТаб); //**15.01.2017 ********1456 } Пока Инд<КолВо Цикл Строка = ФиксМассив[Инд]; Инд2 = Инд+1; Пока Инд2<КолВо Цикл //*16.01.2017 ******** 1456 { Строка2 = ФиксМассив[Инд2]; //Строка = Таб[Инд]; //**16.01.2017 ********1456 } // Если найдено соответствующее встречное перемещение //*15.01.2017 ******** 1456 { //Если Строка.Источник = Строка2.Приемник // И Строка.Приемник = Строка2.Источник Тогда Если МИсточник[Инд] = МПриемник[Инд2] И МПриемник[Инд] = МИсточник[Инд2] Тогда //**15.01.2017 ******** 1456 } Если Строка.Количество>Строка2.Количество Тогда УменьшитьНаКоличество = Строка2.Количество; Иначе УменьшитьНаКоличество = Строка.Количество; КонецЕсли; Строка.Количество = Строка.Количество - УменьшитьНаКоличество; Строка2.Количество = Строка2.Количество - УменьшитьНаКоличество; Для Каждого КолСумма Из МассивСумм Цикл Если Строка.Количество>Строка2.Количество Тогда УменьшитьНаСтоимость = Строка2[КолСумма]; Иначе УменьшитьНаСтоимость = Строка[КолСумма]; КонецЕсли; // То же самое - со стоимостью Строка[КолСумма] = Строка[КолСумма] - УменьшитьНаСтоимость; Строка2[КолСумма] = Строка2[КолСумма] - УменьшитьНаСтоимость; КонецЦикла; // На этом обход можно прервать: быть не более одной пары встречных перемещений Прервать; Иначе Инд2 = Инд2+1; КонецЕсли; КонецЦикла; Инд = Инд+1; КонецЦикла; // Удалим обнулившиеся строки // Удаляем только строки со всеми нулевыми суммами и нулевым количеством КолВо = Таб.Количество(); Инд=0; Пока Инд<КолВо Цикл Строка = Таб[Инд]; НеНужноУдалять = Строка.Количество<>0; Если Не НеНужноУдалять Тогда Для Каждого КолСумма Из МассивСумм Цикл НеНужноУдалять = НеНужноУдалять Или Строка[КолСумма]<>0; КонецЦикла; КонецЕсли; Если Не НеНужноУдалять Тогда Таб.Удалить(Строка); КолВо = КолВо-1; Иначе Инд=Инд+1; КонецЕсли; КонецЦикла; // Получили таблицу перемещений в требуемом формате ТаблицаПеремещений = Таб; // Таблица перемещений содержит несколько несвязанных частей, относящихся к отдельным партиям - строкам таблицы ТаблицаТоваров // Обработка перемещений: разрыв контуров // Получим наборы смежных вершин для каждой вершины // Соотв СмежныеВершины Вершина, СмежныеВершины Источники = Новый Соответствие; Приемники = Новый Соответствие; МассивНачалДеревьев = Новый Массив; Для Каждого Строка Из ТаблицаПеремещений Цикл ПараметрыИсточника = Источники[Строка.Источник]; Если ПараметрыИсточника = Неопределено Тогда СмежныеВершины= Новый Соответствие; ПараметрыИсточника = Новый Структура("Пройден, СмежныеВершины", Ложь, СмежныеВершины); КонецЕсли; ПараметрыИсточника.СмежныеВершины.Вставить(Строка.Приемник, ТаблицаПеремещений.Индекс(Строка)); // во вложенной структуре храним смежную вершину и номер строки перемещения Источники.Вставить(Строка.Источник, ПараметрыИсточника); КонецЦикла; // Чтобы рассчитать перемещения, заменим каждый связный граф перемещений его остовным деревом // Для этого обойдем их все, найдем и разорвем все контуры по предложенному выше правилу. Для Каждого Элемент Из Источники Цикл Если НЕ Элемент.Значение.Пройден Тогда // если от вершины еще не строился контур, обрабатываем //ПройденныеВершины = Новый Соответствие; //НомерВершины = Элемент.Ключ; //ПройденныеВершины.Вставить(НомерВершины, -1); ПройденныеВершины = Новый ТаблицаЗначений; ПройденныеВершины.Колонки.Добавить("Ключ"); ПройденныеВершины.Колонки.Добавить("Значение"); НоваяСтрока = ПройденныеВершины.Добавить(); НоваяСтрока.Ключ = Элемент.Ключ; НоваяСтрока.Значение = -1; НомерВершины = Элемент.Ключ; РазорватьКонтуры(НомерВершины, Источники, ПройденныеВершины, ТаблицаПеремещений); КонецЕсли; КонецЦикла; // После этого таблица содержит незамкнутую последовательность перемещений. // Стоимость перемещений с количеством = 0 в таблице тоже должна быть приведена к 0. СтСумм = Новый Структура; // структура сумм Для Каждого Строка Из ТаблицаПеремещений Цикл Если Строка.Количество=0 Тогда Для Каждого КолСумма Из МассивСумм Цикл СтСумм.Вставить(КолСумма, -Строка[КолСумма]); КонецЦикла; ДобавитьЗаписиПоПеремещению(СоотвПараметровСостояний[Строка.Источник], СоотвПараметровСостояний[Строка.Приемник], СтСумм, СтруктураДопПараметров) Иначе Приемники.Вставить(Строка.Приемник, Строка.Приемник); КонецЕсли; КонецЦикла; // Теперь нужно выделить отдельные деревья, определить среднюю стоимость для каждого дерева, // и начиная с самого начала каждого дерева последовательно рассчитать стоимость для каждого состояния/перемещения // Найдем начало каждого дерева - его нет в приемниках _СоответствиеНачал = Новый Соответствие; Для каждого Строка Из ТаблицаПеремещений Цикл // Анализируем только ненулевые дуги Если Строка.Количество<>0 Тогда // Если источника нет среди приемников, значит это начало дерева Если Приемники[Строка.Источник]=Неопределено Тогда //*16.01.2017 ******** 1456 { //ВершинаНайдена = Ложь; // признак того, что вершина уже есть в массиве // //Для Каждого НачалоДерева Из МассивНачалДеревьев Цикл // // // Такая вершина уже имеется в списке начал // Если Строка.Источник = НачалоДерева Тогда // ВершинаНайдена = Истина; // Прервать; // КонецЕсли; //КонецЦикла; Если _СоответствиеНачал.Получить(Строка.Источник) = Неопределено Тогда _СоответствиеНачал.Вставить(Строка.Источник); МассивНачалДеревьев.Добавить(Строка.Источник); КонецЕсли; //**16.01.2017 ******** 1456 } //Если НЕ ВершинаНайдена Тогда // МассивНачалДеревьев.Добавить(Строка.Источник); //КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; // На данном этапе нужна информация о начальном состоянии и внешнем поступлении в каждую вершину // Будем использовать список вершин, для каждой из которых указаны смежные вершины - приемники и Вершины = Новый Соответствие; // здесь нам понадобится общее количество источников, приемники Для Каждого Строка Из ТаблицаПеремещений Цикл Если Строка.Количество=0 Тогда Продолжить; КонецЕсли; // Обработаем источник ПодчСтруктура = Вершины[Строка.Источник]; Если ПодчСтруктура=Неопределено Тогда ПодчСтруктура = Новый Структура("КоличествоИсточников, Приемники, КоличествоРассчитанныхВходов", 0, Новый Соответствие, 0); КонецЕсли; СтСумм = Новый Структура; // структура сумм Для Каждого КолСумма Из МассивСумм Цикл СтСумм.Вставить(КолСумма, Строка[КолСумма]); КонецЦикла; ПодчСтруктура.Приемники.Вставить(Строка.Приемник, Новый Структура("Количество, СтруктураСумм", Строка.Количество, СтСумм)); // Вместе с вершиной-приемником запоминаем количество перемещения Вершины.Вставить(Строка.Источник, ПодчСтруктура); // Обработаем приемник ПодчСтруктура = Вершины[Строка.Приемник]; Если ПодчСтруктура=Неопределено Тогда |
|||
103
Buster007
12.02.18
✎
17:14
|
а, я подумал ты как-то ускорил решение СЛУ в запросе
|
|||
104
Вафель
12.02.18
✎
17:15
|
Ну что зип архив помог?
|
|||
105
timurhv
12.02.18
✎
17:22
|
(0) Нам интересно узнать постановку задачи, при которой необходимо загружать 80гб\день и перепроводить все.
И откуда эти 80гб берутся. |
|||
106
Tateossian
12.02.18
✎
17:27
|
(103) А, у тебя РАУЗ. Это для партионки. Но у меня есть dll считающая СЛУ. делал когда то. Могу сбросить, на x86 найти не могу, надо пересобирать. На x64 есть.
ИмяВременногоФайла = КаталогВременныхФайлов() + "AddInGauss.dll"; Макет = Документы.ъъРасчетСебестоимости.ПолучитьМакет("ВК_Гаусс"); Макет.Записать(ИмяВременногоФайла); ПодключитьВнешнююКомпоненту(ИмяВременногоФайла, "VKGauss", ТипВнешнейКомпоненты.Native); ВнешКомп = Новый ("AddIn.VKGauss.AddInGaussExtension"); МассивОтветов = Новый Массив(Разрядность); ВнешКомп.СоздатьМатрицу(Разрядность); Для Инд = 0 По Разрядность-1 Цикл Для Инд2 = 0 По Разрядность-1 Цикл ВнешКомп.УстановитьЗначение(Инд, Инд2, МатрицаКоэффициентов[Инд][Инд2]); КонецЦикла; ВнешКомп.УстановитьСвободныйЧлен(Инд, СтолбецПравыхЧастей[Инд]); КонецЦикла; ВнешКомп.РешитьУравнение(); Для Инд = 0 По Разрядность-1 Цикл МассивОтветов[Инд] = ВнешКомп.ПолучитьЗначение(Инд); КонецЦикла; Возврат МассивОтветов; |
|||
107
Tateossian
12.02.18
✎
17:27
|
(103) Заполняешь коэффициенты при неизвестных, столбец свободных членов и Решить().
|
|||
108
Tateossian
12.02.18
✎
17:28
|
(105) Каждый день база должна быть перепроведена по партиям. В результате все перепроведенные регистры накопления выгружаются в такой вот документ.
|
|||
109
Вафель
12.02.18
✎
17:28
|
гаусс - это же самый медленный способ
|
|||
110
Tateossian
12.02.18
✎
17:30
|
(109) Он самый оптимальный. На cpp какая разница. Для 1С деление и обращение по индексу - это самые тяжелые операции во всем расчете(((
|
|||
111
Tateossian
12.02.18
✎
17:31
|
(104) Нет, так как нужно использовать его методы без создания файла.
(103) Куда мне выложить? |
|||
112
Tateossian
12.02.18
✎
17:36
|
Вот статейка насчет сериализации в JVM
htt ps:// habrahabr.r u/po st/60317/ |
|||
113
Buster007
12.02.18
✎
17:36
|
(111) не, компонента не интересна ) В компоненте все в разы быстрее считается, можно даже не оптимизировать практически код, как есть перенести, и уже будет прирост производительности.
|
|||
114
Tateossian
12.02.18
✎
17:39
|
(113) 1С не может в Bigdata и прочие Map&Reduce. Это приходится учитывать. Короче, не годится для сложных расчетных задач. А вообще все остальное в 1С прекрасно:)
|
|||
115
Tateossian
12.02.18
✎
17:40
|
(113) Я не вижу ничего плохого усиливать 1С приданными силами и средствами. Особенно, когда посмотрел на устройство инструментов разработчика от ТормозИТ.
|
|||
116
Вафель
12.02.18
✎
17:43
|
(111) Так на основании потока же можно
|
|||
117
Tateossian
12.02.18
✎
17:45
|
(116) Напиши, плз, как. Я не смог завести, хоть и понимаю как работают потоки.
|
|||
118
Tateossian
12.02.18
✎
17:47
|
(116) там видишь в чем проблема - вернуть ДД можно токлько в том случае, если создался ЗаписьZip файла не инициализированным. А чтобы передать объекту источник данных - можно только путь к файлу. То есть как бы он не асинхронный, этот метод. Может связку между чтением и записью зип...
|
|||
119
H A D G E H O G s
12.02.18
✎
17:47
|
(116) Нет. В поток можно записать результат, но не получить исходные данные.
|
|||
120
H A D G E H O G s
12.02.18
✎
17:48
|
Пишите в файл, чебынет?
|
|||
121
Tateossian
12.02.18
✎
17:49
|
(119) Почему, поток двунаправленный. Все зависит от того, к чему его подсоединять - к чтению или записи. Тебе нужно только спозиционироваться на начальном байте и сделать флуш буферу.
|
|||
122
H A D G E H O G s
12.02.18
✎
17:50
|
ррр, я сказал другими словами твою фразу в (118)
|
|||
123
Tateossian
12.02.18
✎
17:52
|
(120) Да это очень дорогое удовольствие I/O операции... Для каждого чиха. У меня памяти много много оперативной:) Плюс ко всему кластер на диске 64Кб, представь, если писать однокилобайтные (хоть и временные) файлы...
|
|||
124
Вафель
12.02.18
✎
17:55
|
напиши компоненту
|
|||
125
Tateossian
12.02.18
✎
17:57
|
(124) Скорее всего так и будет...
|
|||
126
Вафель
12.02.18
✎
18:00
|
можно кстати рам диск сделать и через него файлы гонять
|
|||
127
Tateossian
12.02.18
✎
18:01
|
(126) У меня база sql там. Точнее, самые hiload таблички.
|
|||
128
Вафель
12.02.18
✎
18:05
|
(127) я про (123)
|
|||
129
Tateossian
12.02.18
✎
18:14
|
(128) Я могу так решить эту проблему, но дело в том, что вообще ищу универсальное решение, будь хоть я в пределах своего продакшн сервера, или хоть на своем компе. Так как это упростит лично мне работу во многих практических случаях.
|
|||
130
Вафель
12.02.18
✎
18:15
|
(129) можно 7z или рар использовать, они могут без файлов
|
|||
131
Вафель
12.02.18
✎
18:15
|
А на сасом деле ты выбрал не правильный механизм хранения ссылок
|
|||
132
Tateossian
12.02.18
✎
18:16
|
(131) А как нужно было?
|
|||
133
Вафель
12.02.18
✎
18:17
|
Откуда у тебя ссылки такие длинные? ты что талблицы значений приводишь к строкам?
|
|||
134
Tateossian
12.02.18
✎
18:22
|
(133) Ключ записи регистра сведений без регистратора.
|
|||
135
Вафель
12.02.18
✎
18:24
|
а как 1сники сделали в своем версионировании?
|
|||
136
Tateossian
12.02.18
✎
18:31
|
(135) В хранилище лежат xml сериализованные, а измерение - ссылка на справочник или документ. Ссылка, понимаешь! А ее может не быть - удален документ, все, нет его:) Короче, не все задачи решает. В зазеркалье был пост, что они пилят платформенное версионирование. Вот это будет круто, но пока у меня даже еще конфа на совместимости:)
|
|||
137
lodger
12.02.18
✎
18:34
|
(135) сериализуют. сперва это было в xml и через темп-файл, потом json.
теперь этот жсон можно не писать в файл. (с недавних версий). |
|||
138
Вафель
12.02.18
✎
18:36
|
(136) я предлагаю посмотреть как они сделали в платформе
|
|||
139
lodger
12.02.18
✎
18:37
|
(136) "удален документ, все, нет его:)" - ну и прекрасно. ссылка превращается в текст равный её гуиду. в представлении данных остается представление полученное перед удалением.
объекта нет, а следы его существования и жизни - есть. потом .уки не отмажутся - "ой не было такого объекта, вам показалось..." |
|||
140
Вафель
12.02.18
✎
18:40
|
(139) основная проблема с регистрами, вот это я и предлагаю посмотреть в платформе. со ссылками проблемы нет
|
|||
141
Tateossian
12.02.18
✎
18:49
|
Посмотрел в последней БСП. Там фастИнфо сет. И только ссылочные типы.
// Возвращает сериализованный объект в виде двоичных данных. // // Параметры: // Объект - Любой - сериализуемый объект. // // Возвращаемое значение: // ДвоичныеДанные - сериализованный объект. Функция СериализоватьОбъект(Объект) Экспорт ЗаписьXML = Новый ЗаписьFastInfoset; ЗаписьXML.УстановитьДвоичныеДанные(); ЗаписьXML.ЗаписатьОбъявлениеXML(); ЗаписатьXML(ЗаписьXML, Объект, НазначениеТипаXML.Явное); Возврат ЗаписьXML.Закрыть(); КонецФункции Поиграл я с FastInfoSet: ЗаписьXML = Новый ЗаписьFastInfoset; ЗаписьXML.УстановитьДвоичныеДанные(); ЗаписьXML.ЗаписатьОбъявлениеXML(); ЗаписатьXML(ЗаписьXML, Объект, НазначениеТипаXML.Явное); Р = ЗаписьXML.Закрыть(); РазмерДДВБайтах = Р.Размер(); //172 байт Ы = ТиповыеОтчеты.СериализоватьОбъектXDTO(Объект); ДлинаОбычнойXMLСтроки = СтрДлина(Ы); //242 символа СтрокаДвДанных = ПолучитьHexСтрокуИзДвоичныхДанных(Р); // ДлинаСтрокиДД = СтрДлина(СтрокаДвДанных); //344симв Он действительно самый компактный формат. Но его потом записывают в хранилище. А вот если привести к строке - ровно в два раза увеличивается количество символов. А если в байтах - то 172 байтами строками хранятся в 688 байт. |
|||
142
lodger
12.02.18
✎
18:51
|
(141) а зачем дд в хекс в строку? дд записать не вариант?
|
|||
143
Tateossian
12.02.18
✎
19:00
|
(142) А как ты запросом эти ДД искать будешь?
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |