11package  iter
22
33import  (
4+ 	"context" 
45	"io" 
5- 	"sync" 
66
77	"github.com/BooleanCat/go-functional/option" 
88)
@@ -38,10 +38,9 @@ var _ Iterator[struct{}] = new(LiftIter[struct{}])
3838// LiftHashMapIter iterator, see [LiftHashMap]. 
3939type  LiftHashMapIter [T  comparable , U  any ] struct  {
4040	BaseIter [Pair [T , U ]]
41- 	hashmap   map [T ]U 
42- 	items     chan  Pair [T , U ]
43- 	stopOnce  sync.Once 
44- 	stop      chan  struct {}
41+ 	hashmap  map [T ]U 
42+ 	items    chan  Pair [T , U ]
43+ 	cancel   func ()
4544}
4645
4746// LiftHashMap instantiates a [*LiftHashMapIter] that will yield all items in 
@@ -60,25 +59,24 @@ type LiftHashMapIter[T comparable, U any] struct {
6059// necessary to call Close if exhaustion is guaranteed, but may be wise to 
6160// redundantly call Close if you're unsure. 
6261func  LiftHashMap [T  comparable , U  any ](hashmap  map [T ]U ) * LiftHashMapIter [T , U ] {
62+ 	ctx , cancel  :=  context .WithCancel (context .Background ())
63+ 
6364	iter  :=  & LiftHashMapIter [T , U ]{
64- 		hashmap :  hashmap ,
65- 		items :    make (chan  Pair [T , U ]),
66- 		stopOnce : sync.Once {},
67- 		stop :     make (chan  struct {}, 1 ),
65+ 		hashmap : hashmap ,
66+ 		items :   make (chan  Pair [T , U ]),
67+ 		cancel :  cancel ,
6868	}
6969
7070	iter .BaseIter  =  BaseIter [Pair [T , U ]]{iter }
7171
7272	go  func () {
7373		defer  close (iter .items )
74- 		defer  iter .stopOnce .Do (func () { close (iter .stop ) })
75- 	outer:
74+ 
7675		for  k , v  :=  range  hashmap  {
7776			select  {
77+ 			case  <- ctx .Done ():
78+ 				return 
7879			case  iter .items  <-  Pair [T , U ]{k , v }:
79- 				continue 
80- 			case  <- iter .stop :
81- 				break  outer
8280			}
8381		}
8482	}()
@@ -92,14 +90,8 @@ func LiftHashMap[T comparable, U any](hashmap map[T]U) *LiftHashMapIter[T, U] {
9290// 
9391// This function can never fail and the error can be ignored. 
9492func  (iter  * LiftHashMapIter [T , U ]) Close () error  {
95- 	iter .stopOnce .Do (func () {
96- 		iter .stop  <-  struct {}{}
97- 		close (iter .stop )
98- 	})
99- 
100- 	for  range  iter .items  {
101- 		// Wait for close 
102- 	}
93+ 	iter .cancel ()
94+ 	<- iter .items 
10395
10496	return  nil 
10597}
0 commit comments