Created
June 9, 2011 05:33
-
-
Save panesofglass/1016122 to your computer and use it in GitHub Desktop.
Updated ObjectPool from fssnip.net/5H
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| namespace Fracture | |
| /// Agent alias for MailboxProcessor | |
| type Agent<'a> = MailboxProcessor<'a> | |
| /// One of three messages for our Object Pool agent | |
| type PoolMessage<'a> = | |
| | Get of AsyncReplyChannel<'a> | |
| | Count of AsyncReplyChannel<int> | |
| | Put of 'a | |
| | Clear of AsyncReplyChannel<'a list> | |
| /// Object pool representing a reusable pool of objects | |
| type ObjectPool<'a>(generate: unit -> 'a, initialPoolCount, autoGrow) = | |
| let initial = [ for x in 1..initialPoolCount do yield generate() ] | |
| let agent = Agent.Start(fun inbox -> | |
| let rec loop xs = async { | |
| let! msg = inbox.Receive() | |
| match msg with | |
| | Get(reply) -> | |
| let res = match xs with | |
| | hd::tl -> reply.Reply hd; tl | |
| | [] as empty -> | |
| // TODO: Create a state machine that checks the autoGrow argument and blocks additional access if it's full. | |
| //if autoGrow then | |
| reply.Reply (generate()) | |
| empty | |
| return! loop res | |
| | Count(reply) -> | |
| reply.Reply xs.Length | |
| return! loop xs | |
| | Put(x)-> | |
| return! loop (x::xs) | |
| | Clear(reply) -> | |
| reply.Reply xs | |
| return! loop List.empty<'a> } | |
| loop initial) | |
| /// Creates an object pool that remains at a constant size | |
| new (generate, count) = ObjectPool<'a>(generate, count, false) | |
| /// Returns the number of items checked into the pool | |
| member this.Count() = agent.PostAndAsyncReply(Count) | |
| /// Gets an item from the pool or if there are none present use the generator | |
| member this.Get(item) = agent.PostAndAsyncReply(Get) | |
| /// Puts an item into the pool | |
| member this.Put(item) = agent.Post(Put item) | |
| /// Clears the object pool, returning all of the data that was in the pool. | |
| member this.ToListAndClear() = agent.PostAndAsyncReply(Clear) |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I added a Count message/method and fixed
Put(you forgot to tellagent.Postwhat type of message you were sending). I also switched out the list initializer to use list comprehensions, which in this case makes it a bit more readable, imho. Finally, I added an overload that could be used in the future to make a blocking version using a state machine.I'm currently in the process of pushing this into Fracture.