当前位置: 首页>>代码示例>>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;未经允许,请勿转载。