imap

package
v0.0.4 Latest Latest
Warning

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

Go to latest
Published: Nov 23, 2023 License: AGPL-3.0 Imports: 13 Imported by: 0

Documentation

Overview

Package imap

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrFinalized = errors.New("IMap is finalized")

Functions

This section is empty.

Types

type DiskMap

type DiskMap struct {
	Path string
}

DiskMap represents an engine that persistently stores data on disk.

func (DiskMap) Forward

func (de DiskMap) Forward() (HashMap[impl.Label, TripleID], error)

func (DiskMap) Reverse

func (de DiskMap) Reverse() (HashMap[impl.ID, impl.Label], error)

type DiskStorage

type DiskStorage[Key comparable, Value any] struct {
	DB *leveldb.DB

	MarshalKey     func(key Key) ([]byte, error)
	UnmarshalKey   func(dest *Key, src []byte) error
	MarshalValue   func(value Value) ([]byte, error)
	UnmarshalValue func(dest *Value, src []byte) error
}

DiskStorage implements Storage as an in-memory storage

func NewDiskStorage

func NewDiskStorage[Key comparable, Value any](path string) (*DiskStorage[Key, Value], error)

NewDiskStorage creates a new disk-based storage with the given options. If the filepath already exists, it is deleted.

func (*DiskStorage[Key, Value]) Close

func (ds *DiskStorage[Key, Value]) Close() error

func (*DiskStorage[Key, Value]) Compact

func (ds *DiskStorage[Key, Value]) Compact() error

func (*DiskStorage[Key, Value]) Count

func (ds *DiskStorage[Key, Value]) Count() (count uint64, err error)

Count returns the number of objects in this DiskStorage.

func (*DiskStorage[Key, Value]) Delete

func (ds *DiskStorage[Key, Value]) Delete(key Key) error

Delete deletes the given key from this storage

func (*DiskStorage[Key, Value]) Finalize

func (ds *DiskStorage[Key, Value]) Finalize() error

func (*DiskStorage[Key, Value]) Get

func (ds *DiskStorage[Key, Value]) Get(key Key) (v Value, b bool, err error)

Get returns the given value if it exists

func (*DiskStorage[Key, Value]) GetZero

func (ds *DiskStorage[Key, Value]) GetZero(key Key) (Value, error)

GetZero returns the value associated with Key, or the zero value otherwise.

func (*DiskStorage[Key, Value]) Has

func (ds *DiskStorage[Key, Value]) Has(key Key) (bool, error)

func (*DiskStorage[Key, Value]) Iterate

func (ds *DiskStorage[Key, Value]) Iterate(f func(Key, Value) error) error

Iterate calls f for all entries in Storage. there is no guarantee on order.

func (*DiskStorage[Key, Value]) Set

func (ds *DiskStorage[Key, Value]) Set(key Key, value Value) error

type HashMap

type HashMap[Key comparable, Value any] interface {
	// Close closes this store
	Close() error

	// Compact informs the store to perform any optimizations or compaction of internal data structures.
	Compact() error

	// Finalize indicates to the implementation that no more mutating calls will be made.
	// A mutating call is one to Compact, Set or Delete.
	Finalize() error

	// Set sets the given key to the given value
	Set(key Key, value Value) error

	// Get retrieves the value for Key from the given storage.
	// The second value indicates if the value was found.
	Get(key Key) (Value, bool, error)

	// GetZero is like Get, but when the value does not exist returns the zero value
	GetZero(key Key) (Value, error)

	// Has is like Get, but returns only the second value.
	Has(key Key) (bool, error)

	// Delete deletes the given key from this storage
	Delete(key Key) error

	// Iterate calls f for all entries in Storage.
	//
	// When any f returns a non-nil error, that error is returned immediately to the caller
	// and iteration stops.
	//
	// There is no guarantee on order.
	Iterate(f func(Key, Value) error) error

	// Count counts the number of elements in this store
	Count() (uint64, error)
}

HashMap is something that stores key-value pairs

type IMap

type IMap struct {
	// contains filtered or unexported fields
}

IMap holds forward and reverse mapping from Labels to IDs. An IMap may be read concurrently; however any operations which change internal state are not safe to access concurrently.

The zero map is not ready for use; it should be initialized using a call to [Reset].

Example
package main

import (
	"fmt"
	"math/big"
	"strconv"
	"testing"

	"github.com/FAU-CDI/hangover/internal/triplestore/impl"
)

// cspell:words itol

