How to use GetFilledExecutionSegmentSequence method of lib Package

Best K6 code snippet using lib.GetFilledExecutionSegmentSequence

execution_segment.go

Source:execution_segment.go Github

copy

Full Screen

...379 }380 return a381}382// IsFull returns whether the sequences is full, that is, whether it starts at 0383// and ends at 1. Use GetFilledExecutionSegmentSequence() to get a full sequence.384func (ess ExecutionSegmentSequence) IsFull() bool {385 return ess != nil && len(ess) != 0 && ess[0].from.Cmp(zeroRat) == 0 && ess[len(ess)-1].to.Cmp(oneRat) == 0386}387// FindSegmentPosition returns the index of the supplied execution segment in388// the sequence, or an error if the segment isn't present. This shouldn't be389// used on a nil or empty sequence, it's best to use this method on the result390// of GetFilledExecutionSegmentSequence().391func (ess ExecutionSegmentSequence) FindSegmentPosition(segment *ExecutionSegment) (int, error) {392 from := zeroRat393 if segment != nil {394 from = segment.from395 }396 index := sort.Search(len(ess), func(i int) bool {397 return ess[i].from.Cmp(from) >= 0398 })399 if index < 0 || index >= len(ess) || !ess[index].Equal(segment) {400 return -1, fmt.Errorf("couldn't find segment %s in sequence %s", segment, ess)401 }402 return index, nil403}404// GetFilledExecutionSegmentSequence makes sure we don't have any gaps in the405// given execution segment sequence, or a nil one. It makes sure that the whole406// 0-1 range is filled.407func GetFilledExecutionSegmentSequence(408 sequence *ExecutionSegmentSequence, fallback *ExecutionSegment,409) (result ExecutionSegmentSequence) {410 if sequence == nil || len(*sequence) == 0 {411 if fallback == nil || fallback.length.Cmp(oneRat) == 0 {412 // There is no sequence or a segment, so it means the whole test run413 // is being planned/executed. So we make sure not to have a nil414 // sequence, returning a full; "0,1" sequence instead, otherwise we415 // will need to check for nil everywhere...416 return ExecutionSegmentSequence{newExecutionSegment(zeroRat, oneRat)}417 }418 // We don't have a sequence, but we have a defined segment, so we419 // fill around it with the missing pieces for a full sequence.420 result = ExecutionSegmentSequence{fallback}421 } else {422 result = *sequence423 }424 if result[0].from.Cmp(zeroRat) != 0 {425 es := newExecutionSegment(zeroRat, result[0].from)426 result = append(ExecutionSegmentSequence{es}, result...)427 }428 if result[len(result)-1].to.Cmp(oneRat) != 0 {429 es := newExecutionSegment(result[len(result)-1].to, oneRat)430 result = append(result, es)431 }432 return result433}434// ExecutionSegmentSequenceWrapper is a caching layer on top of the execution435// segment sequence that allows us to make fast and useful calculations, after436// a somewhat slow initialization.437type ExecutionSegmentSequenceWrapper struct {438 ExecutionSegmentSequence // a filled-out segment sequence439 lcd int64 // pre-calculated least common denominator440 // The striped offsets, i.e. the repeating indexes that "belong" to each441 // execution segment in the sequence.442 offsets [][]int64443}444// NewExecutionSegmentSequenceWrapper expects a filled-out execution segment445// sequence. It pre-calculates the initial caches of and returns a new446// ExecutionSegmentSequenceWrapper, but doesn't calculate the striped offsets.447func NewExecutionSegmentSequenceWrapper(ess ExecutionSegmentSequence) *ExecutionSegmentSequenceWrapper {448 if !ess.IsFull() {449 panic(fmt.Sprintf("Cannot wrap around a non-full execution segment sequence '%s'", ess))450 }451 sequenceLength := len(ess)452 offsets := make([][]int64, sequenceLength)453 lcd := ess.LCD()454 // This will contain the normalized numerator values (i.e. what they would have455 // been if all denominators were equal to the LCD), sorted in descending456 // order (i.e. biggest segments are first), with references to their actual457 // indexes in the execution segment sequence (i.e. `seq` above).458 sortedNormalizedIndexes := make([]struct {459 normNumerator int64460 originalIndex int461 }, sequenceLength)462 for i := range ess {463 normalizedNumerator := ess[i].length.Num().Int64() * (lcd / ess[i].length.Denom().Int64())464 sortedNormalizedIndexes[i].normNumerator = normalizedNumerator465 sortedNormalizedIndexes[i].originalIndex = i466 offsets[i] = make([]int64, 0, normalizedNumerator+1)467 }468 sort.SliceStable(sortedNormalizedIndexes, func(i, j int) bool {469 return sortedNormalizedIndexes[i].normNumerator > sortedNormalizedIndexes[j].normNumerator470 })471 // This is the striping algorithm. Imagine you have a number of rational472 // numbers which all add up to 1 (or less), and call them segments. If you473 // want each to get proportional amount of anything, you need to give them474 // their numerator count of elements for each denominator amount from the475 // original elements. So, for 1/3, you give 1 element for each 3 elements.476 // For 3/5 - 3 elements for each 5. If you have, for example, a sequence477 // with elements with length 3/5 and 1/3, in order to know how to distribute478 // it accurately, you need to get the LCD(lowest common denominitor). In479 // this case, between 3 and 5, the LCD is 15. Then to transform the numbers480 // to have the same, LCD equal, denominator. So 3/5 becomes 9/15 and 1/3481 // becomes 5/15. So now for each 15 elements 9 need to go to the 3/5, and 5482 // need to go to 1/3. This is what we did above in sortedNormalizedIndexes.483 //484 // We use the algorithm below to split elements between ExecutionSegments by485 // using their length as the rational number. As we would like to get486 // non-sequential elements, we try to get the maximum distance between them.487 // That is the number of elements divided by the number of elements for any488 // given segment, which concidently is the length of the segment reversed.489 // The algorithm below does the following:490 // 1. Goes through the elements from 0 to the lcd-1491 // 2. For each of element, it goes through the segments and looks if the492 // amount of already taken elements by the given segment, multiplied by493 // that segment's length inverted, is equal to or less to the current494 // element index. If it is, give that element to that segment. If not,495 // continue with the next element.496 // The code below specifically avoids using big.Rat, for performance497 // reasons, which complicates the code somewhat. As additional note, the498 // sorting of the segments from biggest to smallest helps with the fact that499 // the biggest elements will need to take the most elements, and for them it500 // will be the hardest to not get sequential elements.501 prev := make([]int64, sequenceLength)502 chosenCounts := make([]int64, sequenceLength)503 saveIndex := func(iteration int64, index int, numerator int64) {504 offsets[index] = append(offsets[index], iteration-prev[index])505 prev[index] = iteration506 if int64(len(offsets[index])) == numerator {507 offsets[index] = append(offsets[index], offsets[index][0]+lcd-iteration)508 }509 }510 for i := int64(0); i < lcd; i++ {511 for sortedIndex, chosenCount := range chosenCounts {512 num := chosenCount * lcd513 denom := sortedNormalizedIndexes[sortedIndex].normNumerator514 if i > num/denom || (i == num/denom && num%denom == 0) {515 chosenCounts[sortedIndex]++516 saveIndex(i, sortedNormalizedIndexes[sortedIndex].originalIndex, denom)517 break518 }519 }520 }521 return &ExecutionSegmentSequenceWrapper{ExecutionSegmentSequence: ess, lcd: lcd, offsets: offsets}522}523// LCD returns the (cached) least common denominator of the sequence - no need524// to calculate it again, since we did it in the constructor.525func (essw *ExecutionSegmentSequenceWrapper) LCD() int64 {526 return essw.lcd527}528// ScaleInt64 scales the provided value for the given segment.529func (essw *ExecutionSegmentSequenceWrapper) ScaleInt64(segmentIndex int, value int64) int64 {530 start := essw.offsets[segmentIndex][0]531 offsets := essw.offsets[segmentIndex][1:]532 result := (value / essw.lcd) * int64(len(offsets))533 for gi, i := 0, start; i < value%essw.lcd; gi, i = gi+1, i+offsets[gi] {534 result++535 }536 return result537}538// GetStripedOffsets returns the stripped offsets for the given segment539// the returned values are as follows in order:540// - start: the first value that is for the segment541// - offsets: a list of offsets from the previous value for the segment. This are only the offsets542// to from the start to the next start if we chunk the elements we are going to strip543// into lcd sized chunks544// - lcd: the LCD of the lengths of all segments in the sequence. This is also the number of545// elements after which the algorithm starts to loop and give the same values546func (essw *ExecutionSegmentSequenceWrapper) GetStripedOffsets(segmentIndex int) (int64, []int64, int64) {547 offsets := essw.offsets[segmentIndex]548 return offsets[0], offsets[1:], essw.lcd549}550// GetTuple returns an ExecutionTuple for the specified segment index.551func (essw *ExecutionSegmentSequenceWrapper) GetTuple(segmentIndex int) *ExecutionTuple {552 return &ExecutionTuple{553 Sequence: essw,554 Segment: essw.ExecutionSegmentSequence[segmentIndex],555 SegmentIndex: segmentIndex,556 }557}558// GetNewExecutionSegmentSequenceFromValue uses the value provided, splits it559// between all the segments, using the striping offsets in the sequence,560// generating a new segment sequence. It then returns a new561// ExecutionSegmentSequenceWrapper, with the new sequence and segments, such562// that each new segment in the new sequence has length `Scale(value)/value`563// while keeping the order.564//565// Additionally, the position of a given segment index can be tracked (since566// empty segments are removed), so that you can reconstruct an ExecutionTuple,567// if required. If the segment with the trackedIndex is not part of the new568// sequence, or if a new sequence cannot be generated (for example, for 0569// values), an error will be returned.570func (essw *ExecutionSegmentSequenceWrapper) GetNewExecutionSegmentSequenceFromValue(value int64, trackedIndex int) (571 newSequence *ExecutionSegmentSequenceWrapper, newIndex int, err error,572) {573 if value < 1 {574 return nil, -1, fmt.Errorf("cannot generate new sequence for value %d", value)575 }576 if value%essw.lcd == 0 { // the value is perfectly divisible so we will get the same tuple577 return essw, trackedIndex, nil578 }579 newIndex = -1580 newESS := make(ExecutionSegmentSequence, 0, len(essw.ExecutionSegmentSequence)) // this can be smaller581 prev := int64(0)582 for i := range essw.ExecutionSegmentSequence {583 newValue := essw.ScaleInt64(i, value)584 if newValue == 0 {585 continue586 }587 currentES := newExecutionSegment(big.NewRat(prev, value), big.NewRat(prev+newValue, value))588 prev += newValue589 if i == trackedIndex {590 newIndex = len(newESS)591 }592 newESS = append(newESS, currentES)593 }594 if newIndex == -1 {595 return nil, -1, fmt.Errorf(596 "segment %d (%s) isn't present in the new sequence",597 trackedIndex, essw.ExecutionSegmentSequence[trackedIndex],598 )599 }600 return NewExecutionSegmentSequenceWrapper(newESS), newIndex, nil601}602// ExecutionTuple is the combination of an ExecutionSegmentSequence(Wrapper) and603// a specific ExecutionSegment from it. It gives easy access to the efficient604// scaling and striping algorithms for that specific segment, since the results605// are cached in the sequence wrapper.606type ExecutionTuple struct { // TODO rename? make fields private and have getter methods?607 Sequence *ExecutionSegmentSequenceWrapper608 Segment *ExecutionSegment609 SegmentIndex int610}611func (et *ExecutionTuple) String() string {612 return fmt.Sprintf("%s in %s", et.Segment, et.Sequence)613}614// NewExecutionTuple returns a new ExecutionTuple for the provided segment and615// sequence.616//617// TODO: don't return a pointer?618func NewExecutionTuple(segment *ExecutionSegment, sequence *ExecutionSegmentSequence) (*ExecutionTuple, error) {619 filledSeq := GetFilledExecutionSegmentSequence(sequence, segment)620 wrapper := NewExecutionSegmentSequenceWrapper(filledSeq)621 index, err := wrapper.FindSegmentPosition(segment)622 if err != nil {623 return nil, err624 }625 return &ExecutionTuple{Sequence: wrapper, Segment: segment, SegmentIndex: index}, nil626}627// ScaleInt64 scales the provided value for our execution segment.628func (et *ExecutionTuple) ScaleInt64(value int64) int64 {629 if len(et.Sequence.ExecutionSegmentSequence) == 1 {630 return value // if we don't have any segmentation, just return the original value631 }632 return et.Sequence.ScaleInt64(et.SegmentIndex, value)633}...

