@Override
  public void updateIndices(SegmentDirectory.Writer segmentWriter)
      throws Exception {
    Map<String, List<Operation>> columnOperationsMap = computeOperations(segmentWriter);
    if (columnOperationsMap.isEmpty()) {
      return;
    }

    for (Map.Entry<String, List<Operation>> entry : columnOperationsMap.entrySet()) {
      String column = entry.getKey();
      List<Operation> operations = entry.getValue();

      for (Operation operation : operations) {
        switch (operation) {
          case DISABLE_FORWARD_INDEX:
            // Deletion of the forward index will be handled outside the index handler to ensure that other index
            // handlers that need the forward index to construct their own indexes will have it available.
            _tmpForwardIndexColumns.add(column);
            break;
          case ENABLE_FORWARD_INDEX:
            ColumnMetadata columnMetadata = createForwardIndexIfNeeded(segmentWriter, column, false);
            if (columnMetadata.hasDictionary()) {
              if (!segmentWriter.hasIndexFor(column, StandardIndexes.dictionary())) {
                throw new IllegalStateException(String.format(
                    "Dictionary should still exist after rebuilding forward index for dictionary column: %s", column));
              }
            } else {
              if (segmentWriter.hasIndexFor(column, StandardIndexes.dictionary())) {
                throw new IllegalStateException(
                    String.format("Dictionary should not exist after rebuilding forward index for raw column: %s",
                        column));
              }
            }
            break;
          case DISABLE_DICTIONARY:
            Set<String> newForwardIndexDisabledColumns =
                FieldIndexConfigsUtil.columnsWithIndexDisabled(_fieldIndexConfigs.keySet(), StandardIndexes.forward(),
                    _fieldIndexConfigs);
            if (newForwardIndexDisabledColumns.contains(column)) {
              removeDictionaryFromForwardIndexDisabledColumn(column, segmentWriter);
              if (segmentWriter.hasIndexFor(column, StandardIndexes.dictionary())) {
                throw new IllegalStateException(
                    String.format("Dictionary should not exist after disabling dictionary for column: %s", column));
              }
            } else {
              disableDictionaryAndCreateRawForwardIndex(column, segmentWriter);
            }
            break;
          case ENABLE_DICTIONARY:
            createDictBasedForwardIndex(column, segmentWriter);
            if (!segmentWriter.hasIndexFor(column, StandardIndexes.forward())) {
              throw new IllegalStateException(String.format("Forward index was not created for column: %s", column));
            }
            break;
          case CHANGE_INDEX_COMPRESSION_TYPE:
            rewriteForwardIndexForCompressionChange(column, segmentWriter);
            break;
          default:
            throw new IllegalStateException("Unsupported operation for column " + column);
        }
      }
    }
  }
@Test
  public void testAddOtherIndexForForwardIndexDisabledColumn()
      throws Exception {
    SegmentMetadataImpl existingSegmentMetadata = new SegmentMetadataImpl(_segmentDirectory);
    SegmentDirectory segmentLocalFSDirectory =
        new SegmentLocalFSDirectory(_segmentDirectory, existingSegmentMetadata, ReadMode.mmap);
    SegmentDirectory.Writer writer = segmentLocalFSDirectory.createWriter();
    IndexLoadingConfig indexLoadingConfig = new IndexLoadingConfig(null, _tableConfig);

    Random rand = new Random();
    // Add column to range index list. Must be a numerical type.
    String column;
    do {
      column = MV_FORWARD_INDEX_DISABLED_DUPLICATES_COLUMNS.get(
          rand.nextInt(MV_FORWARD_INDEX_DISABLED_DUPLICATES_COLUMNS.size()));
    } while (!column.equals(DIM_MV_FORWARD_INDEX_DISABLED_DUPLICATES_STRING) && !column.equals(
        DIM_MV_FORWARD_INDEX_DISABLED_DUPLICATES_BYTES));
    indexLoadingConfig.addRangeIndexColumns(column);

    RangeIndexHandler rangeIndexHandler = new RangeIndexHandler(segmentLocalFSDirectory, indexLoadingConfig);
    rangeIndexHandler.updateIndices(writer);

    // Validate forward index exists before calling post cleanup
    validateIndexMap(column, true, false);

    rangeIndexHandler.postUpdateIndicesCleanup(writer);

    // Tear down before validation. Because columns.psf and index map cleanup happens at segmentDirectory.close()
    segmentLocalFSDirectory.close();

    // Validate index map including range index. Forward index should not exist, range index and dictionary should
    validateIndexMap(column, true, true);
    SegmentMetadataImpl segmentMetadata = new SegmentMetadataImpl(_segmentDirectory);
    String segmentDir = INDEX_DIR + "/" + SEGMENT_NAME + "/v3";
    File idxMapFile = new File(segmentDir, V1Constants.INDEX_MAP_FILE_NAME);
    String indexMapStr = FileUtils.readFileToString(idxMapFile, StandardCharsets.UTF_8);
    assertEquals(StringUtils.countMatches(indexMapStr, column + ".range_index" + ".startOffset"), 1, column);
    assertEquals(StringUtils.countMatches(indexMapStr, column + ".range_index" + ".size"), 1, column);

    // In column metadata, some values can change since MV columns with duplicates lose the duplicates on forward index
    // regeneration.
    ColumnMetadata metadata = existingSegmentMetadata.getColumnMetadataFor(column);
    validateMetadataProperties(column, true, 7, metadata.getCardinality(), metadata.getTotalDocs(),
        metadata.getDataType(), metadata.getFieldType(), metadata.isSorted(), metadata.isSingleValue(),
        metadata.getMaxNumberOfMultiValues(), metadata.getTotalNumberOfEntries(), metadata.isAutoGenerated(),
        metadata.getMinValue(), metadata.getMaxValue(), true);

    // Validate that expected metadata properties don't match. totalNumberOfEntries will definitely not match since
    // duplicates will be removed, but maxNumberOfMultiValues may still match if the row with max multi-values didn't
    // have any duplicates.
    segmentMetadata = new SegmentMetadataImpl(_segmentDirectory);
    ColumnMetadata columnMetadata = segmentMetadata.getColumnMetadataFor(column);
    assertNotEquals(metadata.getTotalNumberOfEntries(), columnMetadata.getTotalNumberOfEntries());
  }