@@ -32,6 +32,7 @@ declare namespace State {
3232 interface Entry < A , E > {
3333 readonly deferred : Deferred . Deferred < A , E >
3434 readonly scope : Scope . CloseableScope
35+ readonly finalizer : Effect < void >
3536 fiber : RuntimeFiber < void , never > | undefined
3637 refCount : number
3738 }
@@ -121,96 +122,96 @@ export const make: {
121122export const get : {
122123 < K > ( key : K ) : < A , E > ( self : RcMap . RcMap < K , A , E > ) => Effect < A , E , Scope . Scope >
123124 < K , A , E > ( self : RcMap . RcMap < K , A , E > , key : K ) : Effect < A , E , Scope . Scope >
124- } = dual (
125- 2 ,
126- < K , A , E > ( self_ : RcMap . RcMap < K , A , E > , key : K ) : Effect < A , E , Scope . Scope > => {
127- const self = self_ as RcMapImpl < K , A , E >
128- return core . uninterruptibleMask ( ( restore ) =>
129- core . suspend ( ( ) => {
130- if ( self . state . _tag === "Closed" ) {
131- return core . interrupt
132- }
133- const state = self . state
134- const o = MutableHashMap . get ( state . map , key )
135- if ( o . _tag === "Some" ) {
136- const entry = o . value
137- entry . refCount ++
138- return entry . fiber
139- ? core . as ( core . interruptFiber ( entry . fiber ) , entry )
140- : core . succeed ( entry )
141- } else if ( Number . isFinite ( self . capacity ) && MutableHashMap . size ( self . state . map ) >= self . capacity ) {
142- return core . fail (
143- new core . ExceededCapacityException ( `RcMap attempted to exceed capacity of ${ self . capacity } ` )
144- ) as Effect < never >
125+ } = dual ( 2 , < K , A , E > ( self_ : RcMap . RcMap < K , A , E > , key : K ) : Effect < A , E , Scope . Scope > => {
126+ const self = self_ as RcMapImpl < K , A , E >
127+ return core . uninterruptibleMask ( ( restore ) => getImpl ( self , key , restore as any ) )
128+ } )
129+
130+ const getImpl = core . fnUntraced ( function * < K , A , E > ( self : RcMapImpl < K , A , E > , key : K , restore : < A > ( a : A ) => A ) {
131+ if ( self . state . _tag === "Closed" ) {
132+ return yield * core . interrupt
133+ }
134+ const state = self . state
135+ const o = MutableHashMap . get ( state . map , key )
136+ let entry : State . Entry < A , E >
137+ if ( o . _tag === "Some" ) {
138+ entry = o . value
139+ entry . refCount ++
140+ if ( entry . fiber ) yield * core . interruptFiber ( entry . fiber )
141+ } else if ( Number . isFinite ( self . capacity ) && MutableHashMap . size ( self . state . map ) >= self . capacity ) {
142+ return yield * core . fail (
143+ new core . ExceededCapacityException ( `RcMap attempted to exceed capacity of ${ self . capacity } ` )
144+ ) as Effect < never >
145+ } else {
146+ entry = yield * self . semaphore . withPermits ( 1 ) ( acquire ( self , key , restore ) )
147+ }
148+ const scope = yield * fiberRuntime . scopeTag
149+ yield * scope . addFinalizer ( ( ) => entry . finalizer )
150+ return yield * restore ( core . deferredAwait ( entry . deferred ) )
151+ } )
152+
153+ const acquire = core . fnUntraced ( function * < K , A , E > ( self : RcMapImpl < K , A , E > , key : K , restore : < A > ( a : A ) => A ) {
154+ const scope = yield * fiberRuntime . scopeMake ( )
155+ const deferred = yield * core . deferredMake < A , E > ( )
156+ const acquire = self . lookup ( key )
157+ yield * restore ( core . fiberRefLocally (
158+ acquire as Effect < A , E > ,
159+ core . currentContext ,
160+ Context . add ( self . context , fiberRuntime . scopeTag , scope )
161+ ) ) . pipe (
162+ core . exit ,
163+ core . flatMap ( ( exit ) => core . deferredDone ( deferred , exit ) ) ,
164+ circular . forkIn ( scope )
165+ )
166+ const entry : State . Entry < A , E > = {
167+ deferred,
168+ scope,
169+ finalizer : undefined as any ,
170+ fiber : undefined ,
171+ refCount : 1
172+ }
173+ ; ( entry as any ) . finalizer = release ( self , key , entry )
174+ if ( self . state . _tag === "Open" ) {
175+ MutableHashMap . set ( self . state . map , key , entry )
176+ }
177+ return entry
178+ } )
179+
180+ const release = < K , A , E > ( self : RcMapImpl < K , A , E > , key : K , entry : State . Entry < A , E > ) =>
181+ core . suspend ( ( ) => {
182+ entry . refCount --
183+ if ( entry . refCount > 0 ) {
184+ return core . void
185+ } else if (
186+ self . state . _tag === "Closed"
187+ || ! MutableHashMap . has ( self . state . map , key )
188+ || self . idleTimeToLive === undefined
189+ ) {
190+ if ( self . state . _tag === "Open" ) {
191+ MutableHashMap . remove ( self . state . map , key )
192+ }
193+ return core . scopeClose ( entry . scope , core . exitVoid )
194+ }
195+
196+ return coreEffect . sleep ( self . idleTimeToLive ) . pipe (
197+ core . interruptible ,
198+ core . zipRight ( core . suspend ( ( ) => {
199+ if ( self . state . _tag === "Open" && entry . refCount === 0 ) {
200+ MutableHashMap . remove ( self . state . map , key )
201+ return core . scopeClose ( entry . scope , core . exitVoid )
145202 }
146- const acquire = self . lookup ( key )
147- return fiberRuntime . scopeMake ( ) . pipe (
148- coreEffect . bindTo ( "scope" ) ,
149- coreEffect . bind ( "deferred" , ( ) => core . deferredMake < A , E > ( ) ) ,
150- core . tap ( ( { deferred, scope } ) =>
151- restore ( core . fiberRefLocally (
152- acquire as Effect < A , E > ,
153- core . currentContext ,
154- Context . add ( self . context , fiberRuntime . scopeTag , scope )
155- ) ) . pipe (
156- core . exit ,
157- core . flatMap ( ( exit ) => core . deferredDone ( deferred , exit ) ) ,
158- circular . forkIn ( scope )
159- )
160- ) ,
161- core . map ( ( { deferred, scope } ) => {
162- const entry : State . Entry < A , E > = {
163- deferred,
164- scope,
165- fiber : undefined ,
166- refCount : 1
167- }
168- MutableHashMap . set ( state . map , key , entry )
169- return entry
170- } )
171- )
172- } ) . pipe (
173- self . semaphore . withPermits ( 1 ) ,
174- coreEffect . bindTo ( "entry" ) ,
175- coreEffect . bind ( "scope" , ( ) => fiberRuntime . scopeTag ) ,
176- core . tap ( ( { entry, scope } ) =>
177- scope . addFinalizer ( ( ) =>
178- core . suspend ( ( ) => {
179- entry . refCount --
180- if ( entry . refCount > 0 ) {
181- return core . void
182- } else if ( self . idleTimeToLive === undefined ) {
183- if ( self . state . _tag === "Open" ) {
184- MutableHashMap . remove ( self . state . map , key )
185- }
186- return core . scopeClose ( entry . scope , core . exitVoid )
187- }
188- return coreEffect . sleep ( self . idleTimeToLive ) . pipe (
189- core . interruptible ,
190- core . zipRight ( core . suspend ( ( ) => {
191- if ( self . state . _tag === "Open" && entry . refCount === 0 ) {
192- MutableHashMap . remove ( self . state . map , key )
193- return core . scopeClose ( entry . scope , core . exitVoid )
194- }
195- return core . void
196- } ) ) ,
197- fiberRuntime . ensuring ( core . sync ( ( ) => {
198- entry . fiber = undefined
199- } ) ) ,
200- circular . forkIn ( self . scope ) ,
201- core . tap ( ( fiber ) => {
202- entry . fiber = fiber
203- } ) ,
204- self . semaphore . withPermits ( 1 )
205- )
206- } )
207- )
208- ) ,
209- core . flatMap ( ( { entry } ) => restore ( core . deferredAwait ( entry . deferred ) ) )
210- )
203+ return core . void
204+ } ) ) ,
205+ fiberRuntime . ensuring ( core . sync ( ( ) => {
206+ entry . fiber = undefined
207+ } ) ) ,
208+ circular . forkIn ( self . scope ) ,
209+ core . tap ( ( fiber ) => {
210+ entry . fiber = fiber
211+ } ) ,
212+ self . semaphore . withPermits ( 1 )
211213 )
212- }
213- )
214+ } )
214215
215216/** @internal */
216217export const keys = < K , A , E > ( self : RcMap . RcMap < K , A , E > ) : Effect < Array < K > > => {
@@ -219,3 +220,22 @@ export const keys = <K, A, E>(self: RcMap.RcMap<K, A, E>): Effect<Array<K>> => {
219220 impl . state . _tag === "Closed" ? core . interrupt : core . succeed ( MutableHashMap . keys ( impl . state . map ) )
220221 )
221222}
223+
224+ /** @internal */
225+ export const invalidate : {
226+ < K > ( key : K ) : < A , E > ( self : RcMap . RcMap < K , A , E > ) => Effect < void >
227+ < K , A , E > ( self : RcMap . RcMap < K , A , E > , key : K ) : Effect < void >
228+ } = dual (
229+ 2 ,
230+ core . fnUntraced ( function * < K , A , E > ( self_ : RcMap . RcMap < K , A , E > , key : K ) {
231+ const self = self_ as RcMapImpl < K , A , E >
232+ if ( self . state . _tag === "Closed" ) return
233+ const o = MutableHashMap . get ( self . state . map , key )
234+ if ( o . _tag === "None" ) return
235+ const entry = o . value
236+ MutableHashMap . remove ( self . state . map , key )
237+ if ( entry . refCount > 0 ) return
238+ yield * core . scopeClose ( entry . scope , core . exitVoid )
239+ if ( entry . fiber ) yield * core . interruptFiber ( entry . fiber )
240+ } )
241+ )
0 commit comments