當前位置: 首頁>>代碼示例>>Golang>>正文


Golang atomic.LoadPointer函數代碼示例

本文整理匯總了Golang中sync/atomic.LoadPointer函數的典型用法代碼示例。如果您正苦於以下問題:Golang LoadPointer函數的具體用法?Golang LoadPointer怎麽用?Golang LoadPointer使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。


在下文中一共展示了LoadPointer函數的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。

示例1: GetOrInsert

func (m *Map) GetOrInsert(k uint64, v unsafe.Pointer) unsafe.Pointer {
	if v == nil {
		log.Fatal("GetOrInsert doesn't allow setting nil pointers.")
		return nil
	}

	// Check immutable first.
	cval := atomic.LoadPointer(&m.cs[IMMUTABLE])
	if cval != nil {
		c := (*container)(cval)
		if pv := c.get(k); pv != nil {
			return pv
		}
	}

	// Okay, deal with mutable container now.
	cval = atomic.LoadPointer(&m.cs[MUTABLE])
	if cval == nil {
		log.Fatal("This is disruptive in a bad way.")
	}
	c := (*container)(cval)
	if pv := c.getOrInsert(k, v); pv != nil {
		return pv
	}

	// We still couldn't insert the key. Time to grow.
	// TODO: Handle this case.
	return nil
}
開發者ID:dgraph-io,項目名稱:experiments,代碼行數:29,代碼來源:map.go

示例2: getOrInsert

func (c *container) getOrInsert(k uint64, v unsafe.Pointer) unsafe.Pointer {
	bi := k & (c.sz - 1)
	b := c.list[bi]
	for i := range b.elems {
		e := &b.elems[i]
		// Once allocated a valid key, it would never change. So, first check if
		// it's allocated. If not, then allocate it. If can't, or not allocated,
		// then check if it's k. If it is, then replace value. Otherwise continue.
		// This sequence could be problematic, if this happens:
		// Main thread runs Step 1. Check
		if atomic.CompareAndSwapUint64(&e.k, 0, k) { // Step 1.
			atomic.AddUint32(&c.numElems, 1)
			if atomic.CompareAndSwapPointer(&e.v, nil, v) {
				return v
			}
			return atomic.LoadPointer(&e.v)
		}

		if atomic.LoadUint64(&e.k) == k {
			// Swap if previous pointer is nil.
			if atomic.CompareAndSwapPointer(&e.v, nil, v) {
				return v
			}
			return atomic.LoadPointer(&e.v)
		}
	}
	return nil
}
開發者ID:dgraph-io,項目名稱:experiments,代碼行數:28,代碼來源:map.go

示例3: Preparex

func (db *DB) Preparex(query string) (stmt Stmt, err error) {
	var m stmtCache

	if p := (*stmtCache)(atomic.LoadPointer(&db.stmtCachePtr)); p != nil {
		m = *p
		if stmt = m[query]; stmt.Stmt != nil {
			return
		}
	}

	db.stmtCachePtrMutex.Lock()
	defer db.stmtCachePtrMutex.Unlock()

	if p := (*stmtCache)(atomic.LoadPointer(&db.stmtCachePtr)); p != nil {
		m = *p
		if stmt = m[query]; stmt.Stmt != nil {
			return
		}
	}

	stmtx, err := db.DB.Preparex(query)
	if err != nil {
		return
	}
	stmt = Stmt{Stmt: stmtx}

	m2 := make(stmtCache, len(m)+1)
	for k, v := range m {
		m2[k] = v
	}
	m2[query] = stmt

	atomic.StorePointer(&db.stmtCachePtr, unsafe.Pointer(&m2))
	return
}
開發者ID:chanxuehong,項目名稱:database,代碼行數:35,代碼來源:sqlx.go

示例4: next

