all repos

rss-tools @ a5ac52722b131734c74504b6e6f4d9900536cac7

get rss feed from sources that(i need and) dont provide one

rss-tools/vendor/go.etcd.io/bbolt/internal/freelist/array.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
we're vendoring now, 7 days ago
1
package freelist
2
3
import (
4
	"fmt"
5
	"sort"
6
7
	"go.etcd.io/bbolt/internal/common"
8
)
9
10
type array struct {
11
	*shared
12
13
	ids []common.Pgid // all free and available free page ids.
14
}
15
16
func (f *array) Init(ids common.Pgids) {
17
	f.ids = ids
18
	f.reindex()
19
}
20
21
func (f *array) Allocate(txid common.Txid, n int) common.Pgid {
22
	if len(f.ids) == 0 {
23
		return 0
24
	}
25
26
	var initial, previd common.Pgid
27
	for i, id := range f.ids {
28
		if id <= 1 {
29
			panic(fmt.Sprintf("invalid page allocation: %d", id))
30
		}
31
32
		// Reset initial page if this is not contiguous.
33
		if previd == 0 || id-previd != 1 {
34
			initial = id
35
		}
36
37
		// If we found a contiguous block then remove it and return it.
38
		if (id-initial)+1 == common.Pgid(n) {
39
			// If we're allocating off the beginning then take the fast path
40
			// and just adjust the existing slice. This will use extra memory
41
			// temporarily but the append() in free() will realloc the slice
42
			// as is necessary.
43
			if (i + 1) == n {
44
				f.ids = f.ids[i+1:]
45
			} else {
46
				copy(f.ids[i-n+1:], f.ids[i+1:])
47
				f.ids = f.ids[:len(f.ids)-n]
48
			}
49
50
			// Remove from the free cache.
51
			for i := common.Pgid(0); i < common.Pgid(n); i++ {
52
				delete(f.cache, initial+i)
53
			}
54
			f.allocs[initial] = txid
55
			return initial
56
		}
57
58
		previd = id
59
	}
60
	return 0
61
}
62
63
func (f *array) FreeCount() int {
64
	return len(f.ids)
65
}
66
67
func (f *array) freePageIds() common.Pgids {
68
	return f.ids
69
}
70
71
func (f *array) mergeSpans(ids common.Pgids) {
72
	sort.Sort(ids)
73
	common.Verify(func() {
74
		idsIdx := make(map[common.Pgid]struct{})
75
		for _, id := range f.ids {
76
			// The existing f.ids shouldn't have duplicated free ID.
77
			if _, ok := idsIdx[id]; ok {
78
				panic(fmt.Sprintf("detected duplicated free page ID: %d in existing f.ids: %v", id, f.ids))
79
			}
80
			idsIdx[id] = struct{}{}
81
		}
82
83
		prev := common.Pgid(0)
84
		for _, id := range ids {
85
			// The ids shouldn't have duplicated free ID. Note page 0 and 1
86
			// are reserved for meta pages, so they can never be free page IDs.
87
			if prev == id {
88
				panic(fmt.Sprintf("detected duplicated free ID: %d in ids: %v", id, ids))
89
			}
90
			prev = id
91
92
			// The ids shouldn't have any overlap with the existing f.ids.
93
			if _, ok := idsIdx[id]; ok {
94
				panic(fmt.Sprintf("detected overlapped free page ID: %d between ids: %v and existing f.ids: %v", id, ids, f.ids))
95
			}
96
		}
97
	})
98
	f.ids = common.Pgids(f.ids).Merge(ids)
99
}
100
101
func NewArrayFreelist() Interface {
102
	a := &array{
103
		shared: newShared(),
104
		ids:    []common.Pgid{},
105
	}
106
	a.Interface = a
107
	return a
108
}