github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/pkg/subsystem/linux/coincidence.go (about)

     1  // Copyright 2023 syzkaller project authors. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  package linux
     5  
     6  import "github.com/google/syzkaller/pkg/subsystem"
     7  
     8  // CoincidenceMatrix represents a matrix that, for every pair of subsystems
     9  // A and B, stores the number of times A and B have coincided in the input data.
    10  // So far we only need it for subsystem.Subsystem, so its interface is tailored to it.
    11  type CoincidenceMatrix struct {
    12  	matrix map[*subsystem.Subsystem]map[*subsystem.Subsystem]int
    13  }
    14  
    15  func MakeCoincidenceMatrix() *CoincidenceMatrix {
    16  	return &CoincidenceMatrix{
    17  		matrix: make(map[*subsystem.Subsystem]map[*subsystem.Subsystem]int),
    18  	}
    19  }
    20  
    21  func (cm *CoincidenceMatrix) Record(items ...*subsystem.Subsystem) {
    22  	for i := 0; i < len(items); i++ {
    23  		for j := 0; j < len(items); j++ {
    24  			cm.inc(items[i], items[j])
    25  		}
    26  	}
    27  }
    28  
    29  func (cm *CoincidenceMatrix) Count(a *subsystem.Subsystem) int {
    30  	return cm.Get(a, a)
    31  }
    32  
    33  func (cm *CoincidenceMatrix) Get(a, b *subsystem.Subsystem) int {
    34  	return cm.matrix[a][b]
    35  }
    36  
    37  func (cm *CoincidenceMatrix) NonEmptyPairs(cb func(a, b *subsystem.Subsystem, val int)) {
    38  	for a, sub := range cm.matrix {
    39  		for b, val := range sub {
    40  			if a == b {
    41  				continue
    42  			}
    43  			cb(a, b, val)
    44  		}
    45  	}
    46  }
    47  
    48  func (cm *CoincidenceMatrix) inc(a, b *subsystem.Subsystem) {
    49  	subMatrix, ok := cm.matrix[a]
    50  	if !ok {
    51  		subMatrix = make(map[*subsystem.Subsystem]int)
    52  		cm.matrix[a] = subMatrix
    53  	}
    54  	subMatrix[b]++
    55  }