Doob 2 749 Опубликовано: 3 января, 2021 Многие разрабатывают компьютеризированные хранилища, но мало кто публикует. Захотелось мне свое доработать и опубликовать... и я его не нашел. Либо затер сохранение, либо я его писал в каком-то кастомном клиенте, который удалил. В общем, печаль-беда. Предлагаю коллективно разработать умное хранилище на транспозерах, в которое, можно загружать/выгружать предметы, не заморачиваясь с проектированием и стройкой. Вот примерная архитектура моей системы, которую восстановил по памяти. К серверу подключена сеть из транспозеров и сундуков. При первом запуске, системе надо определить и сохранить свою топологию. Для этого, пользователь выбирает сундук, через который будет происходить ввод-вывод предметов, закидывает в него предмет, который будет играть роль метки при сканировании хранилища. Запускает сканирование в терминале. Система проверяет все транспозеры и находит метку. Сундук помечается как корневой и начинается сканирование. При сканировании, система выбирает еще не помеченный сундук и перемещает туда метку. Сундук помечается и путь к нему от корня записывается в базу данных. При повторном прохождении предмета через сундук в направлении от корня, путь перезаписывается, чтобы избежать конфликта в петлях. Представление данных: Адреса транспозеров записываются в список, позиция в этом списке используется во всех операциях с транспозерами. транспозеры = { [1] = uuid_1, [2] = uuid_2, [3] = uuid_3, ... } Имена предметов хранятся в двойном словаре, это позволяет не хранить в базе полное имя предмета, а только ссылку. Полное имя выглядит так: мод:имя_предмета:мета. предметы = { [1] = идентификатор_1, [идентификатор_1] = 1, [2] = идентификатор_2, [идентификатор_2] = 2, [3] = идентификатор_3, [идентификатор_3] = 3, ... } Для каждого сундука хранятся ссылки на смежные транспозеры, это позволяет перемещать предметы в любом направлении и очень быстро обновлять информацию о содержимом, даже если кто-то залез в хранилище руками. Под нулевым индексом хранится путь от корня. сундуки = { [1] = { [0] = {транспозер_1, транспозер_4, транспозер_10, ...}, транспозер_1 = сторона_1, транспозер_2 = сторона_2, транспозер_3 = сторона_3, ... }, ... } В основной базе данных хранится информация о расположении предметов, идентификатор сундука указывает на таблицу предметов, идентификатор предмета это ссылка на словарь, он указывает на таблицу слотов сундука, в которых лежит данный предмет. база_данных = { сундук_1 = { предмет_1 = { [слот1] = количество, [слот2] = количество, [слот3] = количество, ... }, ... }, ... } Счетчик это вспомогательная таблица для визуализации в терминале и транспортировки предметов. Ссылки на предметы служат указателями на таблицу, в которой первым элементом хранится суммарное количество этого предмета в системе, а дальше следуют ссылки на сундуки, которые содержат этот предмет. (У меня эта таблица была разделена на две, но зачем не могу вспомнить) счетчик = { предмет_1 = {суммарное_количество, сундук_1, сундук_2, ...}, предмет_2 = {суммарное_количество, сундук_1, сундук_2, ...}, предмет_3 = {суммарное_количество, сундук_1, сундук_2, ...}, ... } Первый слот во всех сундуках (кроме корневого) всегда свободен, это транспортировочный слот, по которому перемещаются предметы. Алгоритм импорта предмета очень прост, система находит свободный или неполный слот, берет путь из таблицы сундуков и перекачивает предмет, командуя транспозерам записанное направление, обновляет базу данных. Для экспорта ищется предмет, если он есть в ненулевом количестве, то выбираются сундуки и слоты с требуемым суммарным количеством и по очереди в корень переносятся предметы (в обратном направлении) и обновляется база. Для принудительного обновления информации, системе достаточно просканировать сундуки и записать хранящиеся в них предметы. А вот при добавлении транспозеров или сундуков, необходимо производить ту же операцию, что и при первом запуске. База данных получается полностью реляционная, с неполной связью. Ничего лишнего, кроме ссылок не хранится, в памяти сложных операций с таблицами не производится. Последний раз тестировал больше полугода назад, кажется использовал креативную шину, так что транспозеров было больше нормы, никаких проблем с памятью не наблюдалось. 2 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
NEO 542 Опубликовано: 3 января, 2021 Можно использовать алгоритм для динамической маршрутизации, сеть сама будет перестраиваться после любых изменений. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Mihis 14 Опубликовано: 3 января, 2021 (изменено) А разве апгрейд "Контроллер инвентаря" не работает с адаптером? UPD. Не знал, что транспозером можно смотреть инвентари тоже. Изменено 3 января, 2021 пользователем Mihis Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Doob Автор темы 2 749 Опубликовано: 3 января, 2021 20 минут назад, Mihis сказал: А разве апгрейд "Контроллер инвентаря" не работает с адаптером? Работает, но адаптер не может открыть сундук под собой, тут это обсуждали. 1 час назад, NEO сказал: Можно использовать алгоритм для динамической маршрутизации, сеть сама будет перестраиваться после любых изменений. Изначально я так и хотел. Но придется считать или хранить пути для всех сундуков, от каждого к каждому. Чтобы избавиться от древовидной структуры надо придумать, как обходить кольца при поиске пути. Самое простое - не использовать двойные сундуки, но хотелось бы с ними. Если с этим разобраться, то все сундуки будут иметь один ранг и можно будет перемещать предметы в любом направлении. Собственно, идея была не только хранить предметы, но еще использовать хранилище как трубы. Можно подключить к системе любое устройство, назначить ему подпрограмму и по команде кидать в него предметы. Например, подключить печку: ставим печку к транспозеру, в программе находим ее по метке, назначаем входы и выходы, потом будет достаточно указать какой ресурс и в каком количестве на какой слот подать, а система будет распределять готовые ресурсы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
NEO 542 Опубликовано: 3 января, 2021 1 час назад, Doob сказал: Чтобы избавиться от древовидной структуры надо придумать, как обходить кольца при поиске пути. Самое простое - не использовать двойные сундуки, но хотелось бы с ними. Учитывать глубину поиска. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
whiskas 144 Опубликовано: 4 января, 2021 Как многим извесно я уже разрабатывал систему хранения с рекурсивным автокрафтом. Все работает кул и тд. Но когда приходит время к маштабирование то памяти в ОЗУ не хватало. Пришлось запилить какую не какую БД на файликах. Каждый айтем это отдельная строчка и в енм хранятся все метаданные и его расположение в всех сундуках. После того как запилил БД появились очень жёсткие проблемы с временем ожидания которую смог решить добавив индексы по количеству та название. Долгое время все работало нормально пока я не захотел к системе подключить 69 сундуков с емкостю 400 слотов каждый. После этого у меня начали падать ероры при сериализации ибо сериализация большых обьектов очень ресурсозатратна. А ерора падала на рядочек с пустыми слотами (ибо после постройки системы все слоты у меня пустые) тоесть апликуха падала по причине что 1 ров очень много занимал памяти. Эту проблему я решыл тем что переводжу индексы слотов из отдельных таблиц в 1 путем конкатинации их индексов. Тоесть вместо слотов с одинаковыми предметами и количеством к примеру слоты [1][2][3][4][5][6][9][10] я трансформировал в ["1-6,9,10"]. В некоторых случаях экономия огромезная (когда сундук пуст вместо 400 таблиц я имел только одну ["1-400"]. И сейчас вроди все работает норм но чуствую что система на пределе. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Doob Автор темы 2 749 Опубликовано: 4 января, 2021 Выглядит излишне усложненно. С внешней БД таких проблем бы не было, но и это лишнее. Хранение пустых слотов тут не самая большая проблема, там ведь производится много лишних вычислений, чтобы добыть предмет. Стоит хорошо проработать структуру данных, тогда не будет никаких утечек памяти. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
whiskas 144 Опубликовано: 4 января, 2021 (изменено) 4 часа назад, Doob сказал: Стоит хорошо проработать структуру данных, тогда не будет никаких утечек памяти. Ну да можна выгружать в разные файлы одну таблицу с ключами. И потом просто мапить по тех ключах. Тоесть получится что при загрузке будет использоват патерн FlyWeight. И получается большенство обьектов будут тежесамые. Просто сылка в таблице будет дублироватся. А при изменениях тех таблиц не изменять тужесамую а создать другую и заменить Изменено 4 января, 2021 пользователем whiskas Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ProgramCrafter 544 Опубликовано: 6 января, 2021 В 03.01.2021 в 18:29, Doob сказал: Чтобы избавиться от древовидной структуры надо придумать, как обходить кольца при поиске пути. Я сделал макет хранилища, и у меня возникла такая идея: можно каждый раз перемещать предметы в ближайший к конечному сундук, который ещё не посещён. Такой алгоритм будет работать, если в середине сети нет тупиков, в которые предмет мог бы заскочить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Taruu 30 Опубликовано: 6 января, 2021 (изменено) В 03.01.2021 в 12:53, Doob сказал: Имена предметов хранятся в двойном словаре, это позволяет не хранить в базе полное имя предмета, а только ссылку. Полное имя выглядит так: мод:имя_предмета:мета. предметы = { [1] = идентификатор_1, [идентификатор_1] = 1, [2] = идентификатор_2, [идентификатор_2] = 2, [3] = идентификатор_3, [идентификатор_3] = 3, ... } Можно ли это заменить на Database upgrade? Или фича с computerHash тут не применима? Изменено 6 января, 2021 пользователем Taruu Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
whiskas 144 Опубликовано: 6 января, 2021 11 минуту назад, Taruu сказал: Database upgrade? Ты шариш что оно делает?. Просто если заменять на него тебе прийдется их сделать +100500 ибо в 1 оч мало вещей лезет Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Mihis 14 Опубликовано: 6 января, 2021 2 минуты назад, whiskas сказал: Ты шариш что оно делает?. Просто если заменять на него тебе прийдется их сделать +100500 ибо в 1 оч мало вещей лезет Если учитывать, его [Database Upgrade] крафт и емкость, то дешевле просто писать в файл на диск или рейд. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
whiskas 144 Опубликовано: 6 января, 2021 2 минуты назад, Mihis сказал: Если учитывать, его [Database Upgrade] крафт и емкость, Да и еще прийдется делать их куча а каждый будет забирать -1 от общего количества компонентов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Taruu 30 Опубликовано: 7 января, 2021 10 часов назад, whiskas сказал: Да и еще прийдется делать их куча а каждый будет забирать -1 от общего количества компонентов. Ну тогда тут все утыкаетя в базу данных :/ Странно что никто еще не делал СУБД под opencomputers... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
NEO 542 Опубликовано: 7 января, 2021 2 часа назад, Taruu сказал: Странно что никто еще не делал СУБД под opencomputers... Довольно сложно для фана. Такого порядка задачи требуют знатной мотивации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Taruu 30 Опубликовано: 7 января, 2021 (изменено) 2 часа назад, NEO сказал: Довольно сложно для фана. Такого порядка задачи требуют знатной мотивации. Там больше проблем будет в плане написания ихмо велосипед. Хотя сделать базу на уровне sqlite было бы за глаза для майновского уровня. И больше идет вопрос как делать? SQL или свои мини костыли.... Как вариант можно попробовать упоротся и сделать хотя бы быстрый csv ридер. Уже будет хоть что то. Изменено 7 января, 2021 пользователем Taruu Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
whiskas 144 Опубликовано: 7 января, 2021 (изменено) 7 часов назад, Taruu сказал: Странно что никто еще не делал СУБД под opencomputers... Я сделал чтото подобное. Оно скорее non-sql база данных ибо релейшенов нету. Но все хранится в разных файликах и даж индексы есть для ускорения роботы. Но оно немножко недоработаное и там нужен жёсткий рефакторинг потому её нету в паблике. Изменено 7 января, 2021 пользователем whiskas Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах