github.com/janelia-flyem/dvid@v1.0.0/datatype/labelarray/keys.go (about)

     1  /*
     2  	This file supports keyspaces for label block data types.
     3  */
     4  
     5  package labelarray
     6  
     7  import (
     8  	"encoding/binary"
     9  	"fmt"
    10  
    11  	"github.com/janelia-flyem/dvid/datastore"
    12  	"github.com/janelia-flyem/dvid/dvid"
    13  	"github.com/janelia-flyem/dvid/storage"
    14  )
    15  
    16  const (
    17  	// keyUnknown should never be used and is a check for corrupt or incorrectly set keys
    18  	keyUnknown storage.TKeyClass = 0
    19  
    20  	// reserved type-specific key for metadata
    21  	keyProperties = datastore.PropertyTKeyClass
    22  
    23  	// key = scale + block coord
    24  	keyLabelBlock = 186
    25  
    26  	// key = label. value = labels.LabelMeta
    27  	keyLabelIndex = 187
    28  
    29  	// Used to store max label on commit for each version of the instance.
    30  	keyLabelMax = 237
    31  
    32  	// Stores the single repo-wide max label for the instance.  Used for new labels on split.
    33  	keyRepoLabelMax = 238
    34  )
    35  
    36  // DescribeTKeyClass returns a string explanation of what a particular TKeyClass
    37  // is used for.  Implements the datastore.TKeyClassDescriber interface.
    38  func (d *Data) DescribeTKeyClass(tkc storage.TKeyClass) string {
    39  	switch tkc {
    40  	case keyLabelBlock:
    41  		return "labelarray scale + block coord key"
    42  	case keyLabelIndex:
    43  		return "labelarray label index key"
    44  	case keyLabelMax:
    45  		return "labelarray label max key"
    46  	case keyRepoLabelMax:
    47  		return "labelarray repo label max key"
    48  	default:
    49  	}
    50  	return "unknown labelarray key"
    51  }
    52  
    53  var (
    54  	maxLabelTKey     = storage.NewTKey(keyLabelMax, nil)
    55  	maxRepoLabelTKey = storage.NewTKey(keyRepoLabelMax, nil)
    56  )
    57  
    58  // NewBlockTKey returns a TKey for a label block, which is a slice suitable for
    59  // lexicographical ordering on zyx coordinates.
    60  func NewBlockTKey(scale uint8, idx dvid.Index) storage.TKey {
    61  	izyx := idx.(*dvid.IndexZYX)
    62  	return NewBlockTKeyByCoord(scale, izyx.ToIZYXString())
    63  }
    64  
    65  // NewBlockTKeyByCoord returns a TKey for a block coord in string format.
    66  func NewBlockTKeyByCoord(scale uint8, izyx dvid.IZYXString) storage.TKey {
    67  	buf := make([]byte, 13)
    68  	buf[0] = byte(scale)
    69  	copy(buf[1:], []byte(izyx))
    70  	return storage.NewTKey(keyLabelBlock, buf)
    71  }
    72  
    73  // DecodeBlockTKey returns a spatial index from a label block key.
    74  // TODO: Extend this when necessary to allow any form of spatial indexing like CZYX.
    75  func DecodeBlockTKey(tk storage.TKey) (scale uint8, idx *dvid.IndexZYX, err error) {
    76  	ibytes, err := tk.ClassBytes(keyLabelBlock)
    77  	if err != nil {
    78  		return 0, nil, err
    79  	}
    80  	if len(ibytes) != 13 {
    81  		err = fmt.Errorf("bad labelarray block key of %d bytes: %v", len(ibytes), ibytes)
    82  		return
    83  	}
    84  	scale = uint8(ibytes[0])
    85  	idx = new(dvid.IndexZYX)
    86  	if err = idx.IndexFromBytes(ibytes[1:]); err != nil {
    87  		err = fmt.Errorf("Cannot recover ZYX index from image block key %v: %v\n", tk, err)
    88  	}
    89  	return
    90  }
    91  
    92  // NewLabelIndexTKey returns a TKey corresponding to a label.  Value will hold block coords that contain the label.
    93  func NewLabelIndexTKey(label uint64) storage.TKey {
    94  	buf := make([]byte, 8)
    95  	binary.BigEndian.PutUint64(buf, label)
    96  	return storage.NewTKey(keyLabelIndex, buf)
    97  }
    98  
    99  // DecodeLabelIndexTKey parses a TKey and returns the corresponding label.
   100  func DecodeLabelIndexTKey(tk storage.TKey) (label uint64, err error) {
   101  	ibytes, err := tk.ClassBytes(keyLabelIndex)
   102  	if err != nil {
   103  		return
   104  	}
   105  	label = binary.BigEndian.Uint64(ibytes[0:8])
   106  	return
   107  }