Пример #1
0
func (q *atomicMutationQueue) dequeueUptoSeqno(vbucket Vbucket, seqno Seqno,
	datach chan *MutationKeys) {

	//every DEQUEUE_POLL_INTERVAL milliseconds, check for new mutations
	ticker := time.NewTicker(time.Millisecond * DEQUEUE_POLL_INTERVAL)

	var dequeueSeq Seqno

	for _ = range ticker.C {
		for platform.LoadPointer(&q.head[vbucket]) !=
			platform.LoadPointer(&q.tail[vbucket]) { //if queue is nonempty

			head := (*node)(platform.LoadPointer(&q.head[vbucket]))
			//copy the mutation pointer
			m := head.next.mutation
			if seqno >= m.meta.seqno {
				//free mutation pointer
				head.next.mutation = nil
				//move head to next
				platform.StorePointer(&q.head[vbucket], unsafe.Pointer(head.next))
				platform.AddInt64(&q.size[vbucket], -1)
				//send mutation to caller
				dequeueSeq = m.meta.seqno
				datach <- m
			}

			//once the seqno is reached, close the channel
			if seqno <= dequeueSeq {
				ticker.Stop()
				close(datach)
				return
			}
		}
	}
}
Пример #2
0
//PeekHead returns reference to a vbucket's mutation at head of queue without dequeue
func (q *atomicMutationQueue) PeekHead(vbucket Vbucket) *MutationKeys {
	if platform.LoadPointer(&q.head[vbucket]) !=
		platform.LoadPointer(&q.tail[vbucket]) { //if queue is nonempty
		head := (*node)(platform.LoadPointer(&q.head[vbucket]))
		return head.mutation
	}
	return nil
}
Пример #3
0
//Enqueue will enqueue the mutation reference for given vbucket.
//Caller should not free the mutation till it is dequeued.
//Mutation will not be copied internally by the queue.
//caller can call appch to force this call to return. Otherwise
//this is a blocking call till there is a slot available for enqueue.
func (q *atomicMutationQueue) Enqueue(mutation *MutationKeys,
	vbucket Vbucket, appch StopChannel) error {

	if vbucket < 0 || vbucket > Vbucket(q.numVbuckets)-1 {
		return errors.New("vbucket out of range")
	}

	//no more requests are taken once queue
	//is marked as destroyed
	if q.isDestroyed {
		return nil
	}

	//create a new node
	n := q.allocNode(vbucket, appch)
	if n == nil {
		return nil
	}

	n.mutation = mutation
	n.next = nil

	//point tail's next to new node
	tail := (*node)(platform.LoadPointer(&q.tail[vbucket]))
	tail.next = n
	//update tail to new node
	platform.StorePointer(&q.tail[vbucket], unsafe.Pointer(tail.next))

	platform.AddInt64(&q.size[vbucket], 1)

	return nil

}
Пример #4
0
//DequeueSingleElement dequeues a single element and returns.
//Returns nil in case of empty queue.
func (q *atomicMutationQueue) DequeueSingleElement(vbucket Vbucket) *MutationKeys {

	if platform.LoadPointer(&q.head[vbucket]) !=
		platform.LoadPointer(&q.tail[vbucket]) { //if queue is nonempty

		head := (*node)(platform.LoadPointer(&q.head[vbucket]))
		//copy the mutation pointer
		m := head.next.mutation
		//free mutation pointer
		head.next.mutation = nil
		//move head to next
		platform.StorePointer(&q.head[vbucket], unsafe.Pointer(head.next))
		platform.AddInt64(&q.size[vbucket], -1)
		return m
	}
	return nil
}
Пример #5
0
//popFreeList removes a node from freelist and returns to caller.
//if freelist is empty, it returns nil.
func (q *atomicMutationQueue) popFreeList(vbucket Vbucket) *node {

	if q.free[vbucket] != (*node)(platform.LoadPointer(&q.head[vbucket])) {
		n := q.free[vbucket]
		q.free[vbucket] = q.free[vbucket].next
		n.mutation = nil
		n.next = nil
		return n
	} else {
		return nil
	}

}
Пример #6
0
func (c *GsiClient) setBucketHash(bucketn string, crc64 uint64) {
	for {
		ptr := platform.LoadPointer(&c.bucketHash)
		oldm := (*map[string]uint64)(ptr)
		newm := map[string]uint64{}
		for k, v := range *oldm {
			newm[k] = v
		}
		newm[bucketn] = crc64
		if platform.CompareAndSwapPointer(&c.bucketHash, ptr, unsafe.Pointer(&newm)) {
			return
		}
	}
}
Пример #7
0
func (b *Bucket) replaceConnPools(with []*connectionPool) {
	for {
		old := platform.LoadPointer(&b.connPools)
		if platform.CompareAndSwapPointer(&b.connPools, old, unsafe.Pointer(&with)) {
			if old != nil {
				for _, pool := range *(*[]*connectionPool)(old) {
					if pool != nil {
						pool.Close()
					}
				}
			}
			return
		}
	}
}
Пример #8
0
func (h *ConfigHolder) Load() Config {
	confptr := platform.LoadPointer(&h.ptr)
	return *(*Config)(confptr)
}
Пример #9
0
func getBlockPool() *sync.Pool {
	return (*sync.Pool)(platform.LoadPointer(&blockPool))
}
Пример #10
0
func (c *GsiClient) getBucketHash(bucketn string) (uint64, bool) {
	bucketHash := (*map[string]uint64)(platform.LoadPointer(&c.bucketHash))
	crc64, ok := (*bucketHash)[bucketn]
	return crc64, ok
}
Пример #11
0
func (b Bucket) getConnPools() []*connectionPool {
	return *(*[]*connectionPool)(platform.LoadPointer(&b.connPools))
}
Пример #12
0
// Nodes returns teh current list of nodes servicing this bucket.
func (b Bucket) Nodes() []Node {
	return *(*[]Node)(platform.LoadPointer(&b.nodeList))
}
Пример #13
0
// VBServerMap returns the current VBucketServerMap.
func (b *Bucket) VBServerMap() *VBucketServerMap {
	return (*VBucketServerMap)(platform.LoadPointer(&(b.vBucketServerMap)))
}
Пример #14
0
func (h IndexerStatsHolder) Get() *IndexerStats {
	return (*IndexerStats)(platform.LoadPointer(&h.ptr))
}