TEST_F(TestObSSTableSchema, test_add_columns)
      {
        ObSSTableSchema schema;
        ObSSTableSchemaColumnDef column_def;
        const ObSSTableSchemaColumnDef *column = NULL;
        int ret = OB_SUCCESS;

        column_def.reserved_ = 0;
        column_def.column_group_id_ = 2;
        column_def.column_name_id_ = 2;
        column_def.column_value_type_ = ObDoubleType;
        column_def.table_id_ = 1000;
        ret = schema.add_column_def(column_def);
        EXPECT_TRUE(OB_SUCCESS == ret);

        column_def.column_group_id_ = 2;
        column_def.column_name_id_ = 3;
        column_def.column_value_type_ = ObIntType;
        column_def.table_id_ = 1000;
        ret = schema.add_column_def(column_def);
        EXPECT_TRUE(OB_SUCCESS == ret);

        column_def.column_group_id_ = 3;
        column_def.column_name_id_ = 4;
        column_def.column_value_type_ = ObVarcharType;
        column_def.table_id_ = 1000;
        ret = schema.add_column_def(column_def);
        EXPECT_TRUE(OB_SUCCESS == ret);

        EXPECT_EQ(3, schema.get_column_count());

        column = schema.get_column_def(0);
        EXPECT_TRUE(NULL != column);
        EXPECT_EQ(2, (int32_t)column->column_group_id_);
        EXPECT_EQ(2, (int32_t)column->column_name_id_);
        EXPECT_EQ(ObDoubleType, column->column_value_type_);
        EXPECT_EQ(1000, (int32_t)column->table_id_);

        column = schema.get_column_def(1);
        EXPECT_EQ(2, (int32_t)column->column_group_id_);
        EXPECT_EQ(3, (int32_t)column->column_name_id_);
        EXPECT_EQ(ObIntType, column->column_value_type_);
        EXPECT_EQ(1000, (int32_t)column->table_id_);

        column = schema.get_column_def(2);
        EXPECT_EQ(3, (int32_t)column->column_group_id_);
        EXPECT_EQ(4, (int32_t)column->column_name_id_);
        EXPECT_EQ(ObVarcharType, column->column_value_type_);
        EXPECT_EQ(1000, (int32_t)column->table_id_);
      }
      TEST_F(TestObSSTableSchema, test_add_max_columns_one_table)
      {
        ObSSTableSchema schema;
        ObSSTableSchemaColumnDef column_def;
        const ObSSTableSchemaColumnDef *column = NULL;
        int ret = OB_SUCCESS;
        for (int i = 0; i < OB_MAX_COLUMN_NUMBER; ++i)
        {
          column_def.column_group_id_ = 2;
          column_def.column_name_id_ = i + 2;
          column_def.table_id_ = 1000;
          column_def.column_value_type_ = ObNullType;
          ret = schema.add_column_def(column_def);
          EXPECT_EQ(OB_SUCCESS, ret);
        }

        EXPECT_EQ(OB_MAX_COLUMN_NUMBER, schema.get_column_count());

        for (int i = 0; i < OB_MAX_COLUMN_NUMBER; ++i)
        {
          column = schema.get_column_def(i);
          EXPECT_EQ(i + 2, (int32_t)column->column_name_id_);
          EXPECT_EQ(2, (int32_t)column->column_group_id_);
          EXPECT_EQ(1000, (int32_t)column->table_id_);
          EXPECT_EQ(ObNullType, column->column_value_type_);
        }
      }
      TEST_F(TestObSSTableSchema, test_add_more_columns_than_default)
      {
        ObSSTableSchema schema;
        ObSSTableSchemaColumnDef column_def;
        const ObSSTableSchemaColumnDef *column = NULL;
        int ret = OB_SUCCESS;
        for (int i = 0; i <= DEFAULT_COLUMN_DEF_SIZE; ++i)
        {
          column_def.column_group_id_ = 2;
          column_def.column_name_id_ = i + 2;
          if (OB_MAX_COLUMN_NUMBER > i)
          {
            column_def.table_id_ = 1000;
          }
          else
          {
            column_def.table_id_ = 1001;
          }
          column_def.column_value_type_ = ObNullType;
          ret = schema.add_column_def(column_def);
          if ( DEFAULT_COLUMN_DEF_SIZE != i)
          {
            EXPECT_EQ(OB_SUCCESS, ret);
          }
          else
          {
            EXPECT_EQ(OB_ERROR, ret);
          }

        }

        EXPECT_EQ(DEFAULT_COLUMN_DEF_SIZE, schema.get_column_count());

        for (int i = 0; i < DEFAULT_COLUMN_DEF_SIZE; ++i)
        {
          column = schema.get_column_def(i);
          EXPECT_EQ(i + 2, (int32_t)column->column_name_id_);
          EXPECT_EQ(2, (int32_t)column->column_group_id_);
          if (OB_MAX_COLUMN_NUMBER > i)
          {
            EXPECT_EQ(1000, (int32_t)column->table_id_);
          }
          else
          {
            EXPECT_EQ(1001, (int32_t)column->table_id_);
          }
          EXPECT_EQ(ObNullType, column->column_value_type_);
        }
      }
      TEST_F(TestObSSTableSchema, test_get_column_groups_id)
      {
        ObSSTableSchema schema;
        ObSSTableSchemaColumnDef column_def;
        int ret = OB_SUCCESS;
        column_def.reserved_ = 0;

        for ( int table_id = 1000; table_id < 1010; ++table_id )
        {
          column_def.table_id_ = table_id;
          for ( int group_id = 1 ; group_id <= (table_id - 1000)%3 + 1; ++group_id )
          {
            column_def.column_group_id_ = static_cast<uint16_t>(group_id);
            for ( int column_id = 0; column_id < group_id; ++column_id )
            {
              column_def.column_name_id_ = column_id;
              column_def.column_value_type_ = ObIntType;
              ret = schema.add_column_def(column_def);
              EXPECT_TRUE(OB_SUCCESS == ret);
            }
          }
        }

        EXPECT_EQ(31, schema.get_column_count());

        //find an column that doesn't exist
        uint64_t find[OB_MAX_COLUMN_GROUP_NUMBER];
        int64_t size = OB_MAX_COLUMN_GROUP_NUMBER;
        uint64_t table_id = 10000;
        uint64_t group_id = 4;
        ret = schema.get_column_groups_id(table_id, group_id, find, size);
        EXPECT_EQ(OB_ERROR, ret);
        EXPECT_EQ(OB_MAX_COLUMN_GROUP_NUMBER, size);
        for ( int i = 1000; i < 1010; ++i)
        {
          for ( int ci = 0; ci < (i - 1000)%3 + 1; ++ci)
          {
            size = OB_MAX_COLUMN_GROUP_NUMBER;
            ret = schema.get_column_groups_id(i, ci, find, size);
            EXPECT_EQ(OB_SUCCESS, ret);
            EXPECT_EQ((i-1000)%3+1 - ci, size);
            for (int index = 0; index < size; ++index)
            {
              EXPECT_EQ(ci+index+1, (int)find[index]);
            }
          }
        }
      }
      TEST_F(TestObSSTableSchema, test_find_first_offset_column_group_schema)
      {
        ObSSTableSchema schema;
        ObSSTableSchemaColumnDef column_def;
        int ret = OB_SUCCESS;
        column_def.reserved_ = 0;

        for ( int table_id = 1000; table_id < 1010; ++table_id )
        {
          column_def.table_id_ = table_id;
          for ( int group_id = 1 ; group_id <= (table_id - 1000)%3 + 1; ++group_id )
          {
            column_def.column_group_id_ = static_cast<uint16_t>(group_id);
            for ( int column_id = 0; column_id < group_id; ++column_id )
            {
              column_def.column_name_id_ = column_id;
              column_def.column_value_type_ = ObIntType;
              ret = schema.add_column_def(column_def);
              EXPECT_TRUE(OB_SUCCESS == ret);
            }
          }
        }

        EXPECT_EQ(31, schema.get_column_count());

        //find an column that doesn't exist
        uint64_t table_id  = 10000;
        uint64_t column_id = 4;
        uint64_t group_id = 0;
        int64_t offset_in_table = schema.find_offset_first_column_group_schema(table_id, column_id, group_id);
        EXPECT_EQ(-1, offset_in_table);
        EXPECT_EQ(0, (int)group_id);

        for ( int i = 1000; i < 1010; ++i)
        {
           for ( int gi = 1; gi <= (i - 1000)%3+1; ++gi)
           {
             for ( int ci = 0; ci < gi; ++ci)
             {
               offset_in_table = schema.find_offset_first_column_group_schema(i, ci, group_id);
               EXPECT_EQ((int)group_id, ci + 1);
               EXPECT_EQ(offset_in_table, ci);
             }
           }
        }
      }
