示例#1
0
文件: queue.go 项目: mijia/rocksq
func (q *Queue) Dequeue(startId ...uint64) (uint64, []byte, error) {
	store := q.store

	var seekId uint64 = 1
	if len(startId) > 0 {
		seekId = startId[0]
	}
	if seekId < 1 {
		seekId = 1
	}

	var it *rocks.Iterator
	if q.useTailing {
		it = q.tailIterator
		if !it.Valid() {
			// FIXME?(mijia): When Dequeue happens faster than enqueue, the tail iterator would be exhausted
			// so we have seek it again.
			it.Seek(q.key(seekId))
		}
	} else {
		it = store.NewIteratorCF(store.ro, q.cfHandle)
		defer it.Close()
		it.Seek(q.key(seekId))
	}

	if !it.Valid() {
		return 0, nil, EmptyQueue
	}

	wb := rocks.NewWriteBatch()
	defer wb.Destroy()
	key := makeSlice(it.Key())
	value := makeSlice(it.Value())
	wb.DeleteCF(q.cfHandle, key)
	wb.MergeCF(q.cfHandle, q.metaKey("head"), oneBinary)
	err := store.Write(store.wo, wb)
	if err == nil {
		atomic.AddUint64(&q.head, 1)
		if q.useTailing {
			it.Next()
		}
	}

	id := q.id(key)
	log.Debugf("[Queue] Dequeued data id=%d, err=%v", id, err)
	return id, value, err
}