From 32b3cbe8d7529c6753dd7f74770ba1cabb6b7eaf Mon Sep 17 00:00:00 2001 From: Connor Tsui Date: Mon, 9 Dec 2024 10:25:57 -0500 Subject: [PATCH] add rank by size optimization + bump sea-orm-cli This commit adds the rank by size optimization into the embedded union-find data structure of the group sets. It also bumps the version number of `sea-orm-cli` to `1.1.2`. --- optd-mvp/src/entities/fingerprint.rs | 2 +- optd-mvp/src/entities/group.rs | 3 ++- optd-mvp/src/entities/logical_children.rs | 2 +- optd-mvp/src/entities/logical_expression.rs | 2 +- optd-mvp/src/entities/mod.rs | 2 +- optd-mvp/src/entities/physical_children.rs | 2 +- optd-mvp/src/entities/physical_expression.rs | 2 +- optd-mvp/src/entities/prelude.rs | 2 +- .../src/memo/persistent/implementation.rs | 23 ++++++++++++------- .../migrator/memo/m20241127_000001_group.rs | 2 ++ 10 files changed, 26 insertions(+), 16 deletions(-) diff --git a/optd-mvp/src/entities/fingerprint.rs b/optd-mvp/src/entities/fingerprint.rs index 2ab6a7f..608ca57 100644 --- a/optd-mvp/src/entities/fingerprint.rs +++ b/optd-mvp/src/entities/fingerprint.rs @@ -1,4 +1,4 @@ -//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.0 +//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.2 use sea_orm::entity::prelude::*; diff --git a/optd-mvp/src/entities/group.rs b/optd-mvp/src/entities/group.rs index 333ab05..b5b1686 100644 --- a/optd-mvp/src/entities/group.rs +++ b/optd-mvp/src/entities/group.rs @@ -1,4 +1,4 @@ -//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.0 +//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.2 use sea_orm::entity::prelude::*; @@ -10,6 +10,7 @@ pub struct Model { pub status: i8, pub winner: Option, pub cost: Option, + pub set_size: i32, pub parent_id: Option, pub next_id: Option, } diff --git a/optd-mvp/src/entities/logical_children.rs b/optd-mvp/src/entities/logical_children.rs index a0ac39c..31e86c9 100644 --- a/optd-mvp/src/entities/logical_children.rs +++ b/optd-mvp/src/entities/logical_children.rs @@ -1,4 +1,4 @@ -//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.0 +//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.2 use sea_orm::entity::prelude::*; diff --git a/optd-mvp/src/entities/logical_expression.rs b/optd-mvp/src/entities/logical_expression.rs index 82d938f..9311776 100644 --- a/optd-mvp/src/entities/logical_expression.rs +++ b/optd-mvp/src/entities/logical_expression.rs @@ -1,4 +1,4 @@ -//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.0 +//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.2 use sea_orm::entity::prelude::*; diff --git a/optd-mvp/src/entities/mod.rs b/optd-mvp/src/entities/mod.rs index 3abd379..8bdd8f7 100644 --- a/optd-mvp/src/entities/mod.rs +++ b/optd-mvp/src/entities/mod.rs @@ -1,4 +1,4 @@ -//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.0 +//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.2 pub mod prelude; diff --git a/optd-mvp/src/entities/physical_children.rs b/optd-mvp/src/entities/physical_children.rs index e58e9ca..94859a6 100644 --- a/optd-mvp/src/entities/physical_children.rs +++ b/optd-mvp/src/entities/physical_children.rs @@ -1,4 +1,4 @@ -//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.0 +//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.2 use sea_orm::entity::prelude::*; diff --git a/optd-mvp/src/entities/physical_expression.rs b/optd-mvp/src/entities/physical_expression.rs index 4fba71e..918ac03 100644 --- a/optd-mvp/src/entities/physical_expression.rs +++ b/optd-mvp/src/entities/physical_expression.rs @@ -1,4 +1,4 @@ -//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.0 +//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.2 use sea_orm::entity::prelude::*; diff --git a/optd-mvp/src/entities/prelude.rs b/optd-mvp/src/entities/prelude.rs index 8e8deaa..1e27a2c 100644 --- a/optd-mvp/src/entities/prelude.rs +++ b/optd-mvp/src/entities/prelude.rs @@ -1,4 +1,4 @@ -//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.0 +//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.2 #![allow(unused_imports)] diff --git a/optd-mvp/src/memo/persistent/implementation.rs b/optd-mvp/src/memo/persistent/implementation.rs index 8ec6295..9ce30ce 100644 --- a/optd-mvp/src/memo/persistent/implementation.rs +++ b/optd-mvp/src/memo/persistent/implementation.rs @@ -606,6 +606,7 @@ where // The expression does not exist yet, so we need to create a new group and new expression. let group = group::ActiveModel { status: Set(0), // `GroupStatus::InProgress` status. + set_size: Set(1), ..Default::default() }; @@ -676,18 +677,24 @@ where left_group_id: GroupId, right_group_id: GroupId, ) -> OptimizerResult { - // Without a rank / size field, we have no way of determining which set is better to merge - // into the other. So we will arbitrarily choose to merge the left group into the right - // group here. If rank is added in the future, then merge the smaller set into the larger. + let mut left_root_id = self.get_root_group(left_group_id).await?; + let mut left_root = self.get_group(left_root_id).await?; + let mut left_size = left_root.set_size; + + let mut right_root_id = self.get_root_group(right_group_id).await?; + let mut right_root = self.get_group(right_root_id).await?; + let mut right_size = left_root.set_size; + + // Rank/size optimization: merge the smaller set into the larger set. + if left_size > right_size { + std::mem::swap(&mut left_root_id, &mut right_root_id); + std::mem::swap(&mut left_root, &mut right_root); + std::mem::swap(&mut left_size, &mut right_size); + } - let left_root_id = self.get_root_group(left_group_id).await?; - let left_root = self.get_group(left_root_id).await?; // A `None` next pointer means it should technically be pointing to itself. let left_next = left_root.next_id.unwrap_or(left_root_id.0); let mut active_left_root = left_root.into_active_model(); - - let right_root_id = self.get_root_group(right_group_id).await?; - let right_root = self.get_group(right_root_id).await?; // A `None` next pointer means it should technically be pointing to itself. let right_next = right_root.next_id.unwrap_or(right_root_id.0); let mut active_right_root = right_root.into_active_model(); diff --git a/optd-mvp/src/migrator/memo/m20241127_000001_group.rs b/optd-mvp/src/migrator/memo/m20241127_000001_group.rs index 59b5a09..6251b6a 100644 --- a/optd-mvp/src/migrator/memo/m20241127_000001_group.rs +++ b/optd-mvp/src/migrator/memo/m20241127_000001_group.rs @@ -83,6 +83,7 @@ pub enum Group { Status, Winner, Cost, + SetSize, ParentId, NextId, } @@ -109,6 +110,7 @@ impl MigrationTrait for Migration { .on_delete(ForeignKeyAction::SetNull) .on_update(ForeignKeyAction::Cascade), ) + .col(integer(Group::SetSize)) .col(integer_null(Group::ParentId)) .foreign_key( ForeignKey::create()