void generate_cg_schema(
    ObSSTableSchema& sstable_schema, const ObCellInfo** cell_infos,
    const int64_t column_group_id,
    const int64_t start_col, const int64_t end_col)
{
  ObSSTableSchemaColumnDef column_def;

  EXPECT_TRUE(NULL != cell_infos);

  uint64_t table_id = cell_infos[0][0].table_id_;

  for (int64_t i = start_col; i < end_col; ++i)
  {
    column_def.table_id_ = static_cast<uint32_t>(table_id);
    column_def.column_group_id_ = static_cast<uint16_t>(column_group_id);
    column_def.column_name_id_ = static_cast<uint16_t>(cell_infos[0][i].column_id_);
    column_def.column_value_type_ = cell_infos[0][i].value_.get_type();
    sstable_schema.add_column_def(column_def);
  }
}
      TEST_F(TestObSSTableSchema, test_get_group_schema)
      {
        ObSSTableSchema schema;
        ObSSTableSchemaColumnDef column_def;
        const ObSSTableSchemaColumnDef* def_ptr;
        int ret = OB_SUCCESS;
        column_def.reserved_ = 0;

        for ( int table_id = 1000; table_id < 1010; ++table_id )
        {
          column_def.table_id_ = table_id;
          for ( int group_id = 1 ; group_id <= (table_id - 1000)%3 + 1; ++group_id )
          {
            column_def.column_group_id_ = static_cast<uint16_t>(group_id);
            for ( int column_id = 0; column_id < group_id; ++column_id )
            {
              column_def.column_name_id_ = column_id;
              column_def.column_value_type_ = ObIntType;
              ret = schema.add_column_def(column_def);
              EXPECT_TRUE(OB_SUCCESS == ret);
            }
          }
        }

        EXPECT_EQ(31, schema.get_column_count());
        int64_t size = 0;
        for ( int i = 1000; i < 1010; ++i)
        {
          for ( int gi = 1; gi <= (i - 1000)%3+1; ++gi)
          {
            def_ptr = schema.get_group_schema(i, gi, size);
            EXPECT_EQ(gi, size);
            for ( int j = 0; j < size; ++j )
            {
              EXPECT_EQ(i, (int32_t)def_ptr->table_id_);
              EXPECT_EQ(gi, def_ptr->column_group_id_);
              def_ptr++;
            }
          }
        }
      }
