weak

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 13, 2022 License: MIT Imports: 4 Imported by: 4

README

GoDoc

weakref map in go 1.18

This is a weakref map for Go 1.18, with some inspiration from xeus2001's weakref implementation.

This provides both a weak.Ref object to store weak references, and a weak.Map object for maps.

Usage

import "github.com/KarpelesLab/weak"

var m = weak.NewMap[uint64, Object]()

// instanciate/get an object
func Get(id uint64) (*Object, error) {
	// try to get from cache
	var obj *Object
	if obj = m.Get(id); obj == nil {
		// create new
		obj = m.Set(id, &Object{id: id}) // this will return an existing object if already existing
	}

	obj.initOnce.Do(obj.init) // use sync.Once to ensure init happens only once
	return obj, obj.err
}

func main() {
	obj, err := Get(1234)
	// ...
}

As to the Object implementation, it could look like:

type Object struct {
	id       uint64
	initOnce sync.Once
	f        *os.File
	err      error
}

func (o *Object) init() {
	o.f, o.err = os.Open(fmt.Sprintf("/tmp/file%d.bin", o.id))
}

func (o *Object) Destroy() {
	if o.f != nil {
		o.f.Close()
	}
}
File example

Simple example that allows opening multiple files without having to care about closing these and reading random data using ReadAt.

import {
	"github.com/KarpelesLab/weak"
	"os"
	"sync"
}

type File struct {
	*os.File
	err  error
	open sync.Once
}

var fileCache = weak.NewMap[string, File]()

func Open(filepath string) (io.ReaderAt, error) (
	var f *File
	if f = fileCache.Get(filepath); f == nil {
		f = fileCache.Set(filepath, &File{})
	}
	f.open.Do(func() {
		f.File, f.err = os.Open(filepath)
	})
	return f, f.err
}

func (f *File) Destroy() {
	if f.File != nil {
		f.File.Close()
	}
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Destroyable

type Destroyable interface {
	Destroy()
}

Object implementing Destroyable added to a Map will have their Destroy() method called when the object is about to be removed. This replaces use of a finalizer.

type Map

type Map[K comparable, T any] struct {
	// contains filtered or unexported fields
}

Map is a thread safe map for objects to be kept as weak references, useful for cache/etc

func NewMap

func NewMap[K comparable, T any]() *Map[K, T]

NewMap returns a new weak reference map

func (*Map[K, T]) Delete

func (w *Map[K, T]) Delete(k K)

Delete removes element at key k from the map. This doesn't call Destroy immediately as this would typically happen when the object is actually cleared by the garbage collector and instances of said object may still be used.

func (*Map[K, T]) Get

func (w *Map[K, T]) Get(k K) *T

Get returns the value at index k in the map. If no such value exists, nil is returned.

func (*Map[K, T]) Set

func (w *Map[K, T]) Set(k K, v *T) *T

Set inserts the value v if it does not already exists, and return it. If a value v already exists, then the previous value is returned.

type Ref

type Ref[T any] struct {
	// contains filtered or unexported fields
}

Ref is a weak reference to a Go object

func NewRef

func NewRef[T any](v *T) *Ref[T]

NewRef returns a reference to the object v that may be cleared by the garbage collector

func NewRefDestroyer

func NewRefDestroyer[T any](v *T, destroy func(v *T, wr *Ref[T])) *Ref[T]

NewRefDestroyer returns a reference to the object v that may be cleared by the garbage collector, in which case destroy will be called.

func (*Ref[T]) Get

func (wr *Ref[T]) Get() *T

Get returns the value for a given weak reference pointer

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL