// Returns the slice to which any down-resolution data should be written for the given higher-res block coord. func (d *Data) getLoresCache(v dvid.VersionID, block dvid.IZYXString) ([]byte, error) { // Setup the octant buffer and block cache. downresBlock, err := block.Downres() if err != nil { return nil, fmt.Errorf("unable to downres labelblk %q block: %v\n", d.DataName(), err) } var chunkPt dvid.ChunkPoint3d chunkPt, err = block.ToChunkPoint3d() if err != nil { return nil, err } // determine which down-res sector (0-7 where it's x, then y, then z ordering) in 2x2x2 block // the given block will sit. nx := chunkPt[0] % 2 ny := chunkPt[1] % 2 nz := chunkPt[2] % 2 sector := (nz * 4) + (ny * 2) + nx // Get the sector slice from the octant corresponding to the downres block coord. // Initialize blockCache if necessary. d.vcache_mu.Lock() defer d.vcache_mu.Unlock() var bc blockCache if d.vcache == nil { d.vcache = make(map[dvid.VersionID]blockCache) } else { var found bool bc, found = d.vcache[v] if !found { bc = nil } } if bc == nil { bc = make(blockCache) d.vcache[v] = bc } // Get the relevant slice. oct := bc[downresBlock] if oct[sector] == nil { nbytes := d.BlockSize().Prod() // actually / 8 (downres 2^3) then * 8 bytes for label oct[sector] = make([]byte, nbytes) } d.vcache[v][downresBlock] = oct return oct[sector], nil }
// Store a label into a block using RLEs. func (d *Data) storeRLEs(data []byte, toLabel uint64, zyxStr dvid.IZYXString, rles dvid.RLEs) error { // Get the block coordinate bcoord, err := zyxStr.ToChunkPoint3d() if err != nil { return err } // Get the first voxel offset blockSize := d.BlockSize() offset := bcoord.MinPoint(blockSize) // Iterate through rles, getting span for this block of bytes. nx := blockSize.Value(0) * 8 nxy := nx * blockSize.Value(1) for _, rle := range rles { p := rle.StartPt().Sub(offset) i := p.Value(2)*nxy + p.Value(1)*nx + p.Value(0)*8 for n := int32(0); n < rle.Length(); n++ { binary.LittleEndian.PutUint64(data[i:i+8], toLabel) i += 8 } } return nil }