func (n *Node) nextHierarchyLevel(path, parent string) (string, bool) {
	baseName := strings.TrimPrefix(path, parent)
	hierarchies := strings.SplitN(baseName, string(filepath.Separator), 2)
	return filepath.Clean(hierarchies[0]), len(hierarchies) >= 2
}
Returns next hierarchy level and tells if we have more hierarchies
path "/foo", parent "/" => "foo"
package fs
import (
	"context"
	"hash/fnv"
	"os/user"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
	"syscall"
	"time"
	"github.com/hanwen/go-fuse/v2/fs"
	"github.com/hanwen/go-fuse/v2/fuse"
	"github.com/polyrabbit/etcdfs/etcd"
	"github.com/sirupsen/logrus"
	v3 "go.etcd.io/etcd/v3/clientv3"
)
var uid, gid uint32
func init() {
	u, err := user.Current()
	if err != nil {
		panic(err)
	}
	uid32, _ := strconv.ParseUint(u.Uid, 10, 32)
	gid32, _ := strconv.ParseUint(u.Gid, 10, 32)
	uid = uint32(uid32)
	gid = uint32(gid32)
}
type Node struct {
	fs.Inode
	client *etcd.Client
	isLeaf bool    
	path   string  
	rwMu    sync.RWMutex  
	content []byte        
}
func NewRoot(client *etcd.Client) *Node {
	return &Node{
		client: client,
		isLeaf: false,
	}
}
func (n *Node) Readdir(ctx context.Context) (fs.DirStream, syscall.Errno) {
	parent := n.resolve("")
	logrus.WithField("path", parent).Debug("Node Readdir")
	entrySet := make(map[string]fuse.DirEntry)
	opts := []v3.OpOption{v3.WithRange(v3.GetPrefixRangeEnd(parent)),
		v3.WithSort(v3.SortByKey, v3.SortAscend), v3.WithLimit(500)}
	nextGroup := parent
	for {
		keys, moreKeys, err := n.client.ListKeys(ctx, nextGroup, opts...)
		if err != nil {
			logrus.WithError(err).WithField("path", parent).Errorf("Failed to list keys from etcd")
			return nil, syscall.EIO
		}
		var lastName string
		for _, key := range keys {
			nextLevel, hasMore := n.nextHierarchyLevel(key, parent)
			lastName = nextLevel
			if _, exist := entrySet[nextLevel]; exist {
				continue
			}
			entrySet[nextLevel] = fuse.DirEntry{
				Mode: n.getMode(!hasMore),
				Name: nextLevel,
				Ino:  n.inodeHash(nextLevel),
			}
		}
		nextGroup = v3.GetPrefixRangeEnd(n.resolve(lastName))  
		if !moreKeys || len(keys) == 0 {
			break
		}
		if len(entrySet) > 1000 {
			logrus.Warn("Already fetched more than 1000 entries, skipping the rest for performance reason...")
			break
		}
	}
	entries := make([]fuse.DirEntry, 0, len(entrySet))
	for _, e := range entrySet {
		entries = append(entries, e)
	}
	return fs.NewListDirStream(entries), fs.OK
}