λ

Cube Manual

Table of Contents

[in package MGL-CUBE]

λ

1 Introduction

This is the library on which MGL-MAT (see MAT Manual) is built. The idea of automatically translating between various representations may be useful for other applications, so this got its own package and all ties to MGL-MAT has been severed.

This package defines CUBE, an abstract base class that provides a framework for automatic conversion between various representations of the same data. To define a cube, CUBE needs to be subclassed and the Facet Extension API be implemented.

If you are only interested in how to use cubes in general, read Basics, Lifetime and Facet Barriers.

If you want to implement a new cube datatype, then see Facets, Facet Extension API, and The Default Implementation of CALL-WITH-FACET*.

λ

2 Basics

Here we learn what a CUBE is and how to access the data in it with WITH-FACET.

λ

3 Synchronization

Cubes keep track of which facets are used, which are up-to-date to be able to perform automatic translation between facets. WITH-FACET and other operations access and make changes to this metadata so thread safety is a concern. In this section, we detail how to relax the default thread safety guarantees.

A related concern is async signal safety which arises most often when C-c'ing or killing a thread or when the extremely nasty WITH-TIMEOUT macro is used. In a nutshell, changes to cube metadata are always made with interrupts disabled so things should be async signal safe.

λ

4 Facets

The basic currency for implementing new cube types is the FACET. Simply using a cube only involves facet names and values, never facets themselves.

λ

5 Facet Extension API

Many of the generic functions in this section take FACET arguments. FACET is a structure and is not intended to be subclassed. To be able to add specialized methods, the name of the facet (FACET-NAME) is also passed as the argument right in front of the corresponding facet argument.

In summary, define EQL specializers on facet name arguments, and use FACET-DESCRIPTION to associate arbitrary information with facets.

PAX integration follows, don't worry about it if you don't use PAX, but you really should (see PAX Manual).

Also see The Default Implementation of CALL-WITH-FACET*.

λ

6 The Default Implementation of CALL-WITH-FACET*

λ

7 Lifetime

Lifetime management of facets is manual (but facets of garbage cubes are freed automatically by a finalizer, see MAKE-FACET*). One may destroy a single facet or all facets of a cube with DESTROY-FACET and DESTROY-CUBE, respectively. Also see Facet Barriers.

In some cases it is useful to declare the intent to use a facet in the future to prevent its destruction. Hence, every facet has reference count which starts from 0. The reference count is incremented and decremented by ADD-FACET-REFERENCE-BY-NAME and REMOVE-FACET-REFERENCE-BY-NAME, respectively. If it is positive, then the facet will not be destroyed by explicit DESTROY-FACET and DESTROY-CUBE calls, but it will still be destroyed by the finalizer to prevent resource leaks caused by stray references.

λ

7.1 Facet Barriers

A facility to control lifetime of facets tied to a dynamic extent. Also see Lifetime.