Full Screen

Full Screen

GetFilledExecutionSegmentSequence

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 executionSegmentSequence := lib.GetFilledExecutionSegmentSequence()4 fmt.Println(executionSegmentSequence)5}6import (7func main() {8 executionSegmentSequence := lib.GetFilledExecutionSegmentSequence()9 fmt.Println(executionSegmentSequence)10}11import (12func main() {13 executionSegmentSequence := lib.GetFilledExecutionSegmentSequence()14 fmt.Println(executionSegmentSequence)15}16import (17func main() {18 executionSegmentSequence := lib.GetFilledExecutionSegmentSequence()19 fmt.Println(executionSegmentSequence)20}21import (22func main() {23 executionSegmentSequence := lib.GetFilledExecutionSegmentSequence()24 fmt.Println(executionSegmentSequence)25}26import (27func main() {28 executionSegmentSequence := lib.GetFilledExecutionSegmentSequence()29 fmt.Println(executionSegmentSequence)30}31import (32func main() {33 executionSegmentSequence := lib.GetFilledExecutionSegmentSequence()34 fmt.Println(executionSegmentSequence)35}36import (37func main() {38 executionSegmentSequence := lib.GetFilledExecutionSegmentSequence()39 fmt.Println(executionSegmentSequence)40}

Full Screen

Full Screen

GetFilledExecutionSegmentSequence

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 fmt.Println(lib.GetFilledExecutionSegmentSequence())4}5import (6func main() {7 fmt.Println(lib.GetExecutionSegment())8}9import (10func main() {11 fmt.Println(lib.GetFilledExecutionSegmentSequence())12 fmt.Println(lib.GetExecutionSegment())13}

Full Screen

Full Screen

GetFilledExecutionSegmentSequence

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 fmt.Println(lib.GetFilledExecutionSegmentSequence())4}5import (6func main() {7 fmt.Println(lib.GetFilledExecutionSegmentSequence())8}9import (10func main() {11 fmt.Println(lib.GetFilledExecutionSegmentSequence())12}13import (14func main() {15 fmt.Println(lib.GetFilledExecutionSegmentSequence())16}17import (18func main() {19 fmt.Println(lib.GetFilledExecutionSegmentSequence())20}21import (22func main() {23 fmt.Println(lib.GetFilledExecutionSegmentSequence())24}25import (26func main() {27 fmt.Println(lib.GetFilledExecutionSegmentSequence())28}29import (30func main() {

Full Screen

Full Screen

GetFilledExecutionSegmentSequence

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 ess := lib.GetFilledExecutionSegmentSequence("1/5, 2/5, 3/5, 4/5, 5/5")4 fmt.Println("Execution Segment Sequence: ", ess)5}6import (7func main() {8 ess := lib.GetFilledExecutionSegmentSequence("1/5, 2/5, 3/5, 4/5, 5/5, 6/5")9 fmt.Println("Execution Segment Sequence: ", ess)10}11import (12func main() {13 ess := lib.GetFilledExecutionSegmentSequence("1/5, 2/5, 3/5, 4/5, 5/5, 0/5")14 fmt.Println("Execution Segment Sequence: ", ess)15}16import (17func main() {18 ess := lib.GetFilledExecutionSegmentSequence("1/5, 2/5, 3/5, 4/5, 5/5, 1/5")19 fmt.Println("Execution Segment Sequence: ", ess)20}21import (

Full Screen

Full Screen

GetFilledExecutionSegmentSequence

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 l := lib.New()4 fmt.Println(l.GetFilledExecutionSegmentSequence())5}6[{0 1}]7func (l *lib) GetFilledExecutionSegmentSequence() []lib.ExecutionSegment {8}

Full Screen

Full Screen

GetFilledExecutionSegmentSequence

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 lib1 := lib.New()4 executionSegmentSequence := lib1.GetFilledExecutionSegmentSequence()5 fmt.Println(executionSegmentSequence)6}7[{1 1}]8import (9func main() {10 lib1 := lib.New()11 executionSegmentSequence := lib1.GetFilledExecutionSegmentSequence()12 fmt.Println(executionSegmentSequence)13}14[{1 1}]15import (16func main() {17 lib1 := lib.New()18 executionSegmentSequence := lib1.GetFilledExecutionSegmentSequence()19 fmt.Println(executionSegmentSequence)20}21[{1 1}]22import (23func main() {24 lib1 := lib.New()25 executionSegmentSequence := lib1.GetFilledExecutionSegmentSequence()26 fmt.Println(executionSegmentSequence)27}28[{1 1}]29import (

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run K6 automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Most used method in

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful