-
Notifications
You must be signed in to change notification settings - Fork 9
/
flushable.go
94 lines (85 loc) · 3.32 KB
/
flushable.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Copyright 2020 The LevelDB-Go and Pebble and Bitalostored Authors. All rights reserved. Use
// of this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
package bitalostable
import (
"fmt"
"sync/atomic"
"time"
"github.com/zuoyebang/bitalostable/internal/keyspan"
"github.com/zuoyebang/bitalostable/internal/manual"
)
// flushable defines the interface for immutable memtables.
type flushable interface {
newIter(o *IterOptions) internalIterator
newFlushIter(o *IterOptions, bytesFlushed *uint64) internalIterator
newRangeDelIter(o *IterOptions) keyspan.FragmentIterator
newRangeKeyIter(o *IterOptions) keyspan.FragmentIterator
containsRangeKeys() bool
// inuseBytes returns the number of inuse bytes by the flushable.
inuseBytes() uint64
// totalBytes returns the total number of bytes allocated by the flushable.
totalBytes() uint64
// readyForFlush returns true when the flushable is ready for flushing. See
// memTable.readyForFlush for one implementation which needs to check whether
// there are any outstanding write references.
readyForFlush() bool
release()
}
// flushableEntry wraps a flushable and adds additional metadata and
// functionality that is common to all flushables.
type flushableEntry struct {
flushable
// Channel which is closed when the flushable has been flushed.
flushed chan struct{}
// flushForced indicates whether a flush was forced on this memtable (either
// manual, or due to ingestion). Protected by DB.mu.
flushForced bool
// delayedFlushForcedAt indicates whether a timer has been set to force a
// flush on this memtable at some point in the future. Protected by DB.mu.
// Holds the timestamp of when the flush will be issued.
delayedFlushForcedAt time.Time
// logNum corresponds to the WAL that contains the records present in the
// receiver.
logNum FileNum
// logSize is the size in bytes of the associated WAL. Protected by DB.mu.
logSize uint64
// The current logSeqNum at the time the memtable was created. This is
// guaranteed to be less than or equal to any seqnum stored in the memtable.
logSeqNum uint64
// readerRefs tracks the read references on the flushable. The two sources of
// reader references are DB.mu.mem.queue and readState.memtables. The memory
// reserved by the flushable in the cache is released when the reader refs
// drop to zero. If the flushable is a memTable, when the reader refs drops
// to zero, the writer refs will already be zero because the memtable will
// have been flushed and that only occurs once the writer refs drops to zero.
readerRefs int32
// Closure to invoke to release memory accounting.
releaseMemAccounting func()
alloc []byte
}
func (e *flushableEntry) readerRef() {
switch v := atomic.AddInt32(&e.readerRefs, 1); {
case v <= 1:
panic(fmt.Sprintf("bitalostable: inconsistent reference count: %d", v))
}
}
func (e *flushableEntry) readerUnref() {
switch v := atomic.AddInt32(&e.readerRefs, -1); {
case v < 0:
panic(fmt.Sprintf("bitalostable: inconsistent reference count: %d", v))
case v == 0:
if e.releaseMemAccounting == nil {
panic("bitalostable: memtable reservation already released")
}
e.releaseMemAccounting()
e.releaseMemAccounting = nil
if e.alloc != nil {
manual.Free(e.alloc)
e.alloc = nil
}
e.release()
e.flushable = nil
}
}
type flushableList []*flushableEntry