// we need to keep all keys if any of them have a diff that's not ignored
351372
func (f flatAttrDiff) keepDiff(ignoreChanges map[string]bool) bool {
	for k, v := range f {
		ignore := false
		for attr := range ignoreChanges {
			if strings.HasPrefix(k, attr) {
				ignore = true
			}
		}

		if !v.Empty() && !v.NewComputed && !ignore {
			return true
		}
	}
	return false
}
717721
func (s *Section) ParentKeys() []*Key {
	var parentKeys []*Key
	sname := s.name
	for {
		if i := strings.LastIndex(sname, "."); i > -1 {
			sname = sname[:i]
			sec, err := s.f.GetSection(sname)
			if err != nil {
				continue
			}
			parentKeys = append(parentKeys, sec.Keys()...)
		} else {
			break
		}

	}
	return parentKeys
}
1254763
func (d *ResourceDiff) setDiff(key string, new interface{}, computed bool) error {
	if err := d.clear(key); err != nil {
		return err
	}

	if err := d.newWriter.WriteField(strings.Split(key, "."), new, computed); err != nil {
		return fmt.Errorf("Cannot set new diff value for key %s: %s", key, err)
	}

	d.updatedKeys[key] = true

	return nil
}
458499
func (its injectionTypes) Keys() []reflect.Type {
	types := make([]reflect.Type, len(its))
	i := 0
	for t := range its {
		types[i] = t
		i++
	}
	sort.Slice(types, func(i, j int) bool {
		return types[i].Name() < types[j].Name()
	})
	return types
}
530984
func (k *KeyBindings) DropLessEqualKeys(count int) {
	for {
		for i := 0; i < len(k.Bindings); {
			if len(k.Bindings[i].Keys) <= count {
				k.Bindings[i] = k.Bindings[len(k.Bindings)-1]
				k.Bindings = k.Bindings[:len(k.Bindings)-1]
			} else {
				i++
			}
		}
		sort.Sort(k)
		if k.parent == nil {
			break
		}
		k = k.parent.KeyBindings()
	}
}
1206770
func (neq Neq) sortedKeys() []string {
	keys := make([]string, 0, len(neq))
	for key := range neq {
		keys = append(keys, key)
	}
	sort.Strings(keys)
	return keys
}
1292710
func DropKeys(keyvals []interface{}, dropKeyValPredicate func(key, value interface{}) bool) []interface{} {
	keyvalsDropped := make([]interface{}, 0, len(keyvals))
	for i := 0; i < 2*(len(keyvals)/2); i += 2 {
		if !dropKeyValPredicate(keyvals[i], keyvals[i+1]) {
			keyvalsDropped = append(keyvalsDropped, keyvals[i], keyvals[i+1])
		}
	}
	return keyvalsDropped
}
1280175
func keysEqual(a, b []string) bool {
	if len(a) != len(b) {
		return false
	}
	a = a[:]
	b = b[:]
	sort.Strings(a)
	sort.Strings(b)
	for i := range a {
		if a[i] != b[i] {
			return false
		}
	}
	return true
}
136483
func (v *Values) Merge(key Key, other *Values) bool {
	v.lock.Lock()
	defer v.lock.Unlock()

	changed := false
	other.EachKeyValue(func(otherKey Key, value interface{}) {
		actualKey := key.Append(otherKey)
		changed = v.put(actualKey, value) || changed
	})
	return changed
}
157903
func (al HALLinks) Keys() (keys []string) {
	keys = make([]string, len(al.links))
	for i, l := range al.links {
		keys[i] = l.Name
	}
	return
}
1237863
func (p *partition) keys() [][]byte {
	p.mu.RLock()
	keys := make([][]byte, 0, len(p.store))
	for k, v := range p.store {
		if v.count() == 0 {
			continue
		}
		keys = append(keys, []byte(k))
	}
	p.mu.RUnlock()
	return keys
}
559629
func compareKeys(a, b ssh.PublicKey) bool {
	if a.Type() != b.Type() {
		return false
	}
	// The best way to compare just the key seems to be to marshal both and
	// then compare the output byte sequence.
	return subtle.ConstantTimeCompare(a.Marshal(), b.Marshal()) == 1
}
371658
func (c *Cache) Keys() [][]byte {
	c.mu.RLock()
	store := c.store
	c.mu.RUnlock()
	return store.keys(true)
}
243803
func SortedKeys(m map[string]interface{}) []string {
	i, sorted := 0, make([]string, len(m))
	for k := range m {
		sorted[i] = k
		i++
	}
	sort.Strings(sorted)
	return sorted
}
1089597
func (hm *SyncedHashMap) Keys() (ch chan Hashable) {
	ch = make(chan Hashable)
	go func() {
		hm.RLock()
		defer hm.RUnlock()
		defer close(ch)
		for _, v := range hm.keys {
			ch <- v
		}
	}()
	return
}
423926
func (d *ResourceDiff) diffChange(key string) (interface{}, interface{}, bool, bool, bool) {
	old, new, customized := d.getChange(key)

	if !old.Exists {
		old.Value = nil
	}
	if !new.Exists || d.removed(key) {
		new.Value = nil
	}

	return old.Value, new.Value, !reflect.DeepEqual(old.Value, new.Value), new.Computed, customized
}
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
}