Skip to content

Instantly share code, notes, and snippets.

@whitehat101
Last active October 15, 2018 10:35
Show Gist options
  • Save whitehat101/5129dcfb6e0ad7464fe083a1d50749b0 to your computer and use it in GitHub Desktop.
Save whitehat101/5129dcfb6e0ad7464fe083a1d50749b0 to your computer and use it in GitHub Desktop.
JavaScript reference counting (for Blobs w/ URL.createObjectURL / URL.revokeObjectURL)
export default (
create = URL.createObjectURL
free = URL.revokeObjectURL
) ->
map = new Map
retain: (key) ->
if map.has key
data = map.get key
data.count++
else
data =
count: 1
value: await create key
map.set key, data
data.value
release: (key) ->
unless map.has key
throw "key(#{key}) is not allocated"
data = map.get key
data.count--
if data.count is 0
free data.value
map.delete key
else
map.set key, data
data.count
cleanup: ->
for [key, data] from do map.entries
free data.value
map.delete key
data
import refCounter from "./refCounter.coffee"
do ->
test = refCounter (key) ->
console.log "alloc: #{key}"
"blob:#{key}"
, (value) ->
console.log "free: #{value}"
await test.retain 'foo'
await test.retain 'bar'
await test.retain 'baz'
await test.retain 'foo'
test.release 'bar'
try
test.release 'bar'
catch e
console.log e
do test.cleanup
directBlobCounter = do refCounter
blob = new Blob ["data"]
url = await directBlobCounter.retain blob
url is await directBlobCounter.retain blob
await fetch(url).then (r) -> do r.text
await fetch(url).then (r) -> do r.text
directBlobCounter.release url
await fetch(url).then (r) -> do r.text
directBlobCounter.release url
try await fetch(url).then (r) -> do r.text
indirectBlobCounter = refCounter (key) ->
URL.createObjectURL getBlobFromKey key
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment