Esempio n. 1
0
func (d *Data) DeleteElement(ctx *datastore.VersionedCtx, pt dvid.Point3d) error {
	// Get from block key
	blockSize := d.blockSize()
	blockCoord := pt.Chunk(blockSize).(dvid.ChunkPoint3d)
	tk := NewBlockTKey(blockCoord)

	d.Lock()
	defer d.Unlock()

	elems, err := getElements(ctx, tk)
	if err != nil {
		return err
	}

	// Delete the given element
	deleted, _ := elems.delete(pt)
	if deleted == nil {
		return fmt.Errorf("Did not find element %s in datastore", pt)
	}

	// Put block key version without given element
	if err := putElements(ctx, tk, elems); err != nil {
		return err
	}

	// Alter all stored versions of this annotation using a batch.
	store, err := d.BackendStore()
	if err != nil {
		return err
	}
	batcher, ok := store.(storage.KeyValueBatcher)
	if !ok {
		return fmt.Errorf("Data type annotation requires batch-enabled store, which %q is not\n", store)
	}
	batch := batcher.NewBatch(ctx)

	// Delete in label key
	if err := d.deleteElementInLabel(ctx, batch, deleted.Pos); err != nil {
		return err
	}

	// Delete element in any tags
	if err := d.deleteElementInTags(ctx, batch, deleted.Pos, deleted.Tags); err != nil {
		return err
	}

	// Modify any reference in relationships
	if err := d.deleteElementInRelationships(ctx, batch, deleted.Pos, deleted.Rels); err != nil {
		return err
	}

	return batch.Commit()
}
Esempio n. 2
0
// move all reference to given element point in the related points in different blocks.
// This is private method and assumes outer locking as well as current "from" block already being modified,
// including relationships.
func (d *Data) moveElementInRelationships(ctx *datastore.VersionedCtx, batch storage.Batch, from, to dvid.Point3d, rels []Relationship) error {
	blockSize := d.blockSize()
	fromBlockCoord := from.Chunk(blockSize).(dvid.ChunkPoint3d)

	// Get list of blocks with related points.
	relBlocks := make(map[dvid.IZYXString]struct{})
	for _, rel := range rels {
		blockCoord := rel.To.Chunk(blockSize).(dvid.ChunkPoint3d)
		if blockCoord.Equals(fromBlockCoord) {
			continue // relationships are almoved in from block
		}
		relBlocks[blockCoord.ToIZYXString()] = struct{}{}
	}

	// Alter the moved points in those related blocks.
	for izyxstr := range relBlocks {
		blockCoord, err := izyxstr.ToChunkPoint3d()
		if err != nil {
			return err
		}
		tk := NewBlockTKey(blockCoord)
		elems, err := getElements(ctx, tk)
		if err != nil {
			return err
		}

		// Move element in related element.
		if _, changed := elems.move(from, to, false); !changed {
			dvid.Errorf("Unable to find moved element %s in related element @ block %s:\n%v\n", from, blockCoord, elems)
			continue
		}

		// Save the block elements.
		if err := putBatchElements(batch, tk, elems); err != nil {
			return err
		}
	}
	return nil
}
Esempio n. 3
0
func (d *Data) MoveElement(ctx *datastore.VersionedCtx, from, to dvid.Point3d) error {
	// Calc block keys
	blockSize := d.blockSize()
	fromCoord := from.Chunk(blockSize).(dvid.ChunkPoint3d)
	fromTk := NewBlockTKey(fromCoord)

	toCoord := to.Chunk(blockSize).(dvid.ChunkPoint3d)
	toTk := NewBlockTKey(toCoord)

	d.Lock()
	defer d.Unlock()

	// Alter all stored versions of this annotation using a batch.
	store, err := d.BackendStore()
	if err != nil {
		return err
	}
	batcher, ok := store.(storage.KeyValueBatcher)
	if !ok {
		return fmt.Errorf("Data type annotation requires batch-enabled store, which %q is not\n", store)
	}
	batch := batcher.NewBatch(ctx)

	// Handle from block
	fromElems, err := getElements(ctx, fromTk)
	if err != nil {
		return err
	}

	deleteElement := (bytes.Compare(fromTk, toTk) != 0)
	moved, _ := fromElems.move(from, to, deleteElement)
	if moved == nil {
		return fmt.Errorf("Did not find moved element %s in datastore", from)
	}
	dvid.Infof("moved element %v from %s -> %s\n", *moved, fromCoord, toCoord)

	if err := putBatchElements(batch, fromTk, fromElems); err != nil {
		return err
	}

	// If we've moved blocks, add the element in new place.
	if deleteElement {
		toElems, err := getElements(ctx, toTk)
		if err != nil {
			return err
		}
		toElems.add(Elements{*moved})
		dvid.Infof("new %s value: %v\n", toCoord, toElems)

		if err := putBatchElements(batch, toTk, toElems); err != nil {
			return err
		}
	}

	if err := batch.Commit(); err != nil {
		return err
	}
	batch = batcher.NewBatch(ctx)

	// Move in label key
	if err := d.moveElementInLabels(ctx, batch, from, to, moved.ElementNR); err != nil {
		return err
	}

	// Move element in any tags
	if err := d.moveElementInTags(ctx, batch, from, to, moved.Tags); err != nil {
		return err
	}

	// Move any reference in relationships
	if err := d.moveElementInRelationships(ctx, batch, from, to, moved.Rels); err != nil {
		return err
	}

	return batch.Commit()
}