func (self *element) next() *element {
	next := atomic.LoadPointer(&self.Pointer)
	for next != nil {
		/*
		 If the pointer of the next element is marked as deleted, that means the next element is supposed to be GONE
		*/
		if nextPointer := atomic.LoadPointer(&(*element)(normal(next)).Pointer); isDeleted(nextPointer) {
			/*
			 If OUR pointer is marked as deleted, that means WE are supposed to be gone
			*/
			if isDeleted(next) {
				/*
				 .. which means that we can steal the pointer of the next element right away,
				 it points to the right place AND it is marked as deleted.
				*/
				atomic.CompareAndSwapPointer(&self.Pointer, next, nextPointer)
			} else {
				/*
				 .. if not, we have to remove the marking on the pointer before we steal it.
				*/
				atomic.CompareAndSwapPointer(&self.Pointer, next, normal(nextPointer))
			}
			next = atomic.LoadPointer(&self.Pointer)
		} else {
			/*
			 If the next element is NOT deleted, then we simply return a pointer to it, and make
			 damn sure that the pointer is a working one even if we are deleted (and, therefore,
			 our pointer is marked as deleted).
			*/
			return (*element)(normal(next))
		}
	}
	return nil
}
開發者ID:sedzinreri,項目名稱:gotomic,代碼行數:34,代碼來源:list.go

示例5: mutate

func (p *partitionstore) mutate(cb func(keys, changes *gkvlite.Collection)) {
	p.lock.Lock()
	defer p.lock.Unlock()

	cb((*gkvlite.Collection)(atomic.LoadPointer(&p.keys)),
		(*gkvlite.Collection)(atomic.LoadPointer(&p.changes)))
}
開發者ID:steveyen,項目名稱:cbgb,代碼行數:7,代碼來源:partition.go

示例6: visitItems

func (p *partitionstore) visitItems(start []byte, withValue bool,
	visitor func(*item) bool) (err error) {
	keys, changes := p.colls()
	var vErr error
	v := func(kItem *gkvlite.Item) bool {
		i := (*item)(atomic.LoadPointer(&kItem.Transient))
		if i != nil {
			return visitor(i)
		}
		var cItem *gkvlite.Item
		cItem, vErr = changes.GetItem(kItem.Val, true)
		if vErr != nil {
			return false
		}
		if cItem == nil {
			return true // TODO: track this case; might have been compacted away.
		}
		i = (*item)(atomic.LoadPointer(&cItem.Transient))
		if i != nil {
			atomic.StorePointer(&kItem.Transient, unsafe.Pointer(i))
			return visitor(i)
		}
		i = &item{key: kItem.Key}
		if vErr = i.fromValueBytes(cItem.Val); vErr != nil {
			return false
		}
		atomic.StorePointer(&cItem.Transient, unsafe.Pointer(i))
		atomic.StorePointer(&kItem.Transient, unsafe.Pointer(i))
		return visitor(i)
	}
	if err := p.visit(keys, start, true, v); err != nil {
		return err
	}
	return vErr
}
開發者ID:steveyen,項目名稱:cbgb,代碼行數:35,代碼來源:partition.go

示例7: cacheEvict

func (cache *DCache) cacheEvict(fpos int64) Node {
	var node Node
	idx := cache.indexFor(fpos)
	for {
		var retry bool
		hash := (*[]unsafe.Pointer)(atomic.LoadPointer(&(cache.hash)))
		addr := &((*hash)[idx])
		hd := (*DCacheItem)(atomic.LoadPointer(addr))
		for hd != nil {
			nx := atomic.LoadPointer(&hd.next)
			if hd.fpos == fpos {
				if !atomic.CompareAndSwapPointer(addr, unsafe.Pointer(hd), nx) {
					retry = true
				} else {
					node = hd.node
				}
				break
			}
			addr = &hd.next
			hd = (*DCacheItem)(nx)
		}
		if retry {
			continue
		}
		break
	}
	return node
}
開發者ID:prataprc,項目名稱:gobtree,代碼行數:28,代碼來源:cache.go

示例8: next

func (self *element) next() *element {
	next := atomic.LoadPointer(&self.Pointer)
	for next != nil {
		nextElement := (*element)(next)
		/*
		 If our next element contains &deletedElement that means WE are deleted, and
		 we can just return the next-next element. It will make it impossible to add
		 stuff to us, since we will always lie about our next(), but then again, deleted
		 elements shouldn't get new children anyway.
		*/
		if sp, ok := nextElement.value.(*string); ok && sp == &deletedElement {
			return nextElement.next()
		}
		/*
		 If our next element is itself deleted (by the same criteria) then we will just replace
		 it with its next() (which should be the first thing behind it that isn't itself deleted
		 (the power of recursion compels you) and then check again.
		*/
		if nextElement.isDeleted() {
			atomic.CompareAndSwapPointer(&self.Pointer, next, unsafe.Pointer(nextElement.next()))
			next = atomic.LoadPointer(&self.Pointer)
		} else {
			/*
			 If it isn't deleted then we just return it.
			*/
			return nextElement
		}
	}
	/*
	 And if our next is nil, then we are at the end of the list and can just return nil for next()
	*/
	return nil
}
開發者ID:andradeandrey,項目名稱:gotomic,代碼行數:33,代碼來源:list.go