func main() {

	var mp IMap
	mp.Reset(&MemoryMap{})

	lid := func(prefix impl.Label) func(id impl.ID, err error) {
		return func(id impl.ID, err error) {
			fmt.Println(prefix, id, err)
		}
	}

	lid2 := func(prefix impl.Label) func(id TripleID, err error) {
		return func(id TripleID, err error) {
			fmt.Println(prefix, id.Canonical, err)
		}
	}

	lstr := func(prefix impl.Label) func(value impl.Label, err error) {
		return func(value impl.Label, err error) {
			fmt.Println(prefix, value, err)
		}
	}

	lid2("add")(mp.Add("hello"))
	lid2("add")(mp.Add("world"))
	lid2("add")(mp.Add("earth"))

	lid2("add<again>")(mp.Add("hello"))
	lid2("add<again>")(mp.Add("world"))
	lid2("add<again>")(mp.Add("earth"))

	lid("get")(mp.Forward("hello"))
	lid("get")(mp.Forward("world"))
	lid("get")(mp.Forward("earth"))

	lstr("reverse")(mp.Reverse(*new(impl.ID).LoadInt(big.NewInt(1))))
	lstr("reverse")(mp.Reverse(*new(impl.ID).LoadInt(big.NewInt(2))))
	lstr("reverse")(mp.Reverse(*new(impl.ID).LoadInt(big.NewInt(3))))

	mp.MarkIdentical("earth", "world")

	lstr("reverse<again>")(mp.Reverse(*new(impl.ID).LoadInt(big.NewInt(1))))
	lstr("reverse<again>")(mp.Reverse(*new(impl.ID).LoadInt(big.NewInt(3))))

	lid2("add<again>")(mp.Add("hello"))
	lid2("add<again>")(mp.Add("world"))
	lid2("add<again>")(mp.Add("earth"))

}

// itol is like strconv.itoa, but returns a label
func itol(i int) impl.Label {
	return impl.Label(strconv.Itoa(i))
}

// mapTest performs a test for a given engine
func mapTest(t *testing.T, engine Map, N int) {
	t.Helper()

	var mp IMap
	mp.Reset(engine)
	defer mp.Close()

	// make i == i + 1
	for i := 0; i < N; i += 2 {
		canon, err := mp.MarkIdentical(itol(i), itol(i+1))
		if err != nil {
			t.Fatalf("MarkIdentical returned error %s", err)
		}
		got := canon.Int(big.NewInt(0)).Int64()
		want := int64(i + 1)
		if got != want {
			t.Errorf("MarkIdentical() got id = %s, want = %d", canon, want)
		}
	}

	// check that forward mappings work
	for i := 0; i < N; i++ {
		id, err := mp.Forward(itol(i))
		if err != nil {
			t.Errorf("Forward() returned error %s", err)
		}
		got := int(id.Int(big.NewInt(0)).Int64())
		want := i - (i % 2) + 1
		if got != want {
			t.Errorf("Forward() got = %d, want = %d", got, want)
		}
	}

	// check that reverse mappings work
	var id impl.ID
	var big big.Int
	for i := 1; i < N; i++ {
		big.SetInt64(int64(i))

		got, err := mp.Reverse(*id.LoadInt(&big))
		if err != nil {
			t.Errorf("Reverse() returned error %s", err)
		}
		want := itol(i - 1)

		if got != want {
			t.Errorf("Reverse(%s) got = %q, want = %q", &big, got, want)
		}
	}
}
Output:

add ID(1) <nil>
add ID(2) <nil>
add ID(3) <nil>
add<again> ID(1) <nil>
add<again> ID(2) <nil>
add<again> ID(3) <nil>
get ID(1) <nil>
get ID(2) <nil>
get ID(3) <nil>
reverse hello <nil>
reverse world <nil>
reverse earth <nil>
reverse<again> hello <nil>
reverse<again> earth <nil>
add<again> ID(1) <nil>
add<again> ID(3) <nil>
add<again> ID(3) <nil>

func (*IMap) Add

func (mp *IMap) Add(label impl.Label) (ids TripleID, err error)

Add inserts label into this IMap and returns a pair of corresponding ids. The first is the canonical id (for use in lookups) whereas the second is the original id.

When label (or any object marked identical to ID) already exists in this IMap, returns the corresponding ID.

func (*IMap) AddNew

func (mp *IMap) AddNew(label impl.Label) (ids TripleID, old bool, err error)

AddNew behaves like Add, except additionally returns a boolean indicating if the returned id existed previously.

func (*IMap) Close

func (mp *IMap) Close() error

Close closes any storages related to this IMap.

Calling close multiple times results in err = nil.

func (*IMap) Compact

func (mp *IMap) Compact() error

Compact indicates to the implementation to perform any optimization of internal data structures.

func (*IMap) Finalize

func (mp *IMap) Finalize() error

Finalize indicates that no more mutating calls will be made. A mutable call is one made to Compact, Add, AddNew or MarkIdentical.

func (*IMap) Forward

func (mp *IMap) Forward(label impl.Label) (impl.ID, error)

Forward returns the id corresponding to the given label.

If the label is not contained in this map, the zero ID is returned. The zero ID is never returned for a valid id.

func (*IMap) Get

func (mp *IMap) Get(label impl.Label) (ids TripleID, ok bool, err error)

