mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
* implemented distinct * implemented distinct * uses first cut of a buffer pool, and extendible hashing with thresholded spill to disk * tests * cleaned up some stuff around query plan output to make developing tooling easier * added optimization to call PQL Distinct() * fixed test * fix for passing wrong index name in orchestrator * back out change to DistinctTimestamp * fix other instance of wrong table name being passed * use full index name instead of abbreviated one for translation. sigh. * removed some unused code Co-authored-by: Matthew Jaffee <jaffee@pilosa.com>
64 lines
1.5 KiB
Go
64 lines
1.5 KiB
Go
package bufferpool
|
|
|
|
import "errors"
|
|
|
|
// ClockReplacer implements a clock replacer algorithm
|
|
type ClockReplacer struct {
|
|
cList *circularList
|
|
clockHand **circularListNode
|
|
}
|
|
|
|
// NewClockReplacer instantiates a new clock replacer
|
|
func NewClockReplacer(poolSize int) *ClockReplacer {
|
|
cList := newCircularList(poolSize)
|
|
return &ClockReplacer{cList, &cList.head}
|
|
}
|
|
|
|
// Victim removes the victim frame as defined by the replacement policy
|
|
func (c *ClockReplacer) Victim() (FrameID, error) {
|
|
if c.cList.size == 0 {
|
|
return FrameID(INVALID_PAGE), errors.New("no victims available")
|
|
}
|
|
var victimFrameID FrameID
|
|
currentNode := (*c.clockHand)
|
|
for {
|
|
|
|
if currentNode.value.(bool) {
|
|
currentNode.value = false
|
|
c.clockHand = ¤tNode.next
|
|
} else {
|
|
frameID := currentNode.key.(FrameID)
|
|
victimFrameID = frameID
|
|
c.clockHand = ¤tNode.next
|
|
c.cList.remove(currentNode.key)
|
|
return victimFrameID, nil
|
|
}
|
|
}
|
|
}
|
|
|
|
// Unpin unpins a frame, indicating that it can now be victimized
|
|
func (c *ClockReplacer) Unpin(id FrameID) {
|
|
if !c.cList.hasKey(id) {
|
|
c.cList.insert(id, true)
|
|
if c.cList.size == 1 {
|
|
c.clockHand = &c.cList.head
|
|
}
|
|
}
|
|
}
|
|
|
|
// Pin pins a frame, indicating that it should not be victimized until it is unpinned
|
|
func (c *ClockReplacer) Pin(id FrameID) {
|
|
node := c.cList.find(id)
|
|
if node == nil {
|
|
return
|
|
}
|
|
if (*c.clockHand) == node {
|
|
c.clockHand = &(*c.clockHand).next
|
|
}
|
|
c.cList.remove(id)
|
|
}
|
|
|
|
// Size returns the size of the clock
|
|
func (c *ClockReplacer) Size() int {
|
|
return c.cList.size
|
|
}
|