示例9: Dequeue

// Dequeue returns the value at the head of the queue and true, or if the queue is empty, it returns a nil value and false
func (q *ZFifo) Dequeue() (value interface{}, ok bool) {
	for {
		head := atomic.LoadPointer(&q.head)               // Read head pointer
		tail := atomic.LoadPointer(&q.tail)               // Read tail pointer
		next := atomic.LoadPointer(&(*lfNode)(head).next) // Read head.next
		if head != q.head {                               // Check head, tail, and next consistency
			continue // Not consistent. Try again
		}

		if head == tail { // Is queue empty or tail failing behind
			if next == unsafe.Pointer(q) { // Is queue empty?
				return
			}
			// Try to swing tail to the next node as the tail was not pointing to the last node
			atomic.CompareAndSwapPointer(&q.tail, tail, next)
		} else {
			// Read value before CAS
			// Otherwise, another dequeue might free the next node
			value = (*lfNode)(next).value
			// Try to swing Head to the next node
			if atomic.CompareAndSwapPointer(&q.head, head, next) {
				ok = true
				return
			}
			value = nil
		}
	}
	return // Dummy return
}
開發者ID:egonelbre,項目名稱:goqueuestest,代碼行數:30,代碼來源:zfifo.go

示例10: advance

func (this *MapIterator) advance() {
	if this.nextE != nil {
		this.nextE = this.nextE.next
		if this.nextE != nil {
			return
		}
	}

	for this.nextTableIndex >= 0 {
		this.nextE = (*Entry)(atomic.LoadPointer(&this.currentTable[this.nextTableIndex]))
		this.nextTableIndex--
		if this.nextE != nil {
			return
		}
	}

	for this.nextSegmentIndex >= 0 {
		seg := this.cm.segments[this.nextSegmentIndex]
		this.nextSegmentIndex--
		if atomic.LoadInt32(&seg.count) != 0 {
			this.currentTable = seg.loadTable()
			for j := len(this.currentTable) - 1; j >= 0; j-- {
				this.nextE = (*Entry)(atomic.LoadPointer(&this.currentTable[j]))
				if this.nextE != nil {
					this.nextTableIndex = j - 1
					return
				}
			}
		}
	}
}
開發者ID:work-jlsun,項目名稱:go-concurrentMap,代碼行數:31,代碼來源:concurrentmap.go

示例11: checkPingPong

func (wstore *WStore) checkPingPong() {
	ncping := (*map[int64]Node)(atomic.LoadPointer(&wstore.ncping))
	ncpong := (*map[int64]Node)(atomic.LoadPointer(&wstore.ncpong))
	if len(*ncping) != len(*ncpong) {
		panic("Mismatch in nc ping-pong lengths")
	}
	for fpos := range *ncping {
		if (*ncpong)[fpos] == nil {
			panic("fpos not found in nc ping-pong")
		}
	}

	//lcping := (*map[int64]Node)(atomic.LoadPointer(&wstore.lcping))
	//lcpong := (*map[int64]Node)(atomic.LoadPointer(&wstore.lcpong))
	//if len(*lcping) != len(*lcpong) {
	//    panic("Mismatch in lc ping-pong lengths")
	//}
	//for fpos := range *lcping {
	//    if (*lcpong)[fpos] == nil {
	//        panic("fpos not found in lc ping-pong")
	//    }
	//}

	kdping := (*map[int64][]byte)(atomic.LoadPointer(&wstore.kdping))
	kdpong := (*map[int64][]byte)(atomic.LoadPointer(&wstore.kdpong))
	if len(*kdping) != len(*kdpong) {
		panic("Mismatch in kd ping-pong lengths")
	}
	for fpos := range *kdping {
		if (*kdpong)[fpos] == nil {
			panic("fpos not found in kd ping-pong")
		}
	}
}
開發者ID:prataprc,項目名稱:gobtree,代碼行數:34,代碼來源:ppcache.go

