本文整理汇总了Golang中github.com/janelia-flyem/dvid/datastore.VersionedCtx.VersionID方法的典型用法代码示例。如果您正苦于以下问题:Golang VersionedCtx.VersionID方法的具体用法?Golang VersionedCtx.VersionID怎么用?Golang VersionedCtx.VersionID使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类github.com/janelia-flyem/dvid/datastore.VersionedCtx
的用法示例。
在下文中一共展示了VersionedCtx.VersionID方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: splitBlock
// Goroutine that handles splits across a lot of blocks for one label.
func (d *Data) splitBlock(ctx *datastore.VersionedCtx, op splitOp) {
defer d.MutDone(op.mutID)
store, err := d.GetOrderedKeyValueDB()
if err != nil {
dvid.Errorf("Data type labelblk had error initializing store: %v\n", err)
return
}
// Read the block.
tk := NewTKeyByCoord(op.block)
data, err := store.Get(ctx, tk)
if err != nil {
dvid.Errorf("Error on GET of labelblk with coord string %v\n", []byte(op.block))
return
}
if data == nil {
dvid.Errorf("nil label block where split was done, coord %v\n", []byte(op.block))
return
}
blockData, _, err := dvid.DeserializeData(data, true)
if err != nil {
dvid.Criticalf("unable to deserialize label block in '%s' key %v: %v\n", d.DataName(), []byte(op.block), err)
return
}
blockBytes := int(d.BlockSize().Prod() * 8)
if len(blockData) != blockBytes {
dvid.Criticalf("splitBlock: coord %v got back %d bytes, expected %d bytes\n", []byte(op.block), len(blockData), blockBytes)
return
}
// Modify the block using either voxel-level changes or coarser block-level mods.
if op.rles != nil {
if err := d.storeRLEs(blockData, op.newLabel, op.block, op.rles); err != nil {
dvid.Errorf("can't store label %d RLEs into block %s: %v\n", op.newLabel, op.block, err)
return
}
} else {
// We are doing coarse split and will replace all
if err := d.replaceLabel(blockData, op.oldLabel, op.newLabel); err != nil {
dvid.Errorf("can't replace label %d with %d in block %s: %v\n", op.oldLabel, op.newLabel, op.block, err)
return
}
}
// Write the modified block.
serialization, err := dvid.SerializeData(blockData, d.Compression(), d.Checksum())
if err != nil {
dvid.Criticalf("Unable to serialize block %s in %q: %v\n", op.block, d.DataName(), err)
return
}
if err := store.Put(ctx, tk, serialization); err != nil {
dvid.Errorf("Error in putting key %v: %v\n", tk, err)
}
// Notify any downstream downres instance.
d.publishBlockChange(ctx.VersionID(), op.mutID, op.block, blockData)
}
示例2: mergeBlock
// handles relabeling of blocks during a merge operation.
func (d *Data) mergeBlock(ctx *datastore.VersionedCtx, op mergeOp) {
defer d.MutDone(op.mutID)
store, err := d.GetKeyValueDB()
if err != nil {
dvid.Errorf("Data type labelblk had error initializing store: %v\n", err)
return
}
tk := NewTKeyByCoord(op.block)
data, err := store.Get(ctx, tk)
if err != nil {
dvid.Errorf("Error on GET of labelblk with coord string %q\n", op.block)
return
}
if data == nil {
dvid.Errorf("nil label block where merge was done!\n")
return
}
blockData, _, err := dvid.DeserializeData(data, true)
if err != nil {
dvid.Criticalf("unable to deserialize label block in '%s': %v\n", d.DataName(), err)
return
}
blockBytes := int(d.BlockSize().Prod() * 8)
if len(blockData) != blockBytes {
dvid.Criticalf("After labelblk deserialization got back %d bytes, expected %d bytes\n", len(blockData), blockBytes)
return
}
// Iterate through this block of labels and relabel if label in merge.
for i := 0; i < blockBytes; i += 8 {
label := binary.LittleEndian.Uint64(blockData[i : i+8])
if _, merged := op.Merged[label]; merged {
binary.LittleEndian.PutUint64(blockData[i:i+8], op.Target)
}
}
// Store this block.
serialization, err := dvid.SerializeData(blockData, d.Compression(), d.Checksum())
if err != nil {
dvid.Criticalf("Unable to serialize block in %q: %v\n", d.DataName(), err)
return
}
if err := store.Put(ctx, tk, serialization); err != nil {
dvid.Errorf("Error in putting key %v: %v\n", tk, err)
}
// Notify any downstream downres instance.
d.publishBlockChange(ctx.VersionID(), op.mutID, op.block, blockData)
}
示例3: deleteElementInLabel
func (d *Data) deleteElementInLabel(ctx *datastore.VersionedCtx, batch storage.Batch, pt dvid.Point3d) error {
labelData := d.GetSyncedLabelblk()
if labelData == nil {
return nil // no synced labels
}
label, err := labelData.GetLabelAtPoint(ctx.VersionID(), pt)
if err != nil {
return err
}
tk := NewLabelTKey(label)
elems, err := getElementsNR(ctx, tk)
if err != nil {
return fmt.Errorf("err getting elements for label %d: %v\n", label, err)
}
// Note all elements to be deleted.
var delta DeltaModifyElements
var toDel []int
for i, elem := range elems {
if pt.Equals(elem.Pos) {
delta.Del = append(delta.Del, ElementPos{Label: label, Kind: elem.Kind, Pos: elem.Pos})
toDel = append(toDel, i)
}
}
if len(toDel) == 0 {
return nil
}
// Delete them from high index to low index due while reusing slice.
for i := len(toDel) - 1; i >= 0; i-- {
d := toDel[i]
elems[d] = elems[len(elems)-1]
elems[len(elems)-1] = ElementNR{}
elems = elems[:len(elems)-1]
}
// Put the modified list of elements
if err := putBatchElements(batch, tk, elems); err != nil {
return err
}
// Notify any subscribers of label annotation changes.
evt := datastore.SyncEvent{Data: d.DataUUID(), Event: ModifyElementsEvent}
msg := datastore.SyncMessage{Event: ModifyElementsEvent, Version: ctx.VersionID(), Delta: delta}
if err := datastore.NotifySubscribers(evt, msg); err != nil {
return err
}
return nil
}
示例4: moveElementInLabels
func (d *Data) moveElementInLabels(ctx *datastore.VersionedCtx, batch storage.Batch, from, to dvid.Point3d, moved ElementNR) error {
labelData := d.GetSyncedLabelblk()
if labelData == nil {
return nil // no label denormalization possible
}
oldLabel, err := labelData.GetLabelAtPoint(ctx.VersionID(), from)
if err != nil {
return err
}
newLabel, err := labelData.GetLabelAtPoint(ctx.VersionID(), to)
if err != nil {
return err
}
if oldLabel == newLabel {
return nil
}
var delta DeltaModifyElements
if oldLabel != 0 {
tk := NewLabelTKey(oldLabel)
elems, err := getElementsNR(ctx, tk)
if err != nil {
return fmt.Errorf("err getting elements for label %d: %v", oldLabel, err)
}
if _, changed := elems.delete(from); changed {
if err := putBatchElements(batch, tk, elems); err != nil {
return fmt.Errorf("err putting deleted label %d element: %v", oldLabel, err)
}
delta.Del = append(delta.Del, ElementPos{Label: oldLabel, Kind: moved.Kind, Pos: from})
}
}
if newLabel != 0 {
tk := NewLabelTKey(newLabel)
elems, err := getElementsNR(ctx, tk)
if err != nil {
return fmt.Errorf("err getting elements for label %d: %v", newLabel, err)
}
elems.add(ElementsNR{moved})
if err := putBatchElements(batch, tk, elems); err != nil {
return err
}
delta.Add = append(delta.Add, ElementPos{Label: newLabel, Kind: moved.Kind, Pos: to})
}
// Notify any subscribers of label annotation changes.
if len(delta.Del) != 0 || len(delta.Add) != 0 {
evt := datastore.SyncEvent{Data: d.DataUUID(), Event: ModifyElementsEvent}
msg := datastore.SyncMessage{Event: ModifyElementsEvent, Version: ctx.VersionID(), Delta: delta}
if err := datastore.NotifySubscribers(evt, msg); err != nil {
return err
}
}
return nil
}
示例5: ServeHTTP
//.........这里部分代码省略.........
if err != nil {
server.BadRequest(w, r, err)
return
}
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, string(jsonBytes))
return
default:
}
// Get the data name and parse out the channel number or see if composite is required.
var channelNum int32
channumStr := strings.TrimPrefix(parts[2], string(d.DataName()))
if len(channumStr) == 0 {
channelNum = 0
} else {
n, err := strconv.ParseInt(channumStr, 10, 32)
if err != nil {
server.BadRequest(w, r, "Error parsing channel number from data name '%s': %v", parts[2], err)
return
}
if int(n) > d.NumChannels {
minChannelName := fmt.Sprintf("%s1", d.DataName())
maxChannelName := fmt.Sprintf("%s%d", d.DataName(), d.NumChannels)
server.BadRequest(w, r, "Data only has %d channels. Use names '%s' -> '%s'", d.NumChannels,
minChannelName, maxChannelName)
return
}
channelNum = int32(n)
}
// Get the data shape.
shapeStr := dvid.DataShapeString(parts[3])
dataShape, err := shapeStr.DataShape()
if err != nil {
server.BadRequest(w, r, "Bad data shape given '%s'", shapeStr)
return
}
switch dataShape.ShapeDimensions() {
case 2:
sizeStr, offsetStr := parts[4], parts[5]
slice, err := dvid.NewSliceFromStrings(shapeStr, offsetStr, sizeStr, "_")
if err != nil {
server.BadRequest(w, r, err)
return
}
if action == "post" {
server.BadRequest(w, r, "DVID does not yet support POST of slices into multichannel data")
return
} else {
if d.NumChannels == 0 || d.Data.Values == nil {
server.BadRequest(w, r, "Cannot retrieve absent data '%d'. Please load data.", d.DataName())
return
}
values := d.Data.Values
if len(values) <= int(channelNum) {
server.BadRequest(w, r, "Must choose channel from 0 to %d", len(values))
return
}
stride := slice.Size().Value(0) * values.BytesPerElement()
dataValues := dvid.DataValues{values[channelNum]}
data := make([]uint8, int(slice.NumVoxels()))
v := imageblk.NewVoxels(slice, dataValues, data, stride)
channel := &Channel{
Voxels: v,
channelNum: channelNum,
}
img, err := d.GetImage(ctx.VersionID(), channel.Voxels, nil)
var formatStr string
if len(parts) >= 7 {
formatStr = parts[6]
}
//dvid.ElapsedTime(dvid.Normal, startTime, "%s %s upto image formatting", op, slice)
err = dvid.WriteImageHttp(w, img.Get(), formatStr)
if err != nil {
server.BadRequest(w, r, err)
return
}
}
case 3:
sizeStr, offsetStr := parts[4], parts[5]
_, err := dvid.NewSubvolumeFromStrings(offsetStr, sizeStr, "_")
if err != nil {
server.BadRequest(w, r, err)
return
}
if action == "get" {
server.BadRequest(w, r, "DVID does not yet support GET of volume data")
return
} else {
server.BadRequest(w, r, "DVID does not yet support POST of volume data")
return
}
default:
server.BadRequest(w, r, "DVID does not yet support nD volumes")
return
}
timedLog.Infof("HTTP %s: %s", r.Method, dataShape)
}
示例6: ingestBlock
// Note that this does not delete any removed labels in the block since we only get the CURRENT block
// and not PAST blocks. To allow mutation of label blocks, not just ingestion, we need another function.
func (d *Data) ingestBlock(ctx *datastore.VersionedCtx, block imageblk.Block, batcher storage.KeyValueBatcher) {
// Iterate through this block of labels and create RLEs for each label.
blockBytes := len(block.Data)
if blockBytes != int(d.BlockSize.Prod())*8 {
dvid.Criticalf("Deserialized label block %d bytes, not uint64 size times %d block elements\n",
blockBytes, d.BlockSize.Prod())
return
}
labelRLEs := make(map[uint64]dvid.RLEs, 10)
firstPt := block.Index.MinPoint(d.BlockSize)
lastPt := block.Index.MaxPoint(d.BlockSize)
var curStart dvid.Point3d
var voxelLabel, curLabel, maxLabel uint64
var z, y, x, curRun int32
start := 0
for z = firstPt.Value(2); z <= lastPt.Value(2); z++ {
for y = firstPt.Value(1); y <= lastPt.Value(1); y++ {
for x = firstPt.Value(0); x <= lastPt.Value(0); x++ {
voxelLabel = binary.LittleEndian.Uint64(block.Data[start : start+8])
if maxLabel < voxelLabel {
maxLabel = voxelLabel
}
start += 8
// If we hit background or have switched label, save old run and start new one.
if voxelLabel == 0 || voxelLabel != curLabel {
// Save old run
if curRun > 0 {
labelRLEs[curLabel] = append(labelRLEs[curLabel], dvid.NewRLE(curStart, curRun))
}
// Start new one if not zero label.
if voxelLabel != 0 {
curStart = dvid.Point3d{x, y, z}
curRun = 1
} else {
curRun = 0
}
curLabel = voxelLabel
} else {
curRun++
}
}
// Force break of any runs when we finish x scan.
if curRun > 0 {
labelRLEs[curLabel] = append(labelRLEs[curLabel], dvid.NewRLE(curStart, curRun))
curLabel = 0
curRun = 0
}
}
}
// Store the RLEs for each label in this block.
if maxLabel > 0 {
batch := batcher.NewBatch(ctx)
blockStr := block.Index.ToIZYXString()
for label, rles := range labelRLEs {
tk := NewTKey(label, blockStr)
rleBytes, err := rles.MarshalBinary()
if err != nil {
dvid.Errorf("Bad encoding labelvol keys for label %d: %v\n", label, err)
return
}
batch.Put(tk, rleBytes)
}
// compare-and-set MaxLabel and batch commit
d.casMaxLabel(batch, ctx.VersionID(), maxLabel)
}
}
示例7: deleteBlock
// If a block of labels is deleted, the associated synapse elements should be changed to zero label elements.
func (d *Data) deleteBlock(ctx *datastore.VersionedCtx, block labels.DeleteBlock, batcher storage.KeyValueBatcher) {
// Get the synaptic elements for this block
chunkPt := dvid.ChunkPoint3d(*block.Index)
tk := NewBlockTKey(chunkPt)
elems, err := getElements(ctx, tk)
if err != nil {
dvid.Errorf("err getting elements for block %s: %v\n", chunkPt, err)
return
}
if len(elems) == 0 {
return
}
blockSize := d.blockSize()
batch := batcher.NewBatch(ctx)
// Compute the strides (in bytes)
bX := blockSize[0] * 8
bY := blockSize[1] * bX
// Iterate through all element positions, finding corresponding label and storing elements.
toDel := LabelPoints{}
for _, elem := range elems {
pt := elem.Pos.Point3dInChunk(blockSize)
i := pt[2]*bY + pt[1]*bX + pt[0]*8
label := binary.LittleEndian.Uint64(block.Data[i : i+8])
toDel.add(label, elem.Pos)
}
// Delete any non-zero label elements from their respective label k/v.
var delta DeltaModifyElements
for label, pts := range toDel {
tk := NewLabelTKey(label)
elems, err := getElements(ctx, tk)
if err != nil {
dvid.Errorf("err getting elements for label %d: %v\n", label, err)
return
}
save := false
for _, pt := range pts {
deleted, changed := elems.delete(pt)
if changed {
save = true
delta.Del = append(delta.Del, ElementPos{Label: label, Kind: deleted.Kind, Pos: pt})
}
}
if save {
if len(elems) == 0 {
batch.Delete(tk)
} else {
val, err := json.Marshal(elems)
if err != nil {
dvid.Errorf("couldn't serialize annotation elements in instance %q: %v\n", d.DataName(), err)
return
}
batch.Put(tk, val)
}
}
}
if err := batch.Commit(); err != nil {
dvid.Criticalf("bad commit in annotations %q after delete block: %v\n", d.DataName(), err)
return
}
// Notify any subscribers of label annotation changes.
evt := datastore.SyncEvent{Data: d.DataUUID(), Event: ModifyElementsEvent}
msg := datastore.SyncMessage{Event: ModifyElementsEvent, Version: ctx.VersionID(), Delta: delta}
if err := datastore.NotifySubscribers(evt, msg); err != nil {
dvid.Criticalf("unable to notify subscribers of event %s: %v\n", evt, err)
}
}
示例8: mutateBlock
// If a block of labels is mutated, adjust any label that was either removed or added.
func (d *Data) mutateBlock(ctx *datastore.VersionedCtx, block imageblk.MutatedBlock, batcher storage.KeyValueBatcher) {
// Get the synaptic elements for this block
chunkPt := dvid.ChunkPoint3d(*block.Index)
tk := NewBlockTKey(chunkPt)
elems, err := getElementsNR(ctx, tk)
if err != nil {
dvid.Errorf("err getting elements for block %s: %v\n", chunkPt, err)
return
}
if len(elems) == 0 {
return
}
blockSize := d.blockSize()
batch := batcher.NewBatch(ctx)
// Compute the strides (in bytes)
bX := blockSize[0] * 8
bY := blockSize[1] * bX
// Iterate through all element positions, finding corresponding label and storing elements.
var delta DeltaModifyElements
labels := make(map[uint64]struct{})
toAdd := LabelElements{}
toDel := LabelPoints{}
for _, elem := range elems {
pt := elem.Pos.Point3dInChunk(blockSize)
i := pt[2]*bY + pt[1]*bX + pt[0]*8
label := binary.LittleEndian.Uint64(block.Data[i : i+8])
var prev uint64
if len(block.Prev) != 0 {
prev = binary.LittleEndian.Uint64(block.Prev[i : i+8])
}
if label == prev {
continue
}
if label != 0 {
toAdd.add(label, elem)
labels[label] = struct{}{}
delta.Add = append(delta.Add, ElementPos{Label: label, Kind: elem.Kind, Pos: elem.Pos})
}
if prev != 0 {
toDel.add(prev, elem.Pos)
labels[prev] = struct{}{}
delta.Del = append(delta.Del, ElementPos{Label: prev, Kind: elem.Kind, Pos: elem.Pos})
}
}
// Modify any modified label k/v.
for label := range labels {
tk := NewLabelTKey(label)
elems, err := getElementsNR(ctx, tk)
if err != nil {
dvid.Errorf("err getting elements for label %d: %v\n", label, err)
return
}
additions, found := toAdd[label]
if found {
elems.add(additions)
}
deletions, found := toDel[label]
if found {
for _, pt := range deletions {
elems.delete(pt)
}
}
val, err := json.Marshal(elems)
if err != nil {
dvid.Errorf("couldn't serialize annotation elements in instance %q: %v\n", d.DataName(), err)
return
}
batch.Put(tk, val)
}
if err := batch.Commit(); err != nil {
dvid.Criticalf("bad commit in annotations %q after delete block: %v\n", d.DataName(), err)
return
}
// Notify any subscribers of label annotation changes.
evt := datastore.SyncEvent{Data: d.DataUUID(), Event: ModifyElementsEvent}
msg := datastore.SyncMessage{Event: ModifyElementsEvent, Version: ctx.VersionID(), Delta: delta}
if err := datastore.NotifySubscribers(evt, msg); err != nil {
dvid.Criticalf("unable to notify subscribers of event %s: %v\n", evt, err)
}
}
示例9: ServeHTTP
// ServeHTTP handles all incoming HTTP requests for this data.
func (d *Data) ServeHTTP(uuid dvid.UUID, ctx *datastore.VersionedCtx, w http.ResponseWriter, r *http.Request) {
// TODO -- Refactor this method to break it up and make it simpler. Use the web routing for the endpoints.
timedLog := dvid.NewTimeLog()
// Get the action (GET, POST)
action := strings.ToLower(r.Method)
switch action {
case "get":
case "post":
case "delete":
default:
server.BadRequest(w, r, "labelblk only handles GET, POST, and DELETE HTTP verbs")
return
}
// Break URL request into arguments
url := r.URL.Path[len(server.WebAPIPath):]
parts := strings.Split(url, "/")
if len(parts[len(parts)-1]) == 0 {
parts = parts[:len(parts)-1]
}
// Get query strings and possible roi
var roiptr *imageblk.ROI
queryValues := r.URL.Query()
roiname := dvid.InstanceName(queryValues.Get("roi"))
if len(roiname) != 0 {
roiptr = new(imageblk.ROI)
}
// Handle POST on data -> setting of configuration
if len(parts) == 3 && action == "post" {
config, err := server.DecodeJSON(r)
if err != nil {
server.BadRequest(w, r, err)
return
}
if err := d.ModifyConfig(config); err != nil {
server.BadRequest(w, r, err)
return
}
if err := datastore.SaveDataByUUID(uuid, d); err != nil {
server.BadRequest(w, r, err)
return
}
fmt.Fprintf(w, "Changed '%s' based on received configuration:\n%s\n", d.DataName(), config)
return
}
if len(parts) < 4 {
server.BadRequest(w, r, "Incomplete API request")
return
}
// Process help and info.
switch parts[3] {
case "help":
w.Header().Set("Content-Type", "text/plain")
fmt.Fprintln(w, dtype.Help())
case "metadata":
jsonStr, err := d.NdDataMetadata()
if err != nil {
server.BadRequest(w, r, err)
return
}
w.Header().Set("Content-Type", "application/vnd.dvid-nd-data+json")
fmt.Fprintln(w, jsonStr)
case "info":
jsonBytes, err := d.MarshalJSON()
if err != nil {
server.BadRequest(w, r, err)
return
}
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, string(jsonBytes))
case "label":
// GET <api URL>/node/<UUID>/<data name>/label/<coord>
if len(parts) < 5 {
server.BadRequest(w, r, "DVID requires coord to follow 'label' command")
return
}
coord, err := dvid.StringToPoint(parts[4], "_")
if err != nil {
server.BadRequest(w, r, err)
return
}
label, err := d.GetLabelAtPoint(ctx.VersionID(), coord)
if err != nil {
server.BadRequest(w, r, err)
return
}
w.Header().Set("Content-type", "application/json")
jsonStr := fmt.Sprintf(`{"Label": %d}`, label)
fmt.Fprintf(w, jsonStr)
timedLog.Infof("HTTP %s: label at %s (%s)", r.Method, coord, r.URL)
//.........这里部分代码省略.........
示例10: DeleteBlocks
func (d *Data) DeleteBlocks(ctx *datastore.VersionedCtx, start dvid.ChunkPoint3d, span int) error {
store, err := storage.MutableStore()
if err != nil {
return fmt.Errorf("Data type labelblk had error initializing store: %v\n", err)
}
batcher, ok := store.(storage.KeyValueBatcher)
if !ok {
return fmt.Errorf("Data type labelblk requires batch-enabled store, which %q is not\n", store)
}
indexBeg := dvid.IndexZYX(start)
end := start
end[0] += int32(span - 1)
indexEnd := dvid.IndexZYX(end)
begTKey := NewTKey(&indexBeg)
endTKey := NewTKey(&indexEnd)
iv := dvid.InstanceVersion{d.DataName(), ctx.VersionID()}
mapping := labels.MergeCache.LabelMap(iv)
kvs, err := store.GetRange(ctx, begTKey, endTKey)
if err != nil {
return err
}
batch := batcher.NewBatch(ctx)
uncompress := true
for _, kv := range kvs {
izyx, err := DecodeTKey(kv.K)
if err != nil {
return err
}
// Delete the labelblk (really tombstones it)
batch.Delete(kv.K)
// Send data to delete associated labelvol for labels in this block
block, _, err := dvid.DeserializeData(kv.V, uncompress)
if err != nil {
return fmt.Errorf("Unable to deserialize block, %s (%v): %v", ctx, kv.K, err)
}
if mapping != nil {
n := len(block) / 8
for i := 0; i < n; i++ {
orig := binary.LittleEndian.Uint64(block[i*8 : i*8+8])
mapped, found := mapping.FinalLabel(orig)
if !found {
mapped = orig
}
binary.LittleEndian.PutUint64(block[i*8:i*8+8], mapped)
}
}
// Notify any subscribers that we've deleted this block.
evt := datastore.SyncEvent{d.DataName(), labels.DeleteBlockEvent}
msg := datastore.SyncMessage{ctx.VersionID(), labels.DeleteBlock{izyx, block}}
if err := datastore.NotifySubscribers(evt, msg); err != nil {
return err
}
}
return batch.Commit()
}
示例11: ServeHTTP
// ServeHTTP handles all incoming HTTP requests for this data.
func (d *Data) ServeHTTP(uuid dvid.UUID, ctx *datastore.VersionedCtx, w http.ResponseWriter, r *http.Request) {
timedLog := dvid.NewTimeLog()
// Check the action
action := strings.ToLower(r.Method)
if action != "get" {
server.BadRequest(w, r, "labelsz data can only accept GET HTTP requests")
return
}
// Break URL request into arguments
url := r.URL.Path[len(server.WebAPIPath):]
parts := strings.Split(url, "/")
if len(parts[len(parts)-1]) == 0 {
parts = parts[:len(parts)-1]
}
if len(parts) < 4 {
server.BadRequest(w, r, "Incomplete API request")
return
}
// Process help and info.
switch parts[3] {
case "help":
w.Header().Set("Content-Type", "text/plain")
fmt.Fprintln(w, dtype.Help())
case "info":
jsonBytes, err := d.MarshalJSON()
if err != nil {
server.BadRequest(w, r, err)
return
}
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, string(jsonBytes))
case "size":
// GET <api URL>/node/<UUID>/<data name>/size/<label>
if len(parts) < 5 {
server.BadRequest(w, r, "ERROR: DVID requires label ID to follow 'size' command")
return
}
label, err := strconv.ParseUint(parts[4], 10, 64)
if err != nil {
server.BadRequest(w, r, err)
return
}
size, err := d.GetSize(ctx.VersionID(), label)
if err != nil {
server.BadRequest(w, r, err)
return
}
w.Header().Set("Content-type", "application/json")
fmt.Fprintf(w, "{%q: %d, %q: %d}", "Label", label, "Voxels", size)
timedLog.Infof("HTTP %s: get label %d size", r.Method, label)
case "sizerange":
// GET <api URL>/node/<UUID>/<data name>/sizerange/<min size>/<optional max size>
if len(parts) < 5 {
server.BadRequest(w, r, "ERROR: DVID requires at least the minimum size to follow 'sizerange' command")
return
}
minSize, err := strconv.ParseUint(parts[4], 10, 64)
if err != nil {
server.BadRequest(w, r, err)
return
}
var maxSize uint64
if len(parts) >= 6 {
maxSize, err = strconv.ParseUint(parts[5], 10, 64)
if err != nil {
server.BadRequest(w, r, err)
return
}
}
jsonStr, err := d.GetSizeRange(ctx.VersionID(), minSize, maxSize)
if err != nil {
server.BadRequest(w, r, err)
return
}
w.Header().Set("Content-type", "application/json")
fmt.Fprintf(w, jsonStr)
timedLog.Infof("HTTP %s: get labels with volume > %d and < %d (%s)", r.Method, minSize, maxSize, r.URL)
default:
server.BadRequest(w, r, "Unrecognized API call '%s' for labelsz data '%s'. See API help.",
parts[3], d.DataName())
}
}
示例12: ServeHTTP
// ServeHTTP handles all incoming HTTP requests for this data.
func (d *Data) ServeHTTP(uuid dvid.UUID, ctx *datastore.VersionedCtx, w http.ResponseWriter, r *http.Request) {
timedLog := dvid.NewTimeLog()
// Break URL request into arguments
url := r.URL.Path[len(server.WebAPIPath):]
parts := strings.Split(url, "/")
if len(parts[len(parts)-1]) == 0 {
parts = parts[:len(parts)-1]
}
if len(parts) < 4 {
server.BadRequest(w, r, "incomplete API specification")
return
}
// Process help and info.
switch parts[3] {
case "help":
w.Header().Set("Content-Type", "text/plain")
fmt.Fprintln(w, d.Help())
return
case "info":
jsonBytes, err := d.MarshalJSON()
if err != nil {
server.BadRequest(w, r, err)
return
}
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, string(jsonBytes))
return
default:
}
// Get the key and process request
var comment string
command := parts[3]
method := strings.ToLower(r.Method)
switch command {
case "roi":
switch method {
case "get":
if !d.Ready {
w.WriteHeader(http.StatusPartialContent)
}
jsonBytes, err := Get(ctx)
if err != nil {
server.BadRequest(w, r, err)
return
}
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, string(jsonBytes))
comment = fmt.Sprintf("HTTP GET ROI %q: %d bytes\n", d.DataName(), len(jsonBytes))
case "post":
data, err := ioutil.ReadAll(r.Body)
if err != nil {
server.BadRequest(w, r, err)
return
}
err = d.PutJSON(ctx.VersionID(), data)
if err != nil {
server.BadRequest(w, r, err)
return
}
comment = fmt.Sprintf("HTTP POST ROI %q: %d bytes\n", d.DataName(), len(data))
case "delete":
if err := d.Delete(ctx); err != nil {
server.BadRequest(w, r, err)
return
}
comment = fmt.Sprintf("HTTP DELETE ROI %q\n", d.DataName())
}
case "mask":
if method != "get" {
server.BadRequest(w, r, "ROI mask only supports GET")
return
}
if len(parts) < 7 {
server.BadRequest(w, r, "%q must be followed by shape/size/offset", command)
return
}
shapeStr, sizeStr, offsetStr := parts[4], parts[5], parts[6]
planeStr := dvid.DataShapeString(shapeStr)
plane, err := planeStr.DataShape()
if err != nil {
server.BadRequest(w, r, err)
return
}
switch plane.ShapeDimensions() {
case 3:
subvol, err := dvid.NewSubvolumeFromStrings(offsetStr, sizeStr, "_")
if err != nil {
server.BadRequest(w, r, err)
return
}
data, err := d.GetMask(ctx, subvol)
if err != nil {
server.BadRequest(w, r, err)
return
}
//.........这里部分代码省略.........
示例13: ServeHTTP
//.........这里部分代码省略.........
if err != nil {
server.BadRequest(w, r, err)
return
}
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, string(jsonBytes))
return
case "rawkey":
// GET <api URL>/node/<UUID>/<data name>/rawkey?x=<block x>&y=<block y>&z=<block z>
if len(parts) != 4 {
server.BadRequest(w, r, "rawkey endpoint should be followed by query strings (x, y, and z) giving block coord")
return
}
case "blocks":
// GET <api URL>/node/<UUID>/<data name>/blocks/<block coord>/<spanX>
// POST <api URL>/node/<UUID>/<data name>/blocks/<block coord>/<spanX>
if len(parts) < 6 {
server.BadRequest(w, r, "%q must be followed by block-coord/span-x", parts[3])
return
}
blockCoord, err := dvid.StringToChunkPoint3d(parts[4], "_")
if err != nil {
server.BadRequest(w, r, err)
return
}
span, err := strconv.Atoi(parts[5])
if err != nil {
server.BadRequest(w, r, err)
return
}
if action == "get" {
data, err := d.GetBlocks(ctx.VersionID(), blockCoord, int32(span))
if err != nil {
server.BadRequest(w, r, err)
return
}
w.Header().Set("Content-type", "application/octet-stream")
_, err = w.Write(data)
if err != nil {
server.BadRequest(w, r, err)
return
}
} else {
if err := d.PutBlocks(ctx.VersionID(), blockCoord, span, r.Body); err != nil {
server.BadRequest(w, r, err)
return
}
}
timedLog.Infof("HTTP %s: Blocks (%s)", r.Method, r.URL)
case "arb":
// GET <api URL>/node/<UUID>/<data name>/arb/<top left>/<top right>/<bottom left>/<res>[/<format>]
if len(parts) < 8 {
server.BadRequest(w, r, "%q must be followed by top-left/top-right/bottom-left/res", parts[3])
return
}
queryStrings := r.URL.Query()
throttle := queryStrings.Get("throttle")
if throttle == "true" || throttle == "on" {
select {
case <-server.Throttle:
// Proceed with operation, returning throttle token to server at end.
defer func() {
server.Throttle <- 1
示例14: storeLabelElements
// stores synaptic elements arranged by label, replacing any
// elements at same position.
func (d *Data) storeLabelElements(ctx *datastore.VersionedCtx, batch storage.Batch, be blockElements) error {
labelData := d.GetSyncedLabelblk()
if labelData == nil {
dvid.Infof("No synced labels for annotation %q, skipping label-aware denormalization.\n", d.DataName())
return nil // no synced labels
}
// Compute the strides (in bytes)
blockSize := d.blockSize()
bX := blockSize[0] * 8
bY := blockSize[1] * bX
blockBytes := int(blockSize[0] * blockSize[1] * blockSize[2] * 8)
toAdd := LabelElements{}
for izyxStr, elems := range be {
blockCoord, err := izyxStr.ToChunkPoint3d()
if err != nil {
return err
}
// Get the labels for this block
labels, err := labelData.GetLabelBlock(ctx.VersionID(), blockCoord)
if err != nil {
return err
}
if len(labels) == 0 {
continue
}
if len(labels) != blockBytes {
return fmt.Errorf("Expected %d bytes in %q label block, got %d instead. Aborting.", blockBytes, d.DataName(), len(labels))
}
// Group annotations by label
for _, elem := range elems {
pt := elem.Pos.Point3dInChunk(blockSize)
i := pt[2]*bY + pt[1]*bX + pt[0]*8
label := binary.LittleEndian.Uint64(labels[i : i+8])
if label != 0 {
toAdd.add(label, elem.ElementNR)
}
}
}
// Store all the added annotations to the appropriate labels.
var delta DeltaModifyElements
for label, additions := range toAdd {
tk := NewLabelTKey(label)
elems, err := getElementsNR(ctx, tk)
if err != nil {
return fmt.Errorf("err getting elements for label %d: %v\n", label, err)
}
// Check if these annotations already exist.
emap := make(map[string]int)
for i, elem := range elems {
emap[elem.Pos.MapKey()] = i
}
for _, elem := range additions {
i, found := emap[elem.Pos.MapKey()]
if !found {
elems = append(elems, elem)
delta.Add = append(delta.Add, ElementPos{Label: label, Kind: elem.Kind, Pos: elem.Pos})
} else {
elems[i] = elem // replace properties if same position
}
}
if err := putBatchElements(batch, tk, elems); err != nil {
return fmt.Errorf("couldn't serialize label %d annotations in instance %q: %v\n", label, d.DataName(), err)
}
}
// Notify any subscribers of label annotation changes.
evt := datastore.SyncEvent{Data: d.DataUUID(), Event: ModifyElementsEvent}
msg := datastore.SyncMessage{Event: ModifyElementsEvent, Version: ctx.VersionID(), Delta: delta}
if err := datastore.NotifySubscribers(evt, msg); err != nil {
return err
}
return nil
}
示例15: ingestBlock
// If a block of labels is ingested, adjust each label's synaptic element list.
func (d *Data) ingestBlock(ctx *datastore.VersionedCtx, block imageblk.Block, batcher storage.KeyValueBatcher) {
// Get the synaptic elements for this block
chunkPt := dvid.ChunkPoint3d(*block.Index)
tk := NewBlockTKey(chunkPt)
elems, err := getElementsNR(ctx, tk)
if err != nil {
dvid.Errorf("err getting elements for block %s: %v\n", chunkPt, err)
return
}
if len(elems) == 0 {
return
}
blockSize := d.blockSize()
batch := batcher.NewBatch(ctx)
// Compute the strides (in bytes)
bX := blockSize[0] * 8
bY := blockSize[1] * bX
// Iterate through all element positions, finding corresponding label and storing elements.
added := 0
toAdd := LabelElements{}
for _, elem := range elems {
pt := elem.Pos.Point3dInChunk(blockSize)
i := (pt[2]*bY+pt[1])*bX + pt[0]*8
label := binary.LittleEndian.Uint64(block.Data[i : i+8])
if label != 0 {
toAdd.add(label, elem)
added++
}
}
// Add any non-zero label elements to their respective label k/v.
var delta DeltaModifyElements
delta.Add = make([]ElementPos, added)
i := 0
for label, addElems := range toAdd {
tk := NewLabelTKey(label)
elems, err := getElementsNR(ctx, tk)
if err != nil {
dvid.Errorf("err getting elements for label %d: %v\n", label, err)
return
}
elems.add(addElems)
val, err := json.Marshal(elems)
if err != nil {
dvid.Errorf("couldn't serialize annotation elements in instance %q: %v\n", d.DataName(), err)
return
}
batch.Put(tk, val)
for _, addElem := range addElems {
delta.Add[i] = ElementPos{Label: label, Kind: addElem.Kind, Pos: addElem.Pos}
i++
}
}
if err := batch.Commit(); err != nil {
dvid.Criticalf("bad commit in annotations %q after delete block: %v\n", d.DataName(), err)
return
}
// Notify any subscribers of label annotation changes.
evt := datastore.SyncEvent{Data: d.DataUUID(), Event: ModifyElementsEvent}
msg := datastore.SyncMessage{Event: ModifyElementsEvent, Version: ctx.VersionID(), Delta: delta}
if err := datastore.NotifySubscribers(evt, msg); err != nil {
dvid.Criticalf("unable to notify subscribers of event %s: %v\n", evt, err)
}
}