// DeepDelete deletes the key named as the last element of the elements
// arguments in nested buckets named as previous elements.
// With argument set to true, this function will return ErrNotFound
// if the element is not deleted.
332608
func DeepDelete(tx *bolt.Tx, ensure bool, elements ...[]byte) (err error) {
	length := len(elements)
	if length < 2 {
		return fmt.Errorf("insufficient number of elements %d < 2", length)
	}
	path := elements[0]
	bucket := tx.Bucket(elements[0])
	if bucket == nil {
		if ensure {
			return NewNotFoundError(string(path))
		}
		return nil
	}
	for i := 1; i < length-1; i++ {
		path = append(path, []byte(", ")...)
		path = append(path, elements[i]...)
		bucket = bucket.Bucket(elements[i])
		if bucket == nil {
			if ensure {
				return NewNotFoundError(string(path))
			}
			return nil
		}
	}
	if ensure && bucket.Get(elements[length-1]) == nil {
		return NewNotFoundError(string(path) + ", " + string(elements[length-1]))
	}
	if err = bucket.Delete(elements[length-1]); err != nil {
		return fmt.Errorf("bucket %s delete %s: %s", path, elements[length-1], err)
	}
	return
}
1134987
func (c *CassandraBackend) Delete(ctx context.Context, key string) error {
	defer metrics.MeasureSince([]string{"cassandra", "delete"}, time.Now())

	stmt := fmt.Sprintf(`DELETE FROM "%s" WHERE bucket = ? AND key = ?`, c.table)
	results := make(chan error)
	buckets := c.buckets(key)

	for _, bucket := range buckets {
		go func(bucket string) {
			results <- c.sess.Query(stmt, bucket, key).Exec()
		}(bucket)
	}

	for i := 0; i < len(buckets); i++ {
		if err := <-results; err != nil {
			return err
		}
	}
	return nil
}
635387
func (c *Cacher) Delete(key string, recursive bool) []string {
	c.mu.Lock()
	defer c.mu.Unlock()
	var keys []string

	if recursive {
		for k := range c.data {
			if strings.HasPrefix(k, key) {
				delete(c.data, k)
				keys = append(keys, k)
			}
		}
	} else {
		if _, ok := c.data[key]; ok {
			delete(c.data, key)
			keys = append(keys, key)
		}
	}
	return keys
}
970739
func Delete(data []byte, keys ...string) []byte {
	lk := len(keys)
	if lk == 0 {
		return data[:0]
	}

	array := false
	if len(keys[lk-1]) > 0 && string(keys[lk-1][0]) == "[" {
		array = true
	}

	var startOffset, keyOffset int
	endOffset := len(data)
	var err error
	if !array {
		if len(keys) > 1 {
			_, _, startOffset, endOffset, err = internalGet(data, keys[:lk-1]...)
			if err == KeyPathNotFoundError {
				// problem parsing the data
				return data
			}
		}

		keyOffset, err = findKeyStart(data[startOffset:endOffset], keys[lk-1])
		if err == KeyPathNotFoundError {
			// problem parsing the data
			return data
		}
		keyOffset += startOffset
		_, _, _, subEndOffset, _ := internalGet(data[startOffset:endOffset], keys[lk-1])
		endOffset = startOffset + subEndOffset
		tokEnd := tokenEnd(data[endOffset:])
		tokStart := findTokenStart(data[:keyOffset], ","[0])

		if data[endOffset+tokEnd] == ","[0] {
			endOffset += tokEnd + 1
		} else if data[endOffset+tokEnd] == " "[0] && len(data) > endOffset+tokEnd+1 && data[endOffset+tokEnd+1] == ","[0] {
			endOffset += tokEnd + 2
		} else if data[endOffset+tokEnd] == "}"[0] && data[tokStart] == ","[0] {
			keyOffset = tokStart
		}
	} else {
		_, _, keyOffset, endOffset, err = internalGet(data, keys...)
		if err == KeyPathNotFoundError {
			// problem parsing the data
			return data
		}

		tokEnd := tokenEnd(data[endOffset:])
		tokStart := findTokenStart(data[:keyOffset], ","[0])

		if data[endOffset+tokEnd] == ","[0] {
			endOffset += tokEnd + 1
		} else if data[endOffset+tokEnd] == "]"[0] && data[tokStart] == ","[0] {
			keyOffset = tokStart
		}
	}

	// We need to remove remaining trailing comma if we delete las element in the object
	prevTok := lastToken(data[:keyOffset])
	remainedValue := data[endOffset:]

	var newOffset int
	if nextToken(remainedValue) > -1 && remainedValue[nextToken(remainedValue)] == '}' && data[prevTok] == ',' {
		newOffset = prevTok
	} else {
		newOffset = prevTok + 1
	}

	data = append(data[:newOffset], data[endOffset:]...)
	return data
}
539186
func (c *Scratch) Delete(key string) string {
	c.mu.Lock()
	delete(c.values, key)
	c.mu.Unlock()
	return ""
}
471665
func (l *LFUNoTS) Delete(key string) error {
	res, err := l.cache.Get(key)
	if err != nil && err != ErrNotFound {
		return err
	}

	// we dont need to delete if already doesn't exist
	if err == ErrNotFound {
		return nil
	}

	ci := res.(*cacheItem)

	l.remove(ci, ci.freqElement)
	l.currentSize--
	return l.cache.Delete(key)
}
155981
func (m *Mem) Delete(key models.Key) error {
	m.mut.Lock()
	defer m.mut.Unlock()
	delete(m.m, key.String())
	return nil
}
1081741
func (s *StorageView) Delete(ctx context.Context, key string) error {
	if err := s.SanityCheck(key); err != nil {
		return err
	}

	expandedKey := s.ExpandKey(key)

	return s.storage.Delete(ctx, expandedKey)
}
1269253
func (d *DynamoDBBackend) Delete(ctx context.Context, key string) error {
	defer metrics.MeasureSince([]string{"dynamodb", "delete"}, time.Now())

	requests := []*dynamodb.WriteRequest{{
		DeleteRequest: &dynamodb.DeleteRequest{
			Key: map[string]*dynamodb.AttributeValue{
				"Path": {S: aws.String(recordPathForVaultKey(key))},
				"Key":  {S: aws.String(recordKeyForVaultKey(key))},
			},
		},
	}}

	// Clean up empty "folders" by looping through all levels of the path to the item being deleted looking for
	// children. Loop from deepest path to shallowest, and only consider items children if they are not going to be
	// deleted by our batch delete request. If a path has no valid children, then it should be considered an empty
	// "folder" and be deleted along with the original item in our batch job. Because we loop from deepest path to
	// shallowest, once we find a path level that contains valid children we can stop the cleanup operation.
	prefixes := physical.Prefixes(key)
	sort.Sort(sort.Reverse(sort.StringSlice(prefixes)))
	for index, prefix := range prefixes {
		// Because delete batches its requests, we need to pass keys we know are going to be deleted into
		// hasChildren so it can exclude those when it determines if there WILL be any children left after
		// the delete operations have completed.
		var excluded []string
		if index == 0 {
			// This is the value we know for sure is being deleted
			excluded = append(excluded, recordKeyForVaultKey(key))
		} else {
			// The previous path doesn't count as a child, since if we're still looping, we've found no children
			excluded = append(excluded, recordKeyForVaultKey(prefixes[index-1]))
		}

		hasChildren, err := d.hasChildren(prefix, excluded)
		if err != nil {
			return err
		}

		if !hasChildren {
			// If there are no children other than ones we know are being deleted then cleanup empty "folder" pointers
			requests = append(requests, &dynamodb.WriteRequest{
				DeleteRequest: &dynamodb.DeleteRequest{
					Key: map[string]*dynamodb.AttributeValue{
						"Path": {S: aws.String(recordPathForVaultKey(prefix))},
						"Key":  {S: aws.String(fmt.Sprintf("%s/", recordKeyForVaultKey(prefix)))},
					},
				},
			})
		} else {
			// This loop starts at the deepest path and works backwards looking for children
			// once a deeper level of the path has been found to have children there is no
			// more cleanup that needs to happen, otherwise we might remove folder pointers
			// to that deeper path making it "undiscoverable" with the list operation
			break
		}
	}

	return d.batchWriteRequests(requests)
}
1332987
func (b *Bucket) Delete(key []byte) error {
	err := b.boltBucket.Delete(key)
	b.bm.delHash(string(key))
	return err
}
978558
func (s *SkipList) Delete(key interface{}) (value interface{}, ok bool) {
	if key == nil {
		panic("goskiplist: nil keys are not supported")
	}
	update := make([]*node, s.level()+1, s.effectiveMaxLevel())
	candidate := s.getPath(s.header, update, key)

	if candidate == nil || candidate.key != key {
		return nil, false
	}

	previous := candidate.backward
	if s.footer == candidate {
		s.footer = previous
	}

	next := candidate.next()
	if next != nil {
		next.backward = previous
	}

	for i := 0; i <= s.level() && update[i].forward[i] == candidate; i++ {
		update[i].forward[i] = candidate.forward[i]
	}

	for s.level() > 0 && s.header.forward[s.level()] == nil {
		s.header.forward = s.header.forward[:s.level()]
	}
	s.length--

	return candidate.value, true
}
1152588
func (k *KeyValueStringSlice) Delete(key string) {
	for i := 0; i < len(k.Keys); i++ {
		if k.Keys[i] == key {
			k.Keys = k.deleteIndex(i, k.Keys)
			k.Values = k.deleteIndex(i, k.Values)
		}
	}
}
1078436
func (c *LedisCacher) Delete(key string) (err error) {
	if _, err = c.c.Del([]byte(key)); err != nil {
		return err
	}
	_, err = c.c.HDel(defaultHSetName, []byte(key))
	return err
}
330905
func (c *RedisCacher) Delete(key string) error {
	key = c.prefix + key
	if err := c.c.Del(key).Err(); err != nil {
		return err
	}

	if c.occupyMode {
		return nil
	}
	return c.c.HDel(c.hsetName, key).Err()
}
70711
func (r *PrevRevisions) Del(key string) (found bool, prev datasync.KeyVal) {
	found, prev = r.Get(key)

	if found {
		r.mu.Lock()
		delete(r.revisions, key)
		r.mu.Unlock()
	}

	return found, prev
}
1002271
func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) {
	switch n := n.(type) {
	case *shortNode:
		matchlen := prefixLen(key, n.Key)
		if matchlen < len(n.Key) {
			return false, n, nil // don't replace n on mismatch
		}
		if matchlen == len(key) {
			return true, nil, nil // remove n entirely for whole matches
		}
		// The key is longer than n.Key. Remove the remaining suffix
		// from the subtrie. Child can never be nil here since the
		// subtrie must contain at least two other values with keys
		// longer than n.Key.
		dirty, child, err := t.delete(n.Val, append(prefix, key[:len(n.Key)]...), key[len(n.Key):])
		if !dirty || err != nil {
			return false, n, err
		}
		switch child := child.(type) {
		case *shortNode:
			// Deleting from the subtrie reduced it to another
			// short node. Merge the nodes to avoid creating a
			// shortNode{..., shortNode{...}}. Use concat (which
			// always creates a new slice) instead of append to
			// avoid modifying n.Key since it might be shared with
			// other nodes.
			return true, &shortNode{concat(n.Key, child.Key...), child.Val, t.newFlag()}, nil
		default:
			return true, &shortNode{n.Key, child, t.newFlag()}, nil
		}

	case *fullNode:
		dirty, nn, err := t.delete(n.Children[key[0]], append(prefix, key[0]), key[1:])
		if !dirty || err != nil {
			return false, n, err
		}
		n = n.copy()
		n.flags = t.newFlag()
		n.Children[key[0]] = nn

		// Check how many non-nil entries are left after deleting and
		// reduce the full node to a short node if only one entry is
		// left. Since n must've contained at least two children
		// before deletion (otherwise it would not be a full node) n
		// can never be reduced to nil.
		//
		// When the loop is done, pos contains the index of the single
		// value that is left in n or -2 if n contains at least two
		// values.
		pos := -1
		for i, cld := range &n.Children {
			if cld != nil {
				if pos == -1 {
					pos = i
				} else {
					pos = -2
					break
				}
			}
		}
		if pos >= 0 {
			if pos != 16 {
				// If the remaining entry is a short node, it replaces
				// n and its key gets the missing nibble tacked to the
				// front. This avoids creating an invalid
				// shortNode{..., shortNode{...}}.  Since the entry
				// might not be loaded yet, resolve it just for this
				// check.
				cnode, err := t.resolve(n.Children[pos], prefix)
				if err != nil {
					return false, nil, err
				}
				if cnode, ok := cnode.(*shortNode); ok {
					k := append([]byte{byte(pos)}, cnode.Key...)
					return true, &shortNode{k, cnode.Val, t.newFlag()}, nil
				}
			}
			// Otherwise, n is replaced by a one-nibble short node
			// containing the child.
			return true, &shortNode{[]byte{byte(pos)}, n.Children[pos], t.newFlag()}, nil
		}
		// n still contains at least two values and cannot be reduced.
		return true, n, nil

	case valueNode:
		return true, nil, nil

	case nil:
		return false, nil, nil

	case hashNode:
		// We've hit a part of the trie that isn't loaded yet. Load
		// the node and delete from it. This leaves all child nodes on
		// the path to the value in the trie.
		rn, err := t.resolveHash(n, prefix)
		if err != nil {
			return false, nil, err
		}
		dirty, nn, err := t.delete(rn, prefix, key)
		if !dirty || err != nil {
			return false, rn, err
		}
		return true, nn, nil

	default:
		panic(fmt.Sprintf("%T: invalid node: %v (%v)", n, n, key))
	}
}
535778
func (p *DB) Delete(key []byte) error {
	p.mu.Lock()
	defer p.mu.Unlock()

	node, exact := p.findGE(key, true)
	if !exact {
		return ErrNotFound
	}

	h := p.nodeData[node+nHeight]
	for i, n := range p.prevNode[:h] {
		m := n + 4 + i
		p.nodeData[m] = p.nodeData[p.nodeData[m]+nNext+i]
	}

	p.kvSize -= p.nodeData[node+nKey] + p.nodeData[node+nVal]
	p.n--
	return nil
}