Skip to content

Instantly share code, notes, and snippets.

@palladin
Created August 6, 2014 11:40
Show Gist options
  • Save palladin/1e9d6d8b44360951e85f to your computer and use it in GitHub Desktop.
Save palladin/1e9d6d8b44360951e85f to your computer and use it in GitHub Desktop.
GroupingAdd
type Grouping<'T> = { IndexRef : int ref; ArrayRef : 'T [] ref }
let rec groupingAdd (value : 'T) (grouping : Grouping<'T>) =
let indexRef = grouping.IndexRef
let arrayRef = grouping.ArrayRef
let array = !arrayRef
if Object.ReferenceEquals(array, null) then
groupingAdd value grouping
else
let index = Interlocked.Increment(indexRef)
if index < array.Length then
array.[index] <- value
let mutable array' = array
while not <| Object.ReferenceEquals(array', !arrayRef) || Object.ReferenceEquals(array', null) do
array' <- !arrayRef
if not <| Object.ReferenceEquals(array', null) then
array'.[index] <- value
else
lock grouping (fun () ->
if Object.ReferenceEquals(array, !arrayRef) then
arrayRef := null
let index = array.Length
let newArray = Array.zeroCreate<'T> (array.Length * 2)
Array.Copy(array, newArray, index)
indexRef := index - 1
arrayRef := newArray
)
groupingAdd value grouping
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment