//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

}
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
			}
		}
	}
}
Exemple #3
0
func (b *Bucket) init(nb *Bucket) {
	connHost, _, _ := net.SplitHostPort(b.pool.client.BaseURL.Host)
	for i := range nb.NodesJSON {
		nb.NodesJSON[i].Hostname = normalizeHost(connHost, nb.NodesJSON[i].Hostname)
	}

	newcps := make([]*connectionPool, len(nb.VBSMJson.ServerList))
	for i := range newcps {
		nb.VBSMJson.ServerList[i] = normalizeHost(connHost, nb.VBSMJson.ServerList[i])
		newcps[i] = newConnectionPool(
			nb.VBSMJson.ServerList[i],
			b.authHandler(), PoolSize, PoolOverflow)
	}
	b.replaceConnPools(newcps)
	platform.StorePointer(&b.vBucketServerMap, unsafe.Pointer(&nb.VBSMJson))
	platform.StorePointer(&b.nodeList, unsafe.Pointer(&nb.NodesJSON))
}
Exemple #4
0
func SetupBlockPool(sz int) {
	p := &sync.Pool{
		New: func() interface{} {
			b := make([]byte, sz, sz)
			return &b
		},
	}

	platform.StorePointer(&blockPool, unsafe.Pointer(p))
}
Exemple #5
0
func makeWithMetaProvider(
	cluster string, config common.Config) (c *GsiClient, err error) {

	c = &GsiClient{
		cluster:      cluster,
		config:       config,
		queryClients: make(map[string]*GsiScanClient),
	}
	platform.StorePointer(&c.bucketHash, (unsafe.Pointer)(new(map[string]uint64)))
	c.bridge, err = newMetaBridgeClient(cluster, config)
	if err != nil {
		return nil, err
	}
	c.updateScanClients()
	return c, nil
}
//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
}
Exemple #7
0
// create GSI client using cbqBridge and ScanCoordinator
func makeWithCbq(cluster string, config common.Config) (*GsiClient, error) {
	var err error
	c := &GsiClient{
		cluster:      cluster,
		config:       config,
		queryClients: make(map[string]*GsiScanClient),
	}
	platform.StorePointer(&c.bucketHash, (unsafe.Pointer)(new(map[string]uint64)))
	if c.bridge, err = newCbqClient(cluster); err != nil {
		return nil, err
	}
	for _, queryport := range c.bridge.GetScanports() {
		queryClient := NewGsiScanClient(queryport, config)
		c.queryClients[queryport] = queryClient
	}
	return c, nil
}
Exemple #8
0
func (h *ConfigHolder) Store(conf Config) {
	platform.StorePointer(&h.ptr, unsafe.Pointer(&conf))
}
Exemple #9
0
func (h *IndexerStatsHolder) Set(s *IndexerStats) {
	platform.StorePointer(&h.ptr, unsafe.Pointer(s))
}