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

     1  /*
     2  	This file supports keyspaces for point annotation data type.
     3  */
     4  
     5  package annotation
     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 = iota
    19  
    20  	// reserved type-specific key for metadata
    21  	keyProperties = datastore.PropertyTKeyClass
    22  
    23  	// key is tag id.  value is serialization of the tag name and all synaptic elements it contains.
    24  	keyTag = 70
    25  
    26  	// key is label.  value is serialization of all synaptic elements associated with a label.
    27  	keyLabel = 71
    28  
    29  	// key is block coordinate.  value is serialization of synaptic elements.
    30  	keyBlock = 72
    31  )
    32  
    33  // DescribeTKeyClass returns a string explanation of what a particular TKeyClass
    34  // is used for.  Implements the datastore.TKeyClassDescriber interface.
    35  func (d *Data) DescribeTKeyClass(tkc storage.TKeyClass) string {
    36  	switch tkc {
    37  	case keyTag:
    38  		return "annotation tag key"
    39  	case keyLabel:
    40  		return "annotation label key"
    41  	case keyBlock:
    42  		return "annotation block coord key"
    43  	default:
    44  	}
    45  	return "unknown annotation key"
    46  }
    47  
    48  // NewTagTKey returns a TKey for a given tag.
    49  func NewTagTKey(tag Tag) (storage.TKey, error) {
    50  	if len(tag) == 0 {
    51  		return nil, fmt.Errorf("empty tag not permitted")
    52  	}
    53  	return storage.NewTKey(keyTag, append([]byte(tag), 0)), nil
    54  }
    55  
    56  // DecodeTagTKey returns the Tag corresponding to this type-specific key.
    57  func DecodeTagTKey(tk storage.TKey) (Tag, error) {
    58  	ibytes, err := tk.ClassBytes(keyTag)
    59  	if err != nil {
    60  		return "", err
    61  	}
    62  	sz := len(ibytes) - 1
    63  	if sz <= 0 {
    64  		return "", fmt.Errorf("empty tag")
    65  	}
    66  	if ibytes[sz] != 0 {
    67  		return "", fmt.Errorf("expected 0 byte ending tag key, got %d", ibytes[sz])
    68  	}
    69  	return Tag(ibytes[:sz]), nil
    70  }
    71  
    72  func NewLabelTKey(label uint64) storage.TKey {
    73  	buf := make([]byte, 8)
    74  	binary.BigEndian.PutUint64(buf, label)
    75  	return storage.NewTKey(keyLabel, buf)
    76  }
    77  
    78  func DecodeLabelTKey(tk storage.TKey) (label uint64, err error) {
    79  	ibytes, err := tk.ClassBytes(keyLabel)
    80  	if err != nil {
    81  		return
    82  	}
    83  	label = binary.BigEndian.Uint64(ibytes[0:8])
    84  	return
    85  }
    86  
    87  func BlockTKeyRange() (min, max storage.TKey) {
    88  	return NewBlockTKey(dvid.MinChunkPoint3d), NewBlockTKey(dvid.MaxChunkPoint3d)
    89  }
    90  
    91  func BlockTKeyZRange(begBlockCoord, endBlockCoord dvid.ChunkPoint3d) (min, max storage.TKey) {
    92  	begTKey := NewBlockTKey(dvid.ChunkPoint3d{dvid.MinChunkPoint3d[0], dvid.MinChunkPoint3d[1], begBlockCoord[2]})
    93  	endTKey := NewBlockTKey(dvid.ChunkPoint3d{dvid.MaxChunkPoint3d[0], dvid.MaxChunkPoint3d[1], endBlockCoord[2]})
    94  	return begTKey, endTKey
    95  }
    96  
    97  func NewBlockTKey(pt dvid.ChunkPoint3d) storage.TKey {
    98  	idx := dvid.IndexZYX(pt)
    99  	return storage.NewTKey(keyBlock, idx.Bytes())
   100  }
   101  
   102  func DecodeBlockTKey(tk storage.TKey) (pt dvid.ChunkPoint3d, err error) {
   103  	ibytes, err := tk.ClassBytes(keyBlock)
   104  	if err != nil {
   105  		return
   106  	}
   107  	var idx dvid.IndexZYX
   108  	if err = idx.IndexFromBytes(ibytes); err != nil {
   109  		return
   110  	}
   111  	pt = dvid.ChunkPoint3d(idx)
   112  	return
   113  }