(parent context.Context, fromCh chan Item, identifier func(interface{}) int, opts ...Option)
| 421 | } |
| 422 | |
| 423 | func (o *ObservableImpl) serialize(parent context.Context, fromCh chan Item, identifier func(interface{}) int, opts ...Option) Observable { |
| 424 | option := parseOptions(opts...) |
| 425 | next := option.buildChannel() |
| 426 | |
| 427 | ctx := option.buildContext(parent) |
| 428 | minHeap := binaryheap.NewWith(func(a, b interface{}) int { |
| 429 | return a.(int) - b.(int) |
| 430 | }) |
| 431 | items := make(map[int]interface{}) |
| 432 | |
| 433 | var from int |
| 434 | var counter int64 |
| 435 | src := o.Observe(opts...) |
| 436 | go func() { |
| 437 | select { |
| 438 | case <-ctx.Done(): |
| 439 | close(next) |
| 440 | return |
| 441 | case item := <-fromCh: |
| 442 | if item.Error() { |
| 443 | item.SendContext(ctx, next) |
| 444 | close(next) |
| 445 | return |
| 446 | } |
| 447 | from = item.V.(int) |
| 448 | counter = int64(from) |
| 449 | |
| 450 | go func() { |
| 451 | defer close(next) |
| 452 | |
| 453 | for { |
| 454 | select { |
| 455 | case <-ctx.Done(): |
| 456 | return |
| 457 | case item, ok := <-src: |
| 458 | if !ok { |
| 459 | return |
| 460 | } |
| 461 | if item.Error() { |
| 462 | next <- item |
| 463 | return |
| 464 | } |
| 465 | |
| 466 | id := identifier(item.V) |
| 467 | minHeap.Push(id) |
| 468 | items[id] = item.V |
| 469 | |
| 470 | for !minHeap.Empty() { |
| 471 | v, _ := minHeap.Peek() |
| 472 | id := v.(int) |
| 473 | if atomic.LoadInt64(&counter) == int64(id) { |
| 474 | if itemValue, contains := items[id]; contains { |
| 475 | minHeap.Pop() |
| 476 | delete(items, id) |
| 477 | Of(itemValue).SendContext(ctx, next) |
| 478 | counter++ |
| 479 | continue |
| 480 | } |
no test coverage detected