diff --git a/db/post_migrate/20250214214518_queue_backfill_software_license_policies.rb b/db/post_migrate/20250214214518_queue_backfill_software_license_policies.rb index e73f1df78bdf40a202e1ccc3f515a50a9b46a2f1..b9945f7cb7bb9e88ae5e3eac1bdab78821120106 100644 --- a/db/post_migrate/20250214214518_queue_backfill_software_license_policies.rb +++ b/db/post_migrate/20250214214518_queue_backfill_software_license_policies.rb @@ -10,18 +10,8 @@ class QueueBackfillSoftwareLicensePolicies < Gitlab::Database::Migration[2.2] BATCH_SIZE = 1000 SUB_BATCH_SIZE = 100 - def up - queue_batched_background_migration( - MIGRATION, - :software_license_policies, - :id, - job_interval: DELAY_INTERVAL, - batch_size: BATCH_SIZE, - sub_batch_size: SUB_BATCH_SIZE - ) - end + # This migration is already finalized and we are removing the software_licenses table. + def up; end - def down - delete_batched_background_migration(MIGRATION, :software_license_policies, :id, []) - end + def down; end end diff --git a/db/post_migrate/20250505171359_queue_backfill_licenses_outside_spdx_catalogue.rb b/db/post_migrate/20250505171359_queue_backfill_licenses_outside_spdx_catalogue.rb index 97f2ca342fbf82557b72a55c61b7dd4219b207a9..8cc2345f6e2cd5002f2f4ca14c110623aec4a71a 100644 --- a/db/post_migrate/20250505171359_queue_backfill_licenses_outside_spdx_catalogue.rb +++ b/db/post_migrate/20250505171359_queue_backfill_licenses_outside_spdx_catalogue.rb @@ -9,17 +9,8 @@ class QueueBackfillLicensesOutsideSpdxCatalogue < Gitlab::Database::Migration[2. BATCH_SIZE = 1000 SUB_BATCH_SIZE = 100 - def up - queue_batched_background_migration( - MIGRATION, - :software_license_policies, - :id, - batch_size: BATCH_SIZE, - sub_batch_size: SUB_BATCH_SIZE - ) - end + # This migration is already finalized and we are removing the software_licenses table. + def up; end - def down - delete_batched_background_migration(MIGRATION, :software_license_policies, :id, []) - end + def down; end end diff --git a/db/post_migrate/20251017155824_cleanup_backfill_licenses_outside_spdx_catalogue.rb b/db/post_migrate/20251017155824_cleanup_backfill_licenses_outside_spdx_catalogue.rb new file mode 100644 index 0000000000000000000000000000000000000000..994cf43f6c1a2e24e83865561cad436d8b67cd99 --- /dev/null +++ b/db/post_migrate/20251017155824_cleanup_backfill_licenses_outside_spdx_catalogue.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class CleanupBackfillLicensesOutsideSpdxCatalogue < Gitlab::Database::Migration[2.3] + MIGRATION = "BackfillLicensesOutsideSpdxCatalogue" + + restrict_gitlab_migration gitlab_schema: :gitlab_main_org + milestone '18.6' + + def up + delete_batched_background_migration(MIGRATION, :software_license_policies, :id, []) + end + + def down; end +end diff --git a/db/post_migrate/20251017155829_cleanup_backfill_software_license_policies.rb b/db/post_migrate/20251017155829_cleanup_backfill_software_license_policies.rb new file mode 100644 index 0000000000000000000000000000000000000000..b2b1c9848e665782ef9062e206f27b65310461f2 --- /dev/null +++ b/db/post_migrate/20251017155829_cleanup_backfill_software_license_policies.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class CleanupBackfillSoftwareLicensePolicies < Gitlab::Database::Migration[2.3] + MIGRATION = "BackfillSoftwareLicensePolicies" + + restrict_gitlab_migration gitlab_schema: :gitlab_main_org + milestone '18.6' + + def up + delete_batched_background_migration(MIGRATION, :software_license_policies, :id, []) + end + + def down; end +end diff --git a/db/schema_migrations/20251017155824 b/db/schema_migrations/20251017155824 new file mode 100644 index 0000000000000000000000000000000000000000..7ba114c74d27708f3c68699d74cf1413891bdf63 --- /dev/null +++ b/db/schema_migrations/20251017155824 @@ -0,0 +1 @@ +311eca4052b9b92855489272ce343e5603ed2ca00c49c85657b3575052e7f9e5 \ No newline at end of file diff --git a/db/schema_migrations/20251017155829 b/db/schema_migrations/20251017155829 new file mode 100644 index 0000000000000000000000000000000000000000..e642851760f3719904e1470f6c3464eeb7ee86ae --- /dev/null +++ b/db/schema_migrations/20251017155829 @@ -0,0 +1 @@ +7fbb82d82c60c53ff18dceb04c9caa0a21a23b761b6073a90b071bcd4304bd36 \ No newline at end of file diff --git a/ee/lib/ee/gitlab/background_migration/backfill_licenses_outside_spdx_catalogue.rb b/ee/lib/ee/gitlab/background_migration/backfill_licenses_outside_spdx_catalogue.rb deleted file mode 100644 index fde37965e35ce2f5482be135ac0a656e949db760..0000000000000000000000000000000000000000 --- a/ee/lib/ee/gitlab/background_migration/backfill_licenses_outside_spdx_catalogue.rb +++ /dev/null @@ -1,54 +0,0 @@ -# frozen_string_literal: true - -module EE - module Gitlab - module BackgroundMigration - module BackfillLicensesOutsideSpdxCatalogue - extend ActiveSupport::Concern - extend ::Gitlab::Utils::Override - - prepended do - operation_name :backfill_licenses_outside_spdx_catalogue - scope_to ->(relation) do - relation.where(software_license_spdx_identifier: nil, custom_software_license_id: nil) - .where.not(software_license_id: nil) - end - end - - class SoftwareLicensePolicy < ::ApplicationRecord - self.table_name = 'software_license_policies' - - belongs_to :software_license, -> { readonly } - end - - class SoftwareLicense < ::ApplicationRecord - self.table_name = 'software_licenses' - end - - class CustomSoftwareLicense < ::ApplicationRecord - self.table_name = 'custom_software_licenses' - end - - override :perform - def perform - each_sub_batch do |sub_batch| - SoftwareLicensePolicy.id_in(sub_batch).includes(:software_license).find_each do |software_license_policy| - software_license_name = software_license_policy.software_license.name - - custom_software_license = find_or_create_custom_software_license(software_license_name, - software_license_policy.project_id) - - software_license_policy.update!(custom_software_license_id: custom_software_license.id) - end - end - end - - def find_or_create_custom_software_license(name, project_id) - params = { name: name, project_id: project_id } - CustomSoftwareLicense.upsert(params, unique_by: [:project_id, :name]) - CustomSoftwareLicense.find_by(params) - end - end - end - end -end diff --git a/ee/lib/ee/gitlab/background_migration/backfill_software_license_policies.rb b/ee/lib/ee/gitlab/background_migration/backfill_software_license_policies.rb deleted file mode 100644 index d2b5a018240577e3dfbafb70637e35bce68ee264..0000000000000000000000000000000000000000 --- a/ee/lib/ee/gitlab/background_migration/backfill_software_license_policies.rb +++ /dev/null @@ -1,72 +0,0 @@ -# frozen_string_literal: true - -module EE - module Gitlab - module BackgroundMigration - module BackfillSoftwareLicensePolicies - extend ActiveSupport::Concern - extend ::Gitlab::Utils::Override - include ::Gitlab::Utils::StrongMemoize - - prepended do - operation_name :migrate_licenses_outside_spdx_to_custom_license - scope_to ->(relation) do - relation.where(software_license_spdx_identifier: nil) - .where(custom_software_license_id: nil) - .where.not(software_license_id: nil) - end - end - - class SoftwareLicensePolicy < ::ApplicationRecord - self.table_name = 'software_license_policies' - - belongs_to :software_license, -> { readonly } - end - - class SoftwareLicense < ::ApplicationRecord - self.table_name = 'software_licenses' - end - - class CustomSoftwareLicense < ::ApplicationRecord - self.table_name = 'custom_software_licenses' - end - - override :perform - def perform - each_sub_batch do |sub_batch| - SoftwareLicensePolicy.id_in(sub_batch).includes(:software_license).find_each do |software_license_policy| - software_license_name = software_license_policy.software_license.name - spdx_identifier = licenses_map[software_license_name] - - if spdx_identifier.present? - software_license_policy.update!(software_license_spdx_identifier: spdx_identifier) - else - custom_software_license = find_or_create_custom_software_license(software_license_name, - software_license_policy.project_id) - - software_license_policy.update!(custom_software_license_id: custom_software_license.id) - end - end - end - end - - private - - def find_or_create_custom_software_license(name, project_id) - params = { name: name, project_id: project_id } - CustomSoftwareLicense.upsert(params, unique_by: [:project_id, :name]) - CustomSoftwareLicense.find_by(params) - end - - def licenses_map - catalog_licenses = ::Gitlab::SPDX::Catalogue.latest_active_licenses - - catalog_licenses.each_with_object({}) do |license, map| - map[license.name] = license.id - end - end - strong_memoize_attr :licenses_map - end - end - end -end diff --git a/ee/spec/lib/ee/gitlab/background_migration/backfill_licenses_outside_spdx_catalogue_spec.rb b/ee/spec/lib/ee/gitlab/background_migration/backfill_licenses_outside_spdx_catalogue_spec.rb deleted file mode 100644 index af031fd71bd7c1a17a16711c8b81f0db3d44b663..0000000000000000000000000000000000000000 --- a/ee/spec/lib/ee/gitlab/background_migration/backfill_licenses_outside_spdx_catalogue_spec.rb +++ /dev/null @@ -1,155 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::BackgroundMigration::BackfillLicensesOutsideSpdxCatalogue, - feature_category: :security_policy_management, - schema: 20250505171359 do - let(:organizations) { table(:organizations) } - let(:namespaces) { table(:namespaces) } - let(:projects) { table(:projects) } - - let(:software_licenses) { table(:software_licenses) } - let(:custom_software_licenses) { table(:custom_software_licenses) } - let(:software_license_policies) { table(:software_license_policies) } - - let!(:organization) { organizations.create!(name: 'organization', path: 'organization') } - let!(:namespace) { namespaces.create!(name: 'namespace', path: 'namespace', organization_id: organization.id) } - let!(:project) do - projects.create!(namespace_id: namespace.id, project_namespace_id: namespace.id, organization_id: organization.id) - end - - subject(:perform_migration) do - described_class.new( - start_id: software_license_policies.minimum(:id), - end_id: software_license_policies.maximum(:id), - batch_table: :software_license_policies, - batch_column: :id, - sub_batch_size: 100, - pause_ms: 2.minutes, - connection: ApplicationRecord.connection - ).perform - end - - shared_examples 'does not create a new custom software license' do - it 'does not create a new custom software license' do - expect { perform_migration }.not_to change { custom_software_licenses.count } - end - end - - shared_examples 'creates a new custom software license' do - it 'creates a new custom software license' do - expect { perform_migration }.to change { custom_software_licenses.count }.by(1) - end - end - - shared_examples_for 'when the software license policy has the custom_software_license_id set' do - it_behaves_like 'does not create a new custom software license' - - it 'does not change the custom_software_license_id' do - expect { perform_migration }.not_to change { software_license_policy.reload.custom_software_license_id } - end - end - - context 'when the software license policy has the software_license_spdx_identifier set' do - let(:software_license_spdx_identifier) { 'MIT' } - let!(:mit_license) do - software_licenses.create!(name: 'MIT License', spdx_identifier: software_license_spdx_identifier) - end - - let!(:software_license_policy) do - software_license_policies.create!(project_id: project.id, software_license_id: mit_license.id, - software_license_spdx_identifier: software_license_spdx_identifier) - end - - it 'does not backfill the custom_software_license_id' do - expect(software_license_policy.custom_software_license_id).to be_nil - - perform_migration - - software_license_policy.reload - - expect(software_license_policy.custom_software_license_id).to be_nil - end - end - - context 'when the software license policy has the custom_software_license_id set' do - let(:custom_license_name) { 'Custom License' } - let!(:custom_software_license) do - custom_software_licenses.create!(name: custom_license_name, project_id: project.id) - end - - let(:custom_software_license_id) { custom_software_license.id } - - let!(:software_license_policy) do - software_license_policies.create!(project_id: project.id, - custom_software_license_id: custom_software_license_id) - end - - it_behaves_like 'when the software license policy has the custom_software_license_id set' - end - - context 'when the software license policy does not have the software_license_spdx_identifier set' do - let(:software_license_outside_spdx_name) { 'Software License Outside SPDX' } - let!(:software_license_outside_spdx) do - software_licenses.create!(name: 'Software License Outside SPDX', spdx_identifier: nil) - end - - let!(:software_license_policy) do - software_license_policies.create!(project_id: project.id, - software_license_id: software_license_outside_spdx.id, software_license_spdx_identifier: nil, - custom_software_license_id: custom_software_license_id) - end - - context 'when the software license policy has the custom_software_license_id set' do - let!(:custom_software_license) do - custom_software_licenses.create!(name: software_license_outside_spdx_name, project_id: project.id) - end - - let!(:custom_software_license_id) { custom_software_license.id } - - it_behaves_like 'when the software license policy has the custom_software_license_id set' - end - - context 'when the software license policy does not have the custom_software_license_id set' do - let(:custom_software_license_id) { nil } - - context 'when the custom_software_licenses table does not contain an entry with the same name and project_id' do - it_behaves_like 'creates a new custom software license' - - it 'backfill the custom_software_license_id' do - expect(software_license_policy.software_license_id).to eq(software_license_outside_spdx.id) - expect(software_license_policy.custom_software_license_id).to be_nil - - perform_migration - - software_license_policy.reload - custom_software_license = custom_software_licenses.last - - expect(software_license_policy.software_license_id).to eq(software_license_outside_spdx.id) - expect(software_license_policy.custom_software_license_id).to eq(custom_software_license.id) - end - end - - context 'when the custom_software_licenses table contains an entry with the same name and project_id' do - let!(:existing_custom_software_license) do - custom_software_licenses.create!(name: software_license_outside_spdx_name, project_id: project.id) - end - - it_behaves_like 'does not create a new custom software license' - - it 'backfill the custom_software_license_id with the existing custom_software_license' do - expect(software_license_policy.software_license_id).to eq(software_license_outside_spdx.id) - expect(software_license_policy.custom_software_license_id).to be_nil - - perform_migration - - software_license_policy.reload - - expect(software_license_policy.software_license_id).to eq(software_license_outside_spdx.id) - expect(software_license_policy.custom_software_license_id).to eq(existing_custom_software_license.id) - end - end - end - end -end diff --git a/ee/spec/lib/ee/gitlab/background_migration/backfill_software_license_policies_spec.rb b/ee/spec/lib/ee/gitlab/background_migration/backfill_software_license_policies_spec.rb deleted file mode 100644 index eb8d92af43b2b4e38651676a9bde6f964552afbe..0000000000000000000000000000000000000000 --- a/ee/spec/lib/ee/gitlab/background_migration/backfill_software_license_policies_spec.rb +++ /dev/null @@ -1,140 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::BackgroundMigration::BackfillSoftwareLicensePolicies, feature_category: :security_policy_management do - let(:software_licenses) { table(:software_licenses) } - let(:custom_software_licenses) { table(:custom_software_licenses) } - let(:software_license_policies) { table(:software_license_policies) } - let(:organizations) { table(:organizations) } - let(:projects) { table(:projects) } - let(:namespaces) { table(:namespaces) } - - let!(:organization) { organizations.create!(name: 'organization', path: 'organization') } - let!(:namespace) { namespaces.create!(name: 'namespace', path: 'namespace', organization_id: organization.id) } - let!(:software_license) { software_licenses.create!(name: 'MIT License', spdx_identifier: 'MIT') } - let(:software_license_id) { software_license.id } - let(:software_license_spdx_identifier) { nil } - let(:custom_software_license_id) { nil } - let!(:project) do - projects.create!(namespace_id: namespace.id, project_namespace_id: namespace.id, organization_id: organization.id) - end - - let!(:software_license_policy) do - software_license_policies.create!(project_id: project.id, - software_license_id: software_license_id, - software_license_spdx_identifier: software_license_spdx_identifier, - custom_software_license_id: custom_software_license_id) - end - - subject(:perform_migration) do - described_class.new( - start_id: software_license_policies.minimum(:id), - end_id: software_license_policies.maximum(:id), - batch_table: :software_license_policies, - batch_column: :id, - sub_batch_size: 100, - pause_ms: 2.minutes, - connection: ApplicationRecord.connection - ).perform - end - - shared_examples 'does not create custom software licenses records' do - it 'does not creates custom software licenses records' do - expect { perform_migration }.not_to change { custom_software_licenses.count } - end - end - - shared_examples 'creates a new custom software license' do - it 'creates a new custom software license' do - expect { perform_migration }.to change { custom_software_licenses.count }.by(1) - end - end - - context 'when there are software_license_policies with software_license_spdx_identifier' do - let(:software_license_spdx_identifier) { 'MIT' } - - it_behaves_like 'does not create custom software licenses records' - end - - context 'when there are software_license_policies with custom_software_license_id' do - let!(:custom_software_license) { custom_software_licenses.create!(name: 'Custom License', project_id: project.id) } - let(:software_license_id) { nil } - let(:custom_software_license_id) { custom_software_license.id } - - it_behaves_like 'does not create custom software licenses records' - end - - context <<~DESCRIPTION do - when there are software_license_policies - without software_license_spdx_identifier - and without custom_software_license_id - DESCRIPTION - context 'when the software license is in the SPDX catalog' do - it_behaves_like 'does not create custom software licenses records' - - it 'sets the software_license_spdx_identifier' do - expect { perform_migration }.to change { - software_license_policy.reload.software_license_spdx_identifier - }.from(nil).to('MIT') - end - end - - context 'when the software license is not in the SPDX catalog' do - let!(:software_license) { software_licenses.create!(name: 'Custom License') } - - shared_examples_for 'sets the custom_software_license_id' do - it 'sets the custom_software_license_id' do - expect(software_license_policy.custom_software_license_id).to be_nil - - perform_migration - - custom_software_license = custom_software_licenses.last - - expect(software_license_policy.reload.custom_software_license_id).to eq(custom_software_license.id) - end - end - - context 'when a custom_software_license with the software_license name does not exist' do - it 'does not sets the software_license_spdx_identifier' do - expect { perform_migration }.not_to change { - software_license_policy.reload.software_license_spdx_identifier - }.from(nil) - end - - it_behaves_like 'creates a new custom software license' - it_behaves_like 'sets the custom_software_license_id' - end - - context 'when a custom_software_license with the software_license name exist' do - let!(:custom_software_license) do - custom_software_licenses.create!(name: 'Custom License', project_id: project_id) - end - - context 'when the custom_software_license is associated to another project' do - let!(:other_organization) { organizations.create!(name: 'other organization', path: 'other organization') } - let!(:other_namespace) do - namespaces.create!(name: 'other namespace', path: 'other namespace', organization_id: organization.id) - end - - let!(:other_project) do - projects.create!(namespace_id: other_namespace.id, project_namespace_id: other_namespace.id, - organization_id: other_organization.id) - end - - let(:project_id) { other_project.id } - - it_behaves_like 'creates a new custom software license' - it_behaves_like 'sets the custom_software_license_id' - end - - context 'when the custom_software_license is associated to the same project' do - let(:project_id) { project.id } - - it_behaves_like 'does not create custom software licenses records' - it_behaves_like 'sets the custom_software_license_id' - end - end - end - end -end diff --git a/lib/gitlab/background_migration/backfill_licenses_outside_spdx_catalogue.rb b/lib/gitlab/background_migration/backfill_licenses_outside_spdx_catalogue.rb index 94c3a32f5b75fc54718be5dccf3574192cc922d4..a2736264ab25137effe2eff6582cdb944c98ffcc 100644 --- a/lib/gitlab/background_migration/backfill_licenses_outside_spdx_catalogue.rb +++ b/lib/gitlab/background_migration/backfill_licenses_outside_spdx_catalogue.rb @@ -9,5 +9,3 @@ def perform; end end end end - -Gitlab::BackgroundMigration::BackfillLicensesOutsideSpdxCatalogue.prepend_mod diff --git a/lib/gitlab/background_migration/backfill_software_license_policies.rb b/lib/gitlab/background_migration/backfill_software_license_policies.rb index 7fbd1e12860faf9bd7eae842b74dd33a1a69888c..7c6973af4818d2df71d502a690e0ae26acbc70e3 100644 --- a/lib/gitlab/background_migration/backfill_software_license_policies.rb +++ b/lib/gitlab/background_migration/backfill_software_license_policies.rb @@ -9,5 +9,3 @@ def perform; end end end end - -Gitlab::BackgroundMigration::BackfillSoftwareLicensePolicies.prepend_mod diff --git a/spec/lib/gitlab/database/migration_helpers/restrict_gitlab_schema_spec.rb b/spec/lib/gitlab/database/migration_helpers/restrict_gitlab_schema_spec.rb index 2e4611e3f6aa9248764c5d88a37d7ca133689dff..89778ef8acc16df45c339fbafbaf5d8d0e827f3d 100644 --- a/spec/lib/gitlab/database/migration_helpers/restrict_gitlab_schema_spec.rb +++ b/spec/lib/gitlab/database/migration_helpers/restrict_gitlab_schema_spec.rb @@ -235,23 +235,23 @@ def down } } }, - "does insert into software_licenses" => { + "does insert into features" => { migration: ->(klass) do def up - software_license_class.create!(name: 'aaa') + features_class.create!(key: 'aaa') end def down - software_license_class.where(name: 'aaa').delete_all + features_class.where(key: 'aaa').delete_all end - def software_license_class + def features_class Class.new(Gitlab::Database::Migration[2.0]::MigrationRecord) do - self.table_name = 'software_licenses' + self.table_name = 'features' end end end, - query_matcher: /INSERT INTO "software_licenses"/, + query_matcher: /INSERT INTO "features"/, expected: { no_gitlab_schema: { main: :dml_not_allowed, diff --git a/spec/migrations/20250214214518_queue_backfill_software_license_policies_spec.rb b/spec/migrations/20250214214518_queue_backfill_software_license_policies_spec.rb deleted file mode 100644 index 2cbe813d6f9f81a951f55e0a1877d37a7759b9e3..0000000000000000000000000000000000000000 --- a/spec/migrations/20250214214518_queue_backfill_software_license_policies_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe QueueBackfillSoftwareLicensePolicies, migration: :gitlab_main_org, feature_category: :security_policy_management do - let!(:batched_migration) { described_class::MIGRATION } - - it 'schedules a new batched migration' do - reversible_migration do |migration| - migration.before -> { - expect(batched_migration).not_to have_scheduled_batched_migration - } - - migration.after -> { - expect(batched_migration).to have_scheduled_batched_migration( - gitlab_schema: :gitlab_main, - table_name: :software_license_policies, - column_name: :id, - interval: described_class::DELAY_INTERVAL, - batch_size: described_class::BATCH_SIZE, - sub_batch_size: described_class::SUB_BATCH_SIZE - ) - } - end - end -end diff --git a/spec/migrations/20250505171359_queue_backfill_licenses_outside_spdx_catalogue_spec.rb b/spec/migrations/20250505171359_queue_backfill_licenses_outside_spdx_catalogue_spec.rb deleted file mode 100644 index 1dc8dca82588e0dded437bcbc154f8ae431179ec..0000000000000000000000000000000000000000 --- a/spec/migrations/20250505171359_queue_backfill_licenses_outside_spdx_catalogue_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' -require_migration! - -RSpec.describe QueueBackfillLicensesOutsideSpdxCatalogue, migration: :gitlab_main_org, feature_category: :security_policy_management do - let!(:batched_migration) { described_class::MIGRATION } - - it 'schedules a new batched migration' do - reversible_migration do |migration| - migration.before -> { - expect(batched_migration).not_to have_scheduled_batched_migration - } - - migration.after -> { - expect(batched_migration).to have_scheduled_batched_migration( - gitlab_schema: :gitlab_main, - table_name: :software_license_policies, - column_name: :id, - batch_size: described_class::BATCH_SIZE, - sub_batch_size: described_class::SUB_BATCH_SIZE - ) - } - end - end -end