mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	Refactor issue indexer (#5363)
This commit is contained in:
		
				
					committed by
					
						 techknowlogick
						techknowlogick
					
				
			
			
				
	
			
			
			
						parent
						
							094263db4d
						
					
				
				
					commit
					830ae61456
				
			
							
								
								
									
										214
									
								
								vendor/github.com/lunny/levelqueue/queue.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										214
									
								
								vendor/github.com/lunny/levelqueue/queue.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,214 @@ | ||||
| // Copyright 2019 Lunny Xiao. All rights reserved. | ||||
| // Use of this source code is governed by a MIT-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package levelqueue | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/binary" | ||||
| 	"sync" | ||||
|  | ||||
| 	"github.com/syndtr/goleveldb/leveldb" | ||||
| ) | ||||
|  | ||||
| // Queue defines a queue struct | ||||
| type Queue struct { | ||||
| 	db       *leveldb.DB | ||||
| 	highLock sync.Mutex | ||||
| 	lowLock  sync.Mutex | ||||
| 	low      int64 | ||||
| 	high     int64 | ||||
| } | ||||
|  | ||||
| // Open opens a queue object or create it if not exist | ||||
| func Open(dataDir string) (*Queue, error) { | ||||
| 	db, err := leveldb.OpenFile(dataDir, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	var queue = &Queue{ | ||||
| 		db: db, | ||||
| 	} | ||||
| 	queue.low, err = queue.readID(lowKey) | ||||
| 	if err == leveldb.ErrNotFound { | ||||
| 		queue.low = 1 | ||||
| 		err = db.Put(lowKey, id2bytes(1), nil) | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	queue.high, err = queue.readID(highKey) | ||||
| 	if err == leveldb.ErrNotFound { | ||||
| 		err = db.Put(highKey, id2bytes(0), nil) | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return queue, nil | ||||
| } | ||||
|  | ||||
| func (queue *Queue) readID(key []byte) (int64, error) { | ||||
| 	bs, err := queue.db.Get(key, nil) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return bytes2id(bs) | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	lowKey  = []byte("low") | ||||
| 	highKey = []byte("high") | ||||
| ) | ||||
|  | ||||
| func (queue *Queue) highincrement() (int64, error) { | ||||
| 	id := queue.high + 1 | ||||
| 	queue.high = id | ||||
| 	err := queue.db.Put(highKey, id2bytes(queue.high), nil) | ||||
| 	if err != nil { | ||||
| 		queue.high = queue.high - 1 | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return id, nil | ||||
| } | ||||
|  | ||||
| func (queue *Queue) highdecrement() (int64, error) { | ||||
| 	queue.high = queue.high - 1 | ||||
| 	err := queue.db.Put(highKey, id2bytes(queue.high), nil) | ||||
| 	if err != nil { | ||||
| 		queue.high = queue.high + 1 | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return queue.high, nil | ||||
| } | ||||
|  | ||||
| func (queue *Queue) lowincrement() (int64, error) { | ||||
| 	queue.low = queue.low + 1 | ||||
| 	err := queue.db.Put(lowKey, id2bytes(queue.low), nil) | ||||
| 	if err != nil { | ||||
| 		queue.low = queue.low - 1 | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return queue.low, nil | ||||
| } | ||||
|  | ||||
| func (queue *Queue) lowdecrement() (int64, error) { | ||||
| 	queue.low = queue.low - 1 | ||||
| 	err := queue.db.Put(lowKey, id2bytes(queue.low), nil) | ||||
| 	if err != nil { | ||||
| 		queue.low = queue.low + 1 | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return queue.low, nil | ||||
| } | ||||
|  | ||||
| // Len returns the length of the queue | ||||
| func (queue *Queue) Len() int64 { | ||||
| 	queue.lowLock.Lock() | ||||
| 	queue.highLock.Lock() | ||||
| 	l := queue.high - queue.low + 1 | ||||
| 	queue.highLock.Unlock() | ||||
| 	queue.lowLock.Unlock() | ||||
| 	return l | ||||
| } | ||||
|  | ||||
| func id2bytes(id int64) []byte { | ||||
| 	var buf = make([]byte, 8) | ||||
| 	binary.PutVarint(buf, id) | ||||
| 	return buf | ||||
| } | ||||
|  | ||||
| func bytes2id(b []byte) (int64, error) { | ||||
| 	return binary.ReadVarint(bytes.NewReader(b)) | ||||
| } | ||||
|  | ||||
| // RPush pushes a data from right of queue | ||||
| func (queue *Queue) RPush(data []byte) error { | ||||
| 	queue.highLock.Lock() | ||||
| 	id, err := queue.highincrement() | ||||
| 	if err != nil { | ||||
| 		queue.highLock.Unlock() | ||||
| 		return err | ||||
| 	} | ||||
| 	err = queue.db.Put(id2bytes(id), data, nil) | ||||
| 	queue.highLock.Unlock() | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // LPush pushes a data from left of queue | ||||
| func (queue *Queue) LPush(data []byte) error { | ||||
| 	queue.highLock.Lock() | ||||
| 	id, err := queue.lowdecrement() | ||||
| 	if err != nil { | ||||
| 		queue.highLock.Unlock() | ||||
| 		return err | ||||
| 	} | ||||
| 	err = queue.db.Put(id2bytes(id), data, nil) | ||||
| 	queue.highLock.Unlock() | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // RPop pop a data from right of queue | ||||
| func (queue *Queue) RPop() ([]byte, error) { | ||||
| 	queue.highLock.Lock() | ||||
| 	currentID := queue.high | ||||
|  | ||||
| 	res, err := queue.db.Get(id2bytes(currentID), nil) | ||||
| 	if err != nil { | ||||
| 		queue.highLock.Unlock() | ||||
| 		if err == leveldb.ErrNotFound { | ||||
| 			return nil, ErrNotFound | ||||
| 		} | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	_, err = queue.highdecrement() | ||||
| 	if err != nil { | ||||
| 		queue.highLock.Unlock() | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	err = queue.db.Delete(id2bytes(currentID), nil) | ||||
| 	queue.highLock.Unlock() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return res, nil | ||||
| } | ||||
|  | ||||
| // LPop pop a data from left of queue | ||||
| func (queue *Queue) LPop() ([]byte, error) { | ||||
| 	queue.lowLock.Lock() | ||||
| 	currentID := queue.low | ||||
|  | ||||
| 	res, err := queue.db.Get(id2bytes(currentID), nil) | ||||
| 	if err != nil { | ||||
| 		queue.lowLock.Unlock() | ||||
| 		if err == leveldb.ErrNotFound { | ||||
| 			return nil, ErrNotFound | ||||
| 		} | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	_, err = queue.lowincrement() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	err = queue.db.Delete(id2bytes(currentID), nil) | ||||
| 	queue.lowLock.Unlock() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return res, nil | ||||
| } | ||||
|  | ||||
| // Close closes the queue | ||||
| func (queue *Queue) Close() error { | ||||
| 	err := queue.db.Close() | ||||
| 	queue.db = nil | ||||
| 	return err | ||||
| } | ||||
		Reference in New Issue
	
	Block a user