Get behaves like Add, but in case the label has no associated mappings returns ok = false and does not modify the state.

func (*IMap) IdentityMap

func (mp *IMap) IdentityMap(storage HashMap[impl.Label, impl.Label]) error

IdentityMap writes canonical label mappings to the given storage.

Concretely a pair (L1, L2) is written to storage iff

mp.Reverse(mp.Forward(L1)) == L2 && L1 != L2

func (*IMap) MarkIdentical

func (mp *IMap) MarkIdentical(new, old impl.Label) (canonical impl.ID, err error)

MarkIdentical marks the two labels as being identical. It returns the ID corresponding to the label new.

Once applied, all future calls to [Forward] or [Add] with old will act as if being called by new. A previous ID corresponding to old (if any) is no longer valid.

NOTE(twiesing): Each call to MarkIdentical potentially requires iterating over all calls that were previously added to this map. This is a potentially slow operation and should be avoided.

func (*IMap) Next

func (mp *IMap) Next() impl.ID

Next returns a new unused id within this map It is always valid.

func (*IMap) Reset

func (mp *IMap) Reset(engine Map) error

Reset resets this IMap to be empty, closing any previously opened files

func (*IMap) Reverse

func (mp *IMap) Reverse(id impl.ID) (impl.Label, error)

Reverse returns the label corresponding to the given id. When id is not contained in this map, the zero value of the label type is contained.

type Map

type Map interface {
	Forward() (HashMap[impl.Label, TripleID], error)
	Reverse() (HashMap[impl.ID, impl.Label], error)
}

Map represents the backend of an Imap and creates appropriate key-value stores.

type Memory

type Memory[Key comparable, Value any] struct {
	// contains filtered or unexported fields
}

Memory contains the main in-memory value

func MakeMemory

func MakeMemory[Key comparable, Value any](size int) Memory[Key, Value]

MakeMemory makes a new memory instance

func (*Memory[Key, Value]) Close

func (ims *Memory[Key, Value]) Close() error

Close closes this MapStorage, deleting all values

func (Memory[Key, Value]) Compact

func (Memory[Key, Value]) Compact() error

Compact causes any changes to be flushed to disk and performs common cleanup tasks

func (Memory[Key, Value]) Count

func (ims Memory[Key, Value]) Count() (uint64, error)

func (Memory[Key, Value]) Delete

func (ims Memory[Key, Value]) Delete(key Key) error

Delete deletes the given key from this storage

func (Memory[Key, Value]) Finalize

func (ims Memory[Key, Value]) Finalize() error

Finalize makes this map read-only. It is a no-op.

func (Memory[Key, Value]) Get

func (ims Memory[Key, Value]) Get(key Key) (Value, bool, error)

Get returns the given value if it exists

func (Memory[Key, Value]) GetZero

func (ims Memory[Key, Value]) GetZero(key Key) (Value, error)

GetZero returns the value associated with Key, or the zero value otherwise.

func (*Memory[Key, Value]) GobDecode

func (m *Memory[Key, Value]) GobDecode(src []byte) error

func (Memory[Key, Value]) GobEncode

func (m Memory[Key, Value]) GobEncode() ([]byte, error)

func (Memory[Key, Value]) Has

func (ims Memory[Key, Value]) Has(key Key) (bool, error)

func (Memory[Key, Value]) IsNil

func (m Memory[Key, Value]) IsNil() bool

func (Memory[Key, Value]) Iterate

func (ims Memory[Key, Value]) Iterate(f func(Key, Value) error) error

Iterate calls f for all entries in Storage. there is no guarantee on order.

func (Memory[Key, Value]) Set

func (ims Memory[Key, Value]) Set(key Key, value Value) error

type MemoryMap

type MemoryMap struct {
	FStorage Memory[impl.Label, TripleID]
	RStorage Memory[impl.ID, impl.Label]
}

MemoryMap holds forward and backward maps in memory. It implements Map.

func (*MemoryMap) Close

func (me *MemoryMap) Close() error

func (*MemoryMap) Forward

func (me *MemoryMap) Forward() (HashMap[impl.Label, TripleID], error)

func (*MemoryMap) Reverse

func (me *MemoryMap) Reverse() (HashMap[impl.ID, impl.Label], error)

type TripleID

type TripleID struct {
	// Canonical holds the id of this triple, that is normalized for inverses and identities.
	Canonical impl.ID

	// Literal is the original id of the triple found in the original triple.
	// It always refers to the original value, no matter which value it actually has.
	Literal impl.ID
}

TripleID represents the id of a tripleID

func (TripleID) Marshal

func (ti TripleID) Marshal() ([]byte, error)

Marshal marshals this TripleID into a []byte

func (*TripleID) Unmarshal

func (ti *TripleID) Unmarshal(src []byte) error

Unmarshal reads this TripleID from a []byte

Jump to

Keyboard shortcuts

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