mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-30 06:54:01 +00:00
Add BUILD files and Boilerplates
Updates based on comments * Export comments added * glog changed to klog * Other small edits
This commit is contained in:
parent
f10e76962f
commit
a273333f1f
@ -166,6 +166,7 @@ filegroup(
|
||||
"//pkg/kubelet/cm/cpumanager:all-srcs",
|
||||
"//pkg/kubelet/cm/cpuset:all-srcs",
|
||||
"//pkg/kubelet/cm/devicemanager:all-srcs",
|
||||
"//pkg/kubelet/cm/topologymanager:all-srcs",
|
||||
"//pkg/kubelet/cm/util:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
|
23
pkg/kubelet/cm/topologymanager/BUILD
Normal file
23
pkg/kubelet/cm/topologymanager/BUILD
Normal file
@ -0,0 +1,23 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_test")
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["socketmask_test.go"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/kubelet/cm/topologymanager/socketmask:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
23
pkg/kubelet/cm/topologymanager/socketmask/BUILD
Normal file
23
pkg/kubelet/cm/topologymanager/socketmask/BUILD
Normal file
@ -0,0 +1,23 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["socketmask.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/socketmask",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//vendor/k8s.io/klog:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
@ -1,154 +1,167 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package socketmask
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"k8s.io/klog"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
"bytes"
|
||||
"math"
|
||||
"github.com/golang/glog"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
||||
// SocketMask represents the NUMA affinity of a socket.
|
||||
type SocketMask []int64
|
||||
|
||||
// NewSocketMask creates a new socket mask.
|
||||
func NewSocketMask(Mask []int64) SocketMask {
|
||||
sm := Mask
|
||||
return sm
|
||||
return Mask
|
||||
}
|
||||
|
||||
// GetSocketMask calculates the socket mask.
|
||||
func (sm SocketMask) GetSocketMask(socketMask []SocketMask, maskHolder []string, count int) (SocketMask, []string) {
|
||||
var socketAffinityInt64 [][]int64
|
||||
for r := range socketMask {
|
||||
socketAffinityVals := []int64(socketMask[r])
|
||||
socketAffinityInt64 = append(socketAffinityInt64,socketAffinityVals)
|
||||
}
|
||||
if count == 0 {
|
||||
maskHolder = buildMaskHolder(socketAffinityInt64)
|
||||
for r := range socketMask {
|
||||
socketAffinityVals := []int64(socketMask[r])
|
||||
socketAffinityInt64 = append(socketAffinityInt64, socketAffinityVals)
|
||||
}
|
||||
glog.Infof("[socketmask] MaskHolder : %v", maskHolder)
|
||||
glog.Infof("[socketmask] %v is passed into arrange function", socketMask)
|
||||
arrangedMask := arrangeMask(socketAffinityInt64)
|
||||
newMask := getTopologyAffinity(arrangedMask, maskHolder)
|
||||
glog.Infof("[socketmask] New Mask after getTopologyAffinity (new mask) : %v ",newMask)
|
||||
finalMaskValue := parseMask(newMask)
|
||||
glog.Infof("[socketmask] Mask []Int64 (finalMaskValue): %v", finalMaskValue)
|
||||
maskHolder = newMask
|
||||
glog.Infof("[socketmask] New MaskHolder: %v", maskHolder)
|
||||
finalSocketMask := SocketMask(finalMaskValue)
|
||||
return finalSocketMask, maskHolder
|
||||
if count == 0 {
|
||||
maskHolder = buildMaskHolder(socketAffinityInt64)
|
||||
}
|
||||
klog.V(4).Infof("[socketmask] MaskHolder : %v", maskHolder)
|
||||
klog.V(4).Infof("[socketmask] %v is passed into arrange function", socketMask)
|
||||
arrangedMask := arrangeMask(socketAffinityInt64)
|
||||
newMask := getTopologyAffinity(arrangedMask, maskHolder)
|
||||
klog.V(4).Infof("[socketmask] New Mask after getTopologyAffinity (new mask) : %v ", newMask)
|
||||
finalMaskValue := parseMask(newMask)
|
||||
klog.V(4).Infof("[socketmask] Mask []Int64 (finalMaskValue): %v", finalMaskValue)
|
||||
maskHolder = newMask
|
||||
klog.V(4).Infof("[socketmask] New MaskHolder: %v", maskHolder)
|
||||
return SocketMask(finalMaskValue), maskHolder
|
||||
}
|
||||
|
||||
func buildMaskHolder(mask [][]int64) []string {
|
||||
var maskHolder []string
|
||||
outerLen := len(mask)
|
||||
var innerLen int = 0
|
||||
for i := 0; i < outerLen; i++ {
|
||||
if innerLen < len(mask[i]) {
|
||||
innerLen = len(mask[i])
|
||||
}
|
||||
}
|
||||
var buffer bytes.Buffer
|
||||
var i, j int = 0, 0
|
||||
for i = 0; i < outerLen; i++ {
|
||||
for j = 0; j < innerLen; j++ {
|
||||
buffer.WriteString("1")
|
||||
}
|
||||
maskHolder = append(maskHolder, buffer.String())
|
||||
buffer.Reset()
|
||||
}
|
||||
return maskHolder
|
||||
outerLen := len(mask)
|
||||
var innerLen int
|
||||
for i := 0; i < outerLen; i++ {
|
||||
if innerLen < len(mask[i]) {
|
||||
innerLen = len(mask[i])
|
||||
}
|
||||
}
|
||||
var maskHolder []string
|
||||
var buffer bytes.Buffer
|
||||
var i, j int = 0, 0
|
||||
for i = 0; i < outerLen; i++ {
|
||||
for j = 0; j < innerLen; j++ {
|
||||
buffer.WriteString("1")
|
||||
}
|
||||
maskHolder = append(maskHolder, buffer.String())
|
||||
buffer.Reset()
|
||||
}
|
||||
return maskHolder
|
||||
}
|
||||
|
||||
func getTopologyAffinity(arrangedMask, maskHolder []string) []string {
|
||||
var topologyTemp []string
|
||||
for i:= 0; i < (len(maskHolder)); i++ {
|
||||
for j:= 0; j < (len(arrangedMask)); j++ {
|
||||
tempStr := andOperation(maskHolder[i],arrangedMask[j])
|
||||
if strings.Contains(tempStr, "1") {
|
||||
topologyTemp = append(topologyTemp, tempStr )
|
||||
}
|
||||
}
|
||||
}
|
||||
duplicates := map[string]bool{}
|
||||
for v:= range topologyTemp {
|
||||
duplicates[topologyTemp[v]] = true
|
||||
}
|
||||
// Place all keys from the map into a slice.
|
||||
topologyResult := []string{}
|
||||
for key, _ := range duplicates {
|
||||
topologyResult = append(topologyResult, key)
|
||||
}
|
||||
var topologyTemp []string
|
||||
for i := 0; i < len(maskHolder); i++ {
|
||||
for j := 0; j < len(arrangedMask); j++ {
|
||||
tempStr := andOperation(maskHolder[i], arrangedMask[j])
|
||||
if strings.Contains(tempStr, "1") {
|
||||
topologyTemp = append(topologyTemp, tempStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
duplicates := map[string]bool{}
|
||||
for v := range topologyTemp {
|
||||
duplicates[topologyTemp[v]] = true
|
||||
}
|
||||
// Place all keys from the map into a slice.
|
||||
topologyResult := []string{}
|
||||
for key := range duplicates {
|
||||
topologyResult = append(topologyResult, key)
|
||||
}
|
||||
|
||||
return topologyResult
|
||||
return topologyResult
|
||||
}
|
||||
|
||||
func parseMask(mask []string) []int64 {
|
||||
var maskStr string
|
||||
min := strings.Count(mask[0], "1")
|
||||
var num, index int
|
||||
var maskStr string
|
||||
min := strings.Count(mask[0], "1")
|
||||
var num, index int
|
||||
|
||||
for i := 0; i < len(mask); i++ {
|
||||
num = strings.Count(mask[i], "1")
|
||||
if num < min {
|
||||
min = num
|
||||
index = i
|
||||
}
|
||||
maskStr = mask[index]
|
||||
}
|
||||
var maskInt []int64
|
||||
for _, char := range maskStr {
|
||||
convertedStr, err := strconv.Atoi(string(char))
|
||||
if err != nil {
|
||||
glog.Errorf("Could not convert string to int. Err: %v", err)
|
||||
return maskInt
|
||||
}
|
||||
maskInt = append(maskInt, int64(convertedStr))
|
||||
}
|
||||
glog.Infof("[socketmask] Mask Int in Parse Mask: %v", maskInt)
|
||||
return maskInt
|
||||
for i := 0; i < len(mask); i++ {
|
||||
num = strings.Count(mask[i], "1")
|
||||
if num < min {
|
||||
min = num
|
||||
index = i
|
||||
}
|
||||
maskStr = mask[index]
|
||||
}
|
||||
var maskInt []int64
|
||||
for _, char := range maskStr {
|
||||
convertedStr, err := strconv.Atoi(string(char))
|
||||
if err != nil {
|
||||
klog.V(4).Infof("could not convert mask character: %v", err)
|
||||
return maskInt
|
||||
}
|
||||
maskInt = append(maskInt, int64(convertedStr))
|
||||
}
|
||||
klog.V(4).Infof("[socketmask] Mask Int in Parse Mask: %v", maskInt)
|
||||
return maskInt
|
||||
}
|
||||
|
||||
func arrangeMask(mask [][]int64) []string {
|
||||
var socketStr []string
|
||||
var bufferNew bytes.Buffer
|
||||
outerLen := len(mask)
|
||||
innerLen := len(mask[0])
|
||||
for i := 0; i < outerLen; i++ {
|
||||
for j := 0; j < innerLen; j++ {
|
||||
if mask[i][j] == 1 {
|
||||
bufferNew.WriteString("1")
|
||||
} else if mask[i][j] == 0 {
|
||||
bufferNew.WriteString("0")
|
||||
}
|
||||
}
|
||||
socketStr = append(socketStr, bufferNew.String())
|
||||
bufferNew.Reset()
|
||||
}
|
||||
return socketStr
|
||||
var socketStr []string
|
||||
var bufferNew bytes.Buffer
|
||||
outerLen := len(mask)
|
||||
innerLen := len(mask[0])
|
||||
for i := 0; i < outerLen; i++ {
|
||||
for j := 0; j < innerLen; j++ {
|
||||
if mask[i][j] == 1 {
|
||||
bufferNew.WriteString("1")
|
||||
} else if mask[i][j] == 0 {
|
||||
bufferNew.WriteString("0")
|
||||
}
|
||||
}
|
||||
socketStr = append(socketStr, bufferNew.String())
|
||||
bufferNew.Reset()
|
||||
}
|
||||
return socketStr
|
||||
}
|
||||
|
||||
func andOperation(val1, val2 string) (string) {
|
||||
l1, l2 := len(val1), len(val2)
|
||||
//compare lengths of strings - pad shortest with trailing zeros
|
||||
if l1 != l2 {
|
||||
// Get the bit difference
|
||||
var num int
|
||||
diff := math.Abs(float64(l1) - float64(l2))
|
||||
num = int(diff)
|
||||
if l1 < l2 {
|
||||
val1 = val1 + strings.Repeat("0", num)
|
||||
} else {
|
||||
val2 = val2 + strings.Repeat("0", num)
|
||||
}
|
||||
}
|
||||
length := len(val1)
|
||||
byteArr := make([]byte, length)
|
||||
for i := 0; i < length ; i++ {
|
||||
byteArr[i] = (val1[i] & val2[i])
|
||||
}
|
||||
var finalStr string
|
||||
finalStr = string(byteArr[:])
|
||||
func andOperation(val1, val2 string) string {
|
||||
l1, l2 := len(val1), len(val2)
|
||||
//compare lengths of strings - pad shortest with trailing zeros
|
||||
if l1 != l2 {
|
||||
// Get the bit difference
|
||||
var num int
|
||||
diff := math.Abs(float64(l1) - float64(l2))
|
||||
num = int(diff)
|
||||
if l1 < l2 {
|
||||
val1 = val1 + strings.Repeat("0", num)
|
||||
} else {
|
||||
val2 = val2 + strings.Repeat("0", num)
|
||||
}
|
||||
}
|
||||
length := len(val1)
|
||||
byteArr := make([]byte, length)
|
||||
for i := 0; i < length; i++ {
|
||||
byteArr[i] = val1[i] & val2[i]
|
||||
}
|
||||
|
||||
return finalStr
|
||||
return string(byteArr[:])
|
||||
}
|
||||
|
||||
|
104
pkg/kubelet/cm/topologymanager/socketmask_test.go
Normal file
104
pkg/kubelet/cm/topologymanager/socketmask_test.go
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package socketmask
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetSocketmask(t *testing.T) {
|
||||
tcases := []struct {
|
||||
name string
|
||||
socketmask []SocketMask
|
||||
maskholder []string
|
||||
count int
|
||||
expectedMaskHolder []string
|
||||
expectedFinalSocketMask SocketMask
|
||||
}{
|
||||
{
|
||||
name: "Empty MaskHolder and count set as 0",
|
||||
socketmask: []SocketMask{{1, 0}, {0, 1}, {1, 1}},
|
||||
maskholder: []string{""},
|
||||
count: 0,
|
||||
expectedMaskHolder: []string{"10", "01", "11"},
|
||||
expectedFinalSocketMask: SocketMask{1, 0},
|
||||
},
|
||||
{
|
||||
name: "MaskHolder non zero, count set as 1",
|
||||
socketmask: []SocketMask{{1, 0}, {0, 1}, {1, 1}},
|
||||
maskholder: []string{"10", "01", "11"},
|
||||
count: 1,
|
||||
expectedMaskHolder: []string{"10", "01", "11"},
|
||||
expectedFinalSocketMask: SocketMask{1, 0},
|
||||
},
|
||||
|
||||
{
|
||||
name: "Empty MaskHolder and count set as 0",
|
||||
socketmask: []SocketMask{{0, 1}, {1, 1}},
|
||||
maskholder: []string{""},
|
||||
count: 0,
|
||||
expectedMaskHolder: []string{"01", "11"},
|
||||
expectedFinalSocketMask: SocketMask{0, 1},
|
||||
},
|
||||
{
|
||||
name: "MaskHolder non zero, count set as 1",
|
||||
socketmask: []SocketMask{{0, 1}, {1, 1}},
|
||||
maskholder: []string{"01", "11"},
|
||||
count: 1,
|
||||
expectedMaskHolder: []string{"01", "11"},
|
||||
expectedFinalSocketMask: SocketMask{0, 1},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcases {
|
||||
|
||||
sm := NewSocketMask(nil)
|
||||
actualSocketMask, actualMaskHolder := sm.GetSocketMask(tc.socketmask, tc.maskholder, tc.count)
|
||||
if !reflect.DeepEqual(actualSocketMask, tc.expectedFinalSocketMask) {
|
||||
t.Errorf("Expected final socketmask to be %v, got %v", tc.expectedFinalSocketMask, actualSocketMask)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(actualMaskHolder, tc.expectedMaskHolder) {
|
||||
t.Errorf("Expected maskholder to be %v, got %v", tc.expectedMaskHolder, actualMaskHolder)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewSocketMask(t *testing.T) {
|
||||
tcases := []struct {
|
||||
name string
|
||||
Mask []int64
|
||||
expectedMask []int64
|
||||
}{
|
||||
{
|
||||
name: "Mask as an int64 binary array",
|
||||
Mask: []int64{1, 0},
|
||||
expectedMask: []int64{1, 0},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcases {
|
||||
|
||||
sm := NewSocketMask(nil)
|
||||
|
||||
if reflect.DeepEqual(sm, tc.expectedMask) {
|
||||
t.Errorf("Expected socket mask to be %v, got %v", tc.expectedMask, sm)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user