int fill_sstable_schema(ObSchemaManagerV2 &mgr, const uint64_t table_id, ObSSTableSchema& sstable_schema)
{
  int ret = OB_SUCCESS;
  int32_t cols = 0;
  int32_t size = 0;
  ObSSTableSchemaColumnDef column_def;

  sstable_schema.reset();

  const ObColumnSchemaV2 *col = mgr.get_table_schema( table_id,size);

  if (NULL == col || size <= 0)
  {
    TBSYS_LOG(ERROR,"cann't find this table:%lu",table_id);
    ret = OB_ERROR;
  }
  else
  {
    for (int col_index = 0; col_index < size && OB_SUCCESS == ret; ++col_index)
    {
      memset(&column_def,0,sizeof(column_def));
      column_def.table_id_ = static_cast<uint32_t>(table_id);
      column_def.column_group_id_ = static_cast<uint16_t>((col + col_index)->get_column_group_id());
      column_def.column_name_id_ = static_cast<uint16_t>((col + col_index)->get_id());
      column_def.column_value_type_ = (col + col_index)->get_type();
      if ( (ret = sstable_schema.add_column_def(column_def)) != OB_SUCCESS )
      {
        TBSYS_LOG(ERROR,"add column_def(%u,%u,%u) failed col_index : %d",column_def.table_id_,
          column_def.column_group_id_,column_def.column_name_id_,col_index);
      }
      ++cols;
    }
  }

  if ( 0 == cols && OB_SUCCESS == ret ) //this table has moved to updateserver
  {
    ret = OB_CS_TABLE_HAS_DELETED;
  }
  return ret;
}
      TEST_F(TestObSSTableSchema, write_schema_to_disk)
      {
        ObSSTableSchema schema;
        ObSSTableSchemaColumnDef column_def;
        int ret = OB_SUCCESS;
        column_def.reserved_ = 0;

        for ( int table_id = 1000; table_id < 1010; ++table_id )
        {
          column_def.table_id_ = table_id;
          for ( int group_id = 1 ; group_id <= 10; ++group_id )
          {
            column_def.column_group_id_ = static_cast<uint16_t>(group_id);
            for ( int column_id = 0; column_id < group_id; ++column_id )
            {
              column_def.column_name_id_ = column_id;
              column_def.column_value_type_ = ObIntType;
              ret = schema.add_column_def(column_def);
              EXPECT_TRUE(OB_SUCCESS == ret);
            }
          }
        }

        EXPECT_EQ(550, schema.get_column_count());
        FileUtils filesys;
        filesys.open(schema_file_name, O_WRONLY | O_CREAT | O_TRUNC, 0644);
        int64_t buf_size = schema.get_serialize_size();
        char * serialize_buf = reinterpret_cast<char *>(malloc(buf_size));
        EXPECT_TRUE(NULL != serialize_buf);
        int64_t pos = 0;
        schema.serialize(serialize_buf, buf_size, pos);
        
        int64_t write_size = filesys.write(serialize_buf, buf_size);
        EXPECT_EQ(write_size, buf_size);
        free(serialize_buf);
        serialize_buf = NULL;
      }
      TEST_F(TestObSSTableSchema, test_serialize_and_deserialize)
      {
        ObSSTableSchema schema;
        ObSSTableSchema deserialized_schema;
        ObSSTableSchemaColumnDef column_def;
        memset(&column_def, 0, sizeof(column_def));
        const ObSSTableSchemaColumnDef *column = NULL;
        const ObSSTableSchemaColumnDef *deserialized_column = NULL;
        int64_t buf_size = (DEFAULT_COLUMN_DEF_SIZE + 1)  * sizeof(ObSSTableSchemaColumnDef)
                            + sizeof(ObSSTableSchemaHeader);
        char serialize_buf[buf_size];
        int64_t pos = 0;
        int ret = OB_SUCCESS;

        for (int i = 0; i < DEFAULT_COLUMN_DEF_SIZE; ++i)
        {
          column_def.column_group_id_ = static_cast<uint16_t>((i % 128) / 8);
          column_def.column_name_id_ = (i % 8) + 2;
          column_def.column_value_type_ = ObNullType;
          column_def.table_id_ = i / 128 + 1000;
          ret = schema.add_column_def(column_def);
          EXPECT_EQ(OB_SUCCESS, ret);
        }

        EXPECT_EQ(DEFAULT_COLUMN_DEF_SIZE, schema.get_column_count());

        for (int i = 0; i < DEFAULT_COLUMN_DEF_SIZE; ++i)
        {
          column = schema.get_column_def(i);
          EXPECT_EQ((i % 128) / 8, (int32_t)column->column_group_id_);
          EXPECT_EQ((i % 8) + 2, (int32_t)column->column_name_id_);
          EXPECT_EQ(ObNullType, column->column_value_type_);
          EXPECT_EQ(i / 128 + 1000, (int32_t)column->table_id_);
        }

        uint64_t find_id[OB_MAX_COLUMN_GROUP_NUMBER];
        uint64_t group_id_out  = OB_INVALID_ID;

        int64_t size = OB_MAX_COLUMN_GROUP_NUMBER;
        
        //TEST get table column group ids
        for(uint64_t table_id = 1000; table_id < 1100; ++table_id)
        {
          size = OB_MAX_COLUMN_GROUP_NUMBER;
          ret  = schema.get_table_column_groups_id(table_id, find_id, size);
          EXPECT_EQ(16, size);
          for(int64_t index = 0; index < size; ++index)
          {
            EXPECT_EQ(index, (int64_t)find_id[index]);
          }
        }
        
        //TEST get offset first column group schema
        int64_t offset = -1;
        for(uint64_t table_id = 1000; table_id < 1100; ++table_id)
        {
          for(uint64_t column_id = 2; column_id < 10; ++column_id)
          {
            size = OB_MAX_COLUMN_GROUP_NUMBER;
            offset  = schema.find_offset_first_column_group_schema(table_id, column_id, group_id_out);
            EXPECT_EQ(offset, (int64_t)(column_id - 2));
            EXPECT_EQ(group_id_out, (uint64_t)0);
          }
        }
        
        //TEST get column group schema
        int64_t group_size = 0;
        const ObSSTableSchemaColumnDef* def = NULL;
        for(uint64_t table_id = 1000; table_id < 1100; ++table_id)
        {
          for(uint64_t group_id = 0; group_id < 16; ++group_id)
          {
            def = schema.get_group_schema(table_id, group_id, group_size);
            EXPECT_EQ(group_size, 8);
            EXPECT_EQ(def, schema.get_column_def(static_cast<int32_t>(group_id * 8 + (table_id - 1000) * 128)));
          }
        }
        
        //TEST get column group ids 
        for(uint64_t table_id = 1000; table_id < 1100; ++table_id)
        {
          for(uint64_t column_id = 2; column_id < 10; ++column_id)
          {
            size = OB_MAX_COLUMN_GROUP_NUMBER;
            ret  = schema.get_column_groups_id(table_id, column_id, find_id, size);
            EXPECT_EQ((int)size, 16);
            for(int i = 0; i < size; ++i)
            {
              EXPECT_EQ((int)find_id[i], i);
            }
          }
        }

        schema.serialize(serialize_buf, buf_size, pos);
        pos = 0;

        deserialized_schema.deserialize(serialize_buf, buf_size, pos);

        EXPECT_EQ(schema.get_column_count(), deserialized_schema.get_column_count());
        for (int i = 0; i < DEFAULT_COLUMN_DEF_SIZE; ++i)
        {
          column = schema.get_column_def(i);
          deserialized_column = deserialized_schema.get_column_def(i);
          EXPECT_EQ((i % 128) / 8, (int32_t)column->column_group_id_);
          EXPECT_EQ((i % 8) + 2, (int32_t)column->column_name_id_);
          EXPECT_EQ(column->column_name_id_, deserialized_column->column_name_id_);
          EXPECT_EQ(ObNullType, column->column_value_type_);
          EXPECT_EQ(i / 128 + 1000, (int32_t)column->table_id_);
          EXPECT_EQ(column->column_value_type_, deserialized_column->column_value_type_);
        }
        for(uint64_t table_id = 1000; table_id < 1100; ++table_id)
        {
          size = OB_MAX_COLUMN_GROUP_NUMBER;
          ret  = deserialized_schema.get_table_column_groups_id(table_id, find_id, size);
          EXPECT_EQ(16, size);
          for(int64_t index = 0; index < size; ++index)
          {
            EXPECT_EQ(index, (int64_t)find_id[index]);
          }
        }

        offset = -1;
        group_id_out = OB_INVALID_ID;
        for(uint64_t table_id = 1000; table_id < 1100; ++table_id)
        {
          for(uint64_t column_id = 2; column_id < 10; ++column_id)
          {
            size = OB_MAX_COLUMN_GROUP_NUMBER;
            offset = deserialized_schema.find_offset_first_column_group_schema(table_id, column_id, group_id_out);
            EXPECT_EQ(offset, (int64_t)(column_id - 2));
            EXPECT_EQ(group_id_out, (uint64_t)0);
          }
        }
                 
        //TEST get column group schema
        group_size = 0;
        for(uint64_t table_id = 1000; table_id < 1100; ++table_id)
        {
          for(uint64_t group_id = 0; group_id < 16; ++group_id)
          {
            def = deserialized_schema.get_group_schema(table_id, group_id, group_size);
            EXPECT_EQ(group_size, 8);
            EXPECT_EQ(def, deserialized_schema.get_column_def(static_cast<int32_t>(group_id * 8 + (table_id - 1000) * 128)));
          }
        }
        
        //TEST get column group ids 
        for(uint64_t table_id = 1000; table_id < 1100; ++table_id)
        {
          for(uint64_t column_id = 2; column_id < 10; ++column_id)
          {
            size = OB_MAX_COLUMN_GROUP_NUMBER;
            ret  = deserialized_schema.get_column_groups_id(table_id, column_id, find_id, size);
            EXPECT_EQ((int)size, 16);
            for(int i = 0; i < size; ++i)
            {
              EXPECT_EQ((int)find_id[i], i);
            }
          }
        }
      }
      TEST_F(TestObSSTableSchema, test_add_column_def_not_in_order)
      {
        ObSSTableSchema schema;
        ObSSTableSchemaColumnDef column_def;
        const ObSSTableSchemaColumnDef *column = NULL;
        int ret = OB_SUCCESS;

        column_def.reserved_ = 0;
        column_def.column_group_id_ = 2;
        column_def.column_name_id_ = 2;
        column_def.column_value_type_ = ObDoubleType;
        column_def.table_id_ = 1000;
        ret = schema.add_column_def(column_def);
        EXPECT_TRUE(OB_SUCCESS == ret);

        //add an column def with sama
        //table_id column_group_id column_name_id with previous one
        column_def.column_group_id_ = 2;
        column_def.column_name_id_ = 2;
        column_def.column_value_type_ = ObIntType;
        column_def.table_id_ = 1000;
        ret = schema.add_column_def(column_def);
        EXPECT_TRUE(OB_ERROR == ret);

        column_def.column_group_id_ = 2;
        column_def.column_name_id_ = 3;
        column_def.column_value_type_ = ObIntType;
        column_def.table_id_ = 1000;
        ret = schema.add_column_def(column_def);
        EXPECT_TRUE(OB_SUCCESS == ret);

        //curr_table_id < pre_table_id
        column_def.column_group_id_ = 2;
        column_def.column_name_id_ = 4;
        column_def.column_value_type_ = ObIntType;
        column_def.table_id_ = 900;
        ret = schema.add_column_def(column_def);
        EXPECT_TRUE(OB_ERROR == ret);

        column_def.column_group_id_ = 3;
        column_def.column_name_id_ = 4;
        column_def.column_value_type_ = ObVarcharType;
        column_def.table_id_ = 1000;
        ret = schema.add_column_def(column_def);
        EXPECT_TRUE(OB_SUCCESS == ret);

        //curr_column_group_id < pre_column_group_id
        column_def.column_group_id_ = 2;
        column_def.column_name_id_ = 2;
        column_def.column_value_type_ = ObIntType;
        column_def.table_id_ = 1000;
        ret = schema.add_column_def(column_def);
        EXPECT_TRUE(OB_ERROR == ret);

        //curr_column_name_id < pre_column_group_id
        column_def.column_group_id_ = 3;
        column_def.column_name_id_ = 2;
        column_def.column_value_type_ = ObIntType;
        column_def.table_id_ = 1000;
        ret = schema.add_column_def(column_def);
        EXPECT_TRUE(OB_ERROR == ret);

        EXPECT_EQ(3, schema.get_column_count());

        column = schema.get_column_def(0);
        EXPECT_TRUE(NULL != column);
        EXPECT_EQ(2, (int32_t)column->column_group_id_);
        EXPECT_EQ(2, (int32_t)column->column_name_id_);
        EXPECT_EQ(ObDoubleType, column->column_value_type_);
        EXPECT_EQ(1000, (int32_t)column->table_id_);

        column = schema.get_column_def(1);
        EXPECT_EQ(2, (int32_t)column->column_group_id_);
        EXPECT_EQ(3, (int32_t)column->column_name_id_);
        EXPECT_EQ(ObIntType, column->column_value_type_);
        EXPECT_EQ(1000, (int32_t)column->table_id_);

        column = schema.get_column_def(2);
        EXPECT_EQ(3, (int32_t)column->column_group_id_);
        EXPECT_EQ(4, (int32_t)column->column_name_id_);
        EXPECT_EQ(ObVarcharType, column->column_value_type_);
        EXPECT_EQ(1000, (int32_t)column->table_id_);
      }
      void test_write_one_file()
      {
        ObSSTableSchemaColumnDef column_def;
        ObSSTableSchema schema;
        ObSSTableRow row;
        char *compressor_name = (char*)COMPRESSOR_NAME;
        ObSSTableWriter writer;
        ObString file_name(static_cast<int32_t>(strlen(sstable_path) + 1),
                      static_cast<int32_t>(strlen(sstable_path) + 1), sstable_path);
        ObString compressor(static_cast<int32_t>(strlen(compressor_name) + 1),
                            static_cast<int32_t>(strlen(compressor_name) + 1), compressor_name);
        int64_t disk_usage = 0;
        int64_t trailer_offset = 0;
        ObObj obj;
        ObObj key_obj;
        uint64_t table_id = 0;
        uint64_t column_group_id = 0;
        char value_data[1024 + 1];
        char rowkey_str[32];
        ObString row_key;
        ObRowkey key;
        char *ptr;
        int ret;
      
        // init schema
        for (int64_t i = 0; i < 5; ++i)
        {
          column_def.table_id_ = static_cast<uint32_t>(1025 + i);

          // add rowkey column
          column_def.column_group_id_ = 0;
          column_def.column_name_id_ = 1;
          column_def.column_value_type_ = ObVarcharType;
          column_def.rowkey_seq_ = 1;
          schema.add_column_def(column_def);

          for ( int j = 0; j < 10 ; ++j)
          {
            column_def.column_group_id_ = static_cast<uint16_t>(j);
            column_def.column_name_id_ = 2;
            column_def.column_value_type_ = ObDoubleType;
            column_def.rowkey_seq_ = 0;
            schema.add_column_def(column_def);
      
            column_def.column_name_id_ = 3;
            column_def.column_value_type_ = ObIntType;
            column_def.rowkey_seq_ = 0;
            schema.add_column_def(column_def);
      
            column_def.column_name_id_ = 4;
            column_def.column_value_type_ = ObVarcharType;
            column_def.rowkey_seq_ = 0;
            schema.add_column_def(column_def);
          }
        }
      
        //build data
        ptr = value_data;
        for (int64_t i = 0; i < 128; ++i) {
          memcpy(ptr, "testing ", 8);
          ptr += 8;
        }
        ObString value_str(1025, 1025, value_data);
        writer.set_dio(true);
      
        int64_t start_time = tbsys::CTimeUtil::getTime();
        // create sstable file
        if (OB_ERROR == (ret = writer.create_sstable(schema, file_name,
                                  compressor, 2)))
        {
          TBSYS_LOG(ERROR, "Failed to create sstable file: %s", sstable_path);
        }
      
        for (int64_t i = 0; i < 5000000; ++i) 
        {
          row.clear();
          table_id = i / 1000000 + 1025;
          column_group_id = i % 1000000 / 100000;
          row.set_table_id(table_id);
          row.set_column_group_id(column_group_id);
          sprintf(rowkey_str, "row_key_%08ld", i);
          row_key.assign(rowkey_str, 16);
          key_obj.set_varchar(row_key);
          key.assign(&key_obj, 1);
          row.set_rowkey(key);
      
          obj.set_double((double)i);
          row.add_obj(obj);
          obj.set_int(i);
          row.add_obj(obj);
          obj.set_varchar(value_str);
          row.add_obj(obj);
      
          if (OB_ERROR == (ret = writer.append_row(row, disk_usage)))
          {
            TBSYS_LOG(ERROR, "add row failed, i=%ld", i);
            return;
          }
        }
      
        if (OB_ERROR == (ret = writer.close_sstable(trailer_offset)))
        {
          TBSYS_LOG(ERROR, "close sstable failed ------------------");
        }
      
        printf("test_write_one_file, run_time=%ld\n", 
          tbsys::CTimeUtil::getTime() - start_time);
        //remove(sstable_path);
      }