示例12: Seek

// Seek seeks the handle.
func (t *BoundedTable) Seek(ctx context.Context, handle int64) (int64, bool, error) {
	result := (*boundedItem)(nil)
	if handle < invalidRecordID {
		// this is the first seek call.
		result = (*boundedItem)(atomic.LoadPointer(&t.records[0]))
	} else {
		for i := int64(0); i < t.capacity; i++ {
			record := (*boundedItem)(atomic.LoadPointer(&t.records[i]))
			if record == nil {
				break
			}
			if handle == record.handle {
				result = record
				break
			}
		}
	}
	if result == nil {
		// handle not found.
		return invalidRecordID, false, nil
	}
	if result.handle != invalidRecordID {
		// this record is valid.
		return result.handle, true, nil
	}
	// this record is invalid.
	return invalidRecordID, false, nil
}
開發者ID:jmptrader,項目名稱:tidb,代碼行數:29,代碼來源:bounded_tables.go

示例13: gcasRead

// gcasRead performs a GCAS-linearizable read of the I-node's main node.
func gcasRead(in *iNode, ctrie *ctrie) *mainNode {
	m := (*mainNode)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&in.main))))
	prev := (*mainNode)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&m.prev))))
	if prev == nil {
		return m
	}
	return gcasComplete(in, m, ctrie)
}
開發者ID:alexandercampbell-wf,項目名稱:matchbox,代碼行數:9,代碼來源:ctrie.go

示例14: Insert

// Insert inserts v into the list in order. An error is returned if v is already present.
func (l *partitionList) Insert(v partition.Partition) error {
	n := &partitionListNode{
		val:  v,
		next: nil,
	}

HEAD:
	headPtr := atomic.LoadPointer(&l.head)

	if headPtr == nil {
		if !atomic.CompareAndSwapPointer(&l.head, headPtr, unsafe.Pointer(n)) {
			goto HEAD
		}

		atomic.AddInt32(&l.size, 1)
		return nil
	}

	headNode := (*partitionListNode)(headPtr)
	if comparePartitions(headNode.val, n.val) > 0 {
		n.next = headPtr
		if !atomic.CompareAndSwapPointer(&l.head, headPtr, unsafe.Pointer(n)) {
			goto HEAD
		}

		atomic.AddInt32(&l.size, 1)
		return nil
	}

NEXT:
	nextPtr := atomic.LoadPointer(&headNode.next)
	if nextPtr == nil {
		if !atomic.CompareAndSwapPointer(&headNode.next, nextPtr, unsafe.Pointer(n)) {
			goto NEXT
		}

		atomic.AddInt32(&l.size, 1)
		return nil
	}

	nextNode := (*partitionListNode)(nextPtr)
	if comparePartitions(nextNode.val, n.val) > 0 {
		n.next = nextPtr
		if !atomic.CompareAndSwapPointer(&headNode.next, nextPtr, unsafe.Pointer(n)) {
			goto NEXT
		}

		atomic.AddInt32(&l.size, 1)
		return nil
	}

	if comparePartitions(nextNode.val, n.val) == 0 {
		return errors.New("catena/partition_list: partition exists")
	}

	headNode = nextNode
	goto NEXT
}
開發者ID:jmptrader,項目名稱:catena,代碼行數:59,代碼來源:partition_list.go

示例15: getBucket

func (r *Cache) getBucket(hash uint32) (*mNode, *mBucket) {
	h := (*mNode)(atomic.LoadPointer(&r.mHead))
	i := hash & h.mask
	b := (*mBucket)(atomic.LoadPointer(&h.buckets[i]))
	if b == nil {
		b = h.initBucket(i)
	}
	return h, b
}
開發者ID:nikandfor,項目名稱:goleveldb,代碼行數:9,代碼來源:cache.go


注:本文中的sync/atomic.LoadPointer函數示例由純淨天空整理自Github/MSDocs等開源代碼及文檔管理平台,相關代碼片段篩選自各路編程大神貢獻的開源項目,源碼版權歸原作者所有,傳播和使用請參考對應項目的License;未經允許,請勿轉載。