Статьи

Кто был непослушным, кто был хорошим?

Вы когда-нибудь задумывались, как Санта может доставить праздничные подарки всем детям по всему миру? Есть 2 миллиарда детей, каждый с индивидуальным списком пожеланий, и он делает это за 24 часа. Это означает, что в среднем 43 микросекунды на ребенка, и он должен проверить, был ли каждый ребенок непослушным или хорошим.

Вам не нужно больше удивляться. Я раскрою секрет. Он использует Java 11 и современный потоковый ORM со сверхбыстрым исполнением.

Java 11 Советы

Несмотря на то, что резервная база данных Санты старая и медленная, он может анализировать данные в микросекундах с помощью стандартных потоков Java и технологии памяти в JVM. База данных Санты содержит две таблицы; Child который держит каждого ребенка в мире, и HolidayGift который определяет все предметы, доступные для производства в мастерской Санты. У ребенка может быть только одно желание, таковы правила хеширования.

Просмотр базы данных в виде потоков

Speedment — это современный ORM на основе потоков, который может просматривать таблицы реляционных баз данных как стандартные потоки Java. Как мы все знаем, подарки получают только хорошие дети, поэтому важно различать тех, кто был непослушным, и тех, кто был милым. Это легко сделать с помощью следующего кода:

1
2
3
4
var niceChildren = children.stream()
        .filter(Child.NICE.isTrue())
        .sorted(Child.COUNTRY.comparator())
        .collect(Collectors.toList());

Этот поток выдаст длинный список, содержащий только хороших детей. Чтобы Санта мог оптимизировать свой маршрут доставки, список отсортирован по стране проживания.

Присоединение ребенка и HolidayGift

Этот список кажется неполным, хотя. Как Санта следит за тем, какой подарок кому идет? Теперь
HolidayGift пригодится. Поскольку некоторые дети предоставили Санте свой список желаний, мы можем теперь объединить эти два стола вместе, чтобы составить полный список, содержащий всех хороших детей и их соответствующий подарок. Важно включать детей без какого-либо желания (они получат случайный подарок), поэтому мы делаем левое соединение.

1
2
3
4
5
var join = joinComponent
    .from(ChildManager.IDENTIFIER)
        .where(Child.NICE.isTrue())
    .leftJoinOn(HolidayGift.GIFT_ID).equal(Child.GIFT_ID)
    .build(Tuples::of);

Speedment использует шаблон компоновщика для создания объекта Join<T> который затем можно использовать снова и снова для создания потоков с элементами типа
T В этом случае он используется для соединения Child и HolidayGift . Объединение включает только дочерние элементы, которые хороши и соответствуют строкам, которые содержат одинаковое значение в полях gift_id .

Вот как Санта доставляет все посылки:

1
2
3
join.stream()
    .parallel()
    .forEach(SleighUtil::deliver);

Как видно, Санта может легко доставить все посылки с параллельными санями, которые несут олени.

Это сделает поток эффективным SQL-запросом, но, к сожалению, он не достаточно быстр, чтобы сделать это вовремя.

Использование ускорения памяти в JVM

Теперь самое интересное. Санта активирует компонент ускорения памяти в JVM в Speedment, который называется DataStore. Это делается следующим образом:

1
2
3
4
5
6
7
8
9
var santasWorkshop = new ApplicationBuilder()
    .withPassword("north-pole")
    // Activate DataStore
    .withBundle(DataStoreBundle.class)
    .build();
 
    // Load a snapshot of the database into off-heap memory
    santasWorkshop.get(DataStoreComponent.class)
        .ifPresent(DataStoreComponent::load);

Эта начальная конфигурация является единственной необходимой настройкой для приложения. Все вышеуказанные потоковые конструкции остаются неизменными. Когда приложение запускается, снимок базы данных помещается в JVM и сохраняется вне кучи. Поскольку данные хранятся вне кучи, это не повлияет на сборку мусора, а объем данных ограничен только доступной оперативной памятью. Ничто не мешает Санте загружать терабайты данных, поскольку он использует облачный сервис и может легко расширить свою оперативную память. Теперь приложение будет работать на порядок быстрее, и Санта сможет доставить все посылки вовремя.

Запустите свои собственные проекты с ускорением памяти в JVM

Если вы хотите попробовать сами, насколько быстрым может быть приложение базы данных, здесь есть инициализатор. Просто отметьте желаемый тип базы данных (Oracle, MySQL, MariaDB, PostgreSQL, Microsoft SQL Server, DB2 или AS400), и вы получите POM и шаблон приложения, автоматически сгенерированный для вас.

Если вам нужна дополнительная помощь в настройке вашего проекта, проверьте Speedment
Страница GitHub или ознакомьтесь с руководством пользователя .

Авторы

Спасибо, Юлия Густафссон и Карина Дрейфельдт за соавторство в этой статье.

Смотрите оригинальную статью здесь: кто был непослушным, кто был милым? Санта дает вам советы Java 11!

Мнения, высказанные участниками Java Code Geeks, являются их собственными.