code: func (d *Dataset) Partition(name string, shard int, sortOption *SortOption) *Dataset {
  	indexes := sortOption.Indexes()
  	if intArrayEquals(d.IsPartitionedBy, indexes) && shard == len(d.Shards) {
  		return d
  	}
  	if 1 == len(d.Shards) && shard == 1 {
  		return d
  	}
  	ret := d.partition_scatter(name, shard, indexes)
  	if shard > 1 {
  		ret = ret.partition_collect(name, shard, indexes)
  	}
  	ret.IsPartitionedBy = indexes
  	return ret
  }
docs: // hash data or by data key, return a new dataset
  // This is divided into 2 steps:
  // 1. Each record is sharded to a local shard
  // 2. The destination shard will collect its child shards and merge into one