// pruneDirsWithLock deletes empty directories in the path walk leading to the
// key k. Typically this function is called after an Erase is made.
189863
func (d *Diskv) pruneDirsWithLock(key string) error {
	pathlist := d.transform(key).Path
	for i := range pathlist {
		dir := filepath.Join(d.BasePath, filepath.Join(pathlist[:len(pathlist)-i]...))

		// thanks to Steven Blenkinsop for this snippet
		switch fi, err := os.Stat(dir); true {
		case err != nil:
			return err
		case !fi.IsDir():
			panic(fmt.Sprintf("corrupt dirstate at %s", dir))
		}

		nlinks, err := filepath.Glob(filepath.Join(dir, "*"))
		if err != nil {
			return err
		} else if len(nlinks) > 0 {
			return nil // has subdirs -- do not prune
		}
		if err = os.Remove(dir); err != nil {
			return err
		}
	}

	return nil
}
1368878
func (s *fsCacheStore) Prune(ctx context.Context) (uint64, error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	var size uint64

	for id, snap := range s.sources {
		select {
		case <-ctx.Done():
			logrus.Debugf("Cache prune operation cancelled, pruned size: %d", size)
			// when the context is cancelled, only return current size and nil
			return size, nil
		default:
		}
		if len(snap.refs) == 0 {
			ss, err := snap.getSize(ctx)
			if err != nil {
				return size, err
			}
			if err := s.delete(id); err != nil {
				return size, errors.Wrapf(err, "failed to delete %s", id)
			}
			size += uint64(ss)
		}
	}
	return size, nil
}
147479
func (d *Diskv) cacheWithoutLock(key string, val []byte) error {
	d.mu.Lock()
	defer d.mu.Unlock()
	return d.cacheWithLock(key, val)
}
610345
func (s *State) prune() {
	if s == nil {
		return
	}

	// Filter out empty modules.
	// A module is always assumed to have a path, and it's length isn't always
	// bounds checked later on. Modules may be "emptied" during destroy, but we
	// never want to store those in the state.
	for i := 0; i < len(s.Modules); i++ {
		if s.Modules[i] == nil || len(s.Modules[i].Path) == 0 {
			s.Modules = append(s.Modules[:i], s.Modules[i+1:]...)
			i--
		}
	}

	for _, mod := range s.Modules {
		mod.prune()
	}
	if s.Remote != nil && s.Remote.Empty() {
		s.Remote = nil
	}
}
388106
func (d *Diskv) Erase(key string) error {
	pathKey := d.transform(key)
	d.mu.Lock()
	defer d.mu.Unlock()

	d.bustCacheWithLock(key)

	// erase from index
	if d.Index != nil {
		d.Index.Delete(key)
	}

	// erase from disk
	filename := d.completeFilename(pathKey)
	if s, err := os.Stat(filename); err == nil {
		if s.IsDir() {
			return errBadKey
		}
		if err = os.Remove(filename); err != nil {
			return err
		}
	} else {
		// Return err as-is so caller can do os.IsNotExist(err).
		return err
	}

	// clean up and return
	d.pruneDirsWithLock(key)
	return nil
}
170140
func (t *Tree) DeletePath(keys []string) error {
	keyLen := len(keys)
	if keyLen == 1 {
		delete(t.values, keys[0])
		return nil
	}
	tree := t.GetPath(keys[:keyLen-1])
	item := keys[keyLen-1]
	switch node := tree.(type) {
	case *Tree:
		delete(node.values, item)
		return nil
	}
	return errors.New("no such key to delete")
}
22574
func (w *Worker) Prune(ctx context.Context, ch chan client.UsageInfo, info ...client.PruneInfo) error {
	return w.CacheManager.Prune(ctx, ch, info...)
}
380283
func (s *ResourceState) prune() {
	s.Lock()
	defer s.Unlock()

	n := len(s.Deposed)
	for i := 0; i < n; i++ {
		inst := s.Deposed[i]
		if inst == nil || inst.ID == "" {
			copy(s.Deposed[i:], s.Deposed[i+1:])
			s.Deposed[n-1] = nil
			n--
			i--
		}
	}
	s.Deposed = s.Deposed[:n]

	s.Dependencies = uniqueStrings(s.Dependencies)
}
964892
func (s *Store) Prune(ctx context.Context, prefix string) error {
	prefix = s.prefix + prefix
	out.Debug(ctx, "consul.Prune(%s)", prefix)
	return s.Delete(ctx, prefix)
}
441135
func (d *Dir) Remove(nodePath string, emptyOnly bool) error {
	var currentNode os.FileInfo = d
	if nodePath == "." || nodePath == "./" || nodePath == "" {
		return fmt.Errorf("memfs.Dir.Remove: It is not possible to delete myself")
	}
	pathNodes := strings.Split(path.Clean(nodePath), "/")
	lastDirNode := len(pathNodes) - 1
	for i := 0; i < lastDirNode; i++ {
		nodeName := pathNodes[i]
		if currentNode.IsDir() != true {
			return fmt.Errorf("memfs.Dir.Remove: Node by name %v must be dir to get sub node (path %v )", currentNode.Name(), nodePath)
		}
		var dir = currentNode.(*Dir)
		newNode, err := dir.GetNode(nodeName)
		if err != nil {
			return err
		}
		currentNode = newNode
	}
	if currentNode.IsDir() != true {
		return fmt.Errorf("memfs.Dir.Remove: Node by name %v must be dir to get sub node (path %v )", currentNode.Name(), nodePath)
	}
	currentDir := currentNode.(*Dir)
	removeNodeName := pathNodes[len(pathNodes)-1]
	for key, removedNode := range currentDir.nodes {
		if removedNode.Name() != removeNodeName {
			continue
		}
		if emptyOnly && removedNode.IsDir() {
			removedDir := removedNode.(*Dir)
			if len(removedDir.nodes) != 0 {
				return fmt.Errorf("memfs.Dir.Remove: Prevent remove no empty directory %v", nodePath)
			}
		}
		currentDir.nodes = append(currentDir.nodes[:key], currentDir.nodes[key+1:]...)
		return nil
	}
	return fmt.Errorf("memfs.Dir.Remove: Con not find node to remove (by name %v)", removeNodeName)
}
411519
func (s *Store) removeEmptyParentDirectories(path string) error {
	parent := filepath.Dir(path)

	if relpath, err := filepath.Rel(s.path, parent); err != nil {
		return err
	} else if strings.HasPrefix(relpath, ".") {
		return nil
	}

	err := os.Remove(parent)
	switch {
	case err == nil:
		return s.removeEmptyParentDirectories(parent)
	case err.(*os.PathError).Err == syscall.ENOTEMPTY:
		// ignore when directory is non-empty
		return nil
	default:
		return err
	}
}
1326894
func (c *ContainerCache) Prune(liveContainers map[string]interface{}) {
	c.Lock()
	defer c.Unlock()

	for id := range c.cache {
		if _, ok := liveContainers[id]; !ok {
			delete(c.cache, id)
		}
	}
}
1209670
func DiffLocks(l1 Lock, l2 Lock) *LockDiff {
	// Default nil locks to empty locks, so that we can still generate a diff
	if l1 == nil {
		l1 = &SimpleLock{}
	}
	if l2 == nil {
		l2 = &SimpleLock{}
	}

	p1, p2 := l1.Projects(), l2.Projects()

	// Check if the slices are sorted already. If they are, we can compare
	// without copying. Otherwise, we have to copy to avoid altering the
	// original input.
	sp1, sp2 := lpsorter(p1), lpsorter(p2)
	if len(p1) > 1 && !sort.IsSorted(sp1) {
		p1 = make([]LockedProject, len(p1))
		copy(p1, l1.Projects())
		sort.Sort(lpsorter(p1))
	}
	if len(p2) > 1 && !sort.IsSorted(sp2) {
		p2 = make([]LockedProject, len(p2))
		copy(p2, l2.Projects())
		sort.Sort(lpsorter(p2))
	}

	diff := LockDiff{}

	h1 := hex.EncodeToString(l1.InputHash())
	h2 := hex.EncodeToString(l2.InputHash())
	if h1 != h2 {
		diff.HashDiff = &StringDiff{Previous: h1, Current: h2}
	}

	var i2next int
	for i1 := 0; i1 < len(p1); i1++ {
		lp1 := p1[i1]
		pr1 := lp1.pi.ProjectRoot

		var matched bool
		for i2 := i2next; i2 < len(p2); i2++ {
			lp2 := p2[i2]
			pr2 := lp2.pi.ProjectRoot

			switch strings.Compare(string(pr1), string(pr2)) {
			case 0: // Found a matching project
				matched = true
				pdiff := DiffProjects(lp1, lp2)
				if pdiff != nil {
					diff.Modify = append(diff.Modify, *pdiff)
				}
				i2next = i2 + 1 // Don't evaluate to this again
			case +1: // Found a new project
				add := buildLockedProjectDiff(lp2)
				diff.Add = append(diff.Add, add)
				i2next = i2 + 1 // Don't evaluate to this again
				continue        // Keep looking for a matching project
			case -1: // Project has been removed, handled below
				break
			}

			break // Done evaluating this project, move onto the next
		}

		if !matched {
			remove := buildLockedProjectDiff(lp1)
			diff.Remove = append(diff.Remove, remove)
		}
	}

	// Anything that still hasn't been evaluated are adds
	for i2 := i2next; i2 < len(p2); i2++ {
		lp2 := p2[i2]
		add := buildLockedProjectDiff(lp2)
		diff.Add = append(diff.Add, add)
	}

	if diff.HashDiff == nil && len(diff.Add) == 0 && len(diff.Remove) == 0 && len(diff.Modify) == 0 {
		return nil // The locks are the equivalent
	}
	return &diff
}
1236601
func (c *LockCache) RemoveByPath(filePath string) error {
	ilock := c.kv.Get(filePath)
	if lock, ok := ilock.(*Lock); ok && lock != nil {
		c.kv.Remove(lock.Path)
		// Id as key is encoded
		c.kv.Remove(c.encodeIdKey(lock.Id))
	}
	return nil
}
135525
func TrySharedKeyLock(lockDir string, key string) (*KeyLock, error) {
	return createAndLock(lockDir, key, keyLockShared|keyLockNonBlocking)
}
1340045
func (p *pruner) Prune(deleter DeploymentDeleter) error {
	deployments, err := p.resolver.Resolve()
	if err != nil {
		return err
	}
	for _, deployment := range deployments {
		if err := deleter.DeleteDeployment(deployment); err != nil {
			return err
		}
	}
	return nil
}
1191550
func (c *Etcd2Backend) LockWith(key, value string) (physical.Lock, error) {
	return &Etcd2Lock{
		kAPI:            c.kAPI,
		value:           value,
		semaphoreDirKey: c.nodePathLock(key),
	}, nil
}