func OpenTable(fd *os.File, mode options.FileLoadingMode, cksum []byte) (*Table, error) {
	fileInfo, err := fd.Stat()
	if err != nil {
		// It's OK to ignore fd.Close() errs in this function because we have only read
		// from the file.
		_ = fd.Close()
		return nil, y.Wrap(err)
	}

	filename := fileInfo.Name()
	id, ok := ParseFileID(filename)
	if !ok {
		_ = fd.Close()
		return nil, errors.Errorf("Invalid filename: %s", filename)
	}
	t := &Table{
		fd:          fd,
		ref:         1, // Caller is given one reference.
		id:          id,
		loadingMode: mode,
	}

	t.tableSize = int(fileInfo.Size())

	// We first load to RAM, so we can read the index and do checksum.
	if err := t.loadToRAM(); err != nil {
		return nil, err
	}
	// Enforce checksum before we read index. Otherwise, if the file was
	// truncated, we'd end up with panics in readIndex.
	if len(cksum) > 0 && !bytes.Equal(t.Checksum, cksum) {
		return nil, fmt.Errorf(
			"CHECKSUM_MISMATCH: Table checksum does not match checksum in MANIFEST."+
				" NOT including table %s. This would lead to missing data."+
				"\n  sha256 %x Expected\n  sha256 %x Found\n", filename, cksum, t.Checksum)
	}
	if err := t.readIndex(); err != nil {
		return nil, y.Wrap(err)
	}

	it := t.NewIterator(false)
	defer it.Close()
	it.Rewind()
	if it.Valid() {
		t.smallest = it.Key()
	}

	it2 := t.NewIterator(true)
	defer it2.Close()
	it2.Rewind()
	if it2.Valid() {
		t.biggest = it2.Key()
	}

	switch mode {
	case options.LoadToRAM:
		// No need to do anything. t.mmap is already filled.
	case options.MemoryMap:
		t.mmap, err = y.Mmap(fd, false, fileInfo.Size())
		if err != nil {
			_ = fd.Close()
			return nil, y.Wrapf(err, "Unable to map file")
		}
	case options.FileIO:
		t.mmap = nil
	default:
		panic(fmt.Sprintf("Invalid loading mode: %v", mode))
	}
	return t, nil
}
func OpenTable(fd *os.File, mode options.FileLoadingMode, cksum []byte) (*Table, error) {
	fileInfo, err := fd.Stat()
	if err != nil {
		// It's OK to ignore fd.Close() errs in this function because we have only read
		// from the file.
		_ = fd.Close()
		return nil, y.Wrap(err)
	}

	filename := fileInfo.Name()
	id, ok := ParseFileID(filename)
	if !ok {
		_ = fd.Close()
		return nil, errors.Errorf("Invalid filename: %s", filename)
	}
	t := &Table{
		fd:          fd,
		ref:         1, // Caller is given one reference.
		id:          id,
		loadingMode: mode,
	}

	t.tableSize = int(fileInfo.Size())

	// We first load to RAM, so we can read the index and do checksum.
	if err := t.loadToRAM(); err != nil {
		return nil, err
	}
	// Enforce checksum before we read index. Otherwise, if the file was
	// truncated, we'd end up with panics in readIndex.
	if len(cksum) > 0 && !bytes.Equal(t.Checksum, cksum) {
		return nil, fmt.Errorf(
			"CHECKSUM_MISMATCH: Table checksum does not match checksum in MANIFEST."+
				" NOT including table %s. This would lead to missing data."+
				"\n  sha256 %x Expected\n  sha256 %x Found\n", filename, cksum, t.Checksum)
	}
	if err := t.readIndex(); err != nil {
		return nil, y.Wrap(err)
	}

	it := t.NewIterator(false)
	defer it.Close()
	it.Rewind()
	if it.Valid() {
		t.smallest = it.Key()
	}

	it2 := t.NewIterator(true)
	defer it2.Close()
	it2.Rewind()
	if it2.Valid() {
		t.biggest = it2.Key()
	}

	switch mode {
	case options.LoadToRAM:
		// No need to do anything. t.mmap is already filled.
	case options.MemoryMap:
		t.mmap, err = y.Mmap(fd, false, fileInfo.Size())
		if err != nil {
			_ = fd.Close()
			return nil, y.Wrapf(err, "Unable to map file")
		}
	case options.FileIO:
		t.mmap = nil
	default:
		panic(fmt.Sprintf("Invalid loading mode: %v", mode))
	}
	return t, nil
}
// OpenTable assumes file has only one table and opens it.  Takes ownership of fd upon function
// entry.  Returns a table with one reference count on it (decrementing which may delete the file!
// -- consider t.Close() instead).  The fd has to writeable because we call Truncate on it before
// deleting.