//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 } } } }
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)) }
func SetupBlockPool(sz int) { p := &sync.Pool{ New: func() interface{} { b := make([]byte, sz, sz) return &b }, } platform.StorePointer(&blockPool, unsafe.Pointer(p)) }
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 }
// 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 }
func (h *ConfigHolder) Store(conf Config) { platform.StorePointer(&h.ptr, unsafe.Pointer(&conf)) }
func (h *IndexerStatsHolder) Set(s *IndexerStats) { platform.StorePointer(&h.ptr, unsafe.Pointer(s)) }