code: func TreeJoin(ctx context.Context, addr Address, getter Getter, depth int) *LazyChunkReader {
  	jp := &JoinerParams{
  		ChunkerParams: ChunkerParams{
  			chunkSize: chunk.DefaultSize,
  			hashSize:  int64(len(addr)),
  		},
  		addr:   addr,
  		getter: getter,
  		depth:  depth,
  		ctx:    ctx,
  	}
  
  	return NewTreeJoiner(jp).Join(ctx)
  }
docs: /*
  	Join reconstructs original content based on a root key.
  	When joining, the caller gets returned a Lazy SectionReader, which is
  	seekable and implements on-demand fetching of chunks as and where it is read.
  	New chunks to retrieve are coming from the getter, which the caller provides.
  	If an error is encountered during joining, it appears as a reader error.
  	The SectionReader.
  	As a result, partial reads from a document are possible even if other parts
  	are corrupt or lost.
  	The chunks are not meant to be validated by the chunker when joining. This
  	is because it is left to the DPA to decide which sources are trusted.
  */