github.com/fluhus/gostuff@v0.4.1-0.20240331134726-be71864f2b5d/ppln/serial_test.go (about)

     1  package ppln
     2  
     3  import (
     4  	"fmt"
     5  	"math/rand"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/fluhus/gostuff/gnum"
    10  )
    11  
    12  func ExampleSerial() {
    13  	ngoroutines := 4
    14  	var results []float64
    15  
    16  	Serial(
    17  		ngoroutines,
    18  		// Read/generate input data.
    19  		func(push func(int), stop func() bool) error {
    20  			for i := 1; i <= 100; i++ {
    21  				push(i)
    22  			}
    23  			return nil
    24  		},
    25  		// Some processing.
    26  		func(a int, i, g int) (float64, error) {
    27  			return float64(a*a) + 0.5, nil
    28  		},
    29  		// Accumulate/forward outputs.
    30  		func(a float64) error {
    31  			results = append(results, a)
    32  			return nil
    33  		})
    34  
    35  	fmt.Println(results[:3], results[len(results)-3:])
    36  
    37  	// Output:
    38  	// [1.5 4.5 9.5] [9604.5 9801.5 10000.5]
    39  }
    40  
    41  func ExampleSerial_parallelAggregation() {
    42  	ngoroutines := 4
    43  	results := make([]int, ngoroutines) // Goroutine-specific data and objects.
    44  
    45  	Serial(
    46  		ngoroutines,
    47  		// Read/generate input data.
    48  		func(push func(int), stop func() bool) error {
    49  			for i := 1; i <= 100; i++ {
    50  				push(i)
    51  			}
    52  			return nil
    53  		},
    54  		// Accumulate in goroutine-specific memory.
    55  		func(a int, i, g int) (int, error) {
    56  			results[g] += a
    57  			return 0, nil // Unused.
    58  		},
    59  		// No outputs.
    60  		func(a int) error { return nil })
    61  
    62  	// Collect the results of all goroutines.
    63  	fmt.Println("Sum of 1-100:", gnum.Sum(results))
    64  
    65  	// Output:
    66  	// Sum of 1-100: 5050
    67  }
    68  
    69  func TestSerial(t *testing.T) {
    70  	for _, nt := range []int{0, 1, 2, 4, 8} {
    71  		t.Run(fmt.Sprint(nt), func(t *testing.T) {
    72  			n := nt * 100
    73  			var result []int
    74  			err := Serial(nt, func(push func(int), stop func() bool) error {
    75  				for i := 0; i < n; i++ {
    76  					push(i)
    77  				}
    78  				return nil
    79  			}, func(a int, i int, g int) (int, error) {
    80  				time.Sleep(time.Millisecond * time.Duration(rand.Intn(3)))
    81  				return a * a, nil
    82  			}, func(i int) error {
    83  				result = append(result, i)
    84  				return nil
    85  			})
    86  			if err != nil {
    87  				t.Fatalf("Serial2(...) failed: %d", err)
    88  			}
    89  			for i := range result {
    90  				if result[i] != i*i {
    91  					t.Errorf("result[%d]=%d, want %d", i, result[i], i*i)
    92  				}
    93  			}
    94  		})
    95  	}
    96  }
    97  
    98  func TestSerial_error(t *testing.T) {
    99  	for _, nt := range []int{0, 1, 2, 4, 8} {
   100  		t.Run(fmt.Sprint(nt), func(t *testing.T) {
   101  			n := nt * 100
   102  			var result []int
   103  			err := Serial(nt, func(push func(int), stop func() bool) error {
   104  				for i := 0; i < n; i++ {
   105  					if stop() {
   106  						break
   107  					}
   108  					push(i)
   109  				}
   110  				return nil
   111  			}, func(a int, i int, g int) (int, error) {
   112  				time.Sleep(time.Millisecond * time.Duration(rand.Intn(3)))
   113  				if a > 300 {
   114  					return 0, fmt.Errorf("a too big: %d", a)
   115  				}
   116  				return a * a, nil
   117  			}, func(i int) error {
   118  				result = append(result, i)
   119  				return nil
   120  			})
   121  			if nt <= 3 {
   122  				if err != nil {
   123  					t.Fatalf("Serial2(...) failed: %d", err)
   124  				}
   125  				for i := range result {
   126  					if result[i] != i*i {
   127  						t.Errorf("result[%d]=%d, want %d", i, result[i], i*i)
   128  					}
   129  				}
   130  			} else { // n > 3
   131  				if err == nil {
   132  					t.Fatalf("Serial2(...) succeeded, want error")
   133  				}
   134  			}
   135  		})
   136  	}
   137  }