-
Notifications
You must be signed in to change notification settings - Fork 636
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Split serialization into composition
This also moves out copyall, removes the duplicated reload function, adds a more general list func. Signed-off-by: Thomas Jungblut <[email protected]>
- Loading branch information
Showing
11 changed files
with
149 additions
and
144 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package freelist | ||
|
||
import ( | ||
"fmt" | ||
"sort" | ||
"unsafe" | ||
|
||
"go.etcd.io/bbolt/internal/common" | ||
) | ||
|
||
type SortedSerializer struct { | ||
} | ||
|
||
func (s *SortedSerializer) Read(t Interface, p *common.Page) { | ||
if !p.IsFreelistPage() { | ||
panic(fmt.Sprintf("invalid freelist page: %d, page type is %s", p.Id(), p.Typ())) | ||
} | ||
|
||
ids := p.FreelistPageIds() | ||
|
||
// Copy the list of page ids from the freelist. | ||
if len(ids) == 0 { | ||
t.Init(nil) | ||
} else { | ||
// copy the ids, so we don't modify on the freelist page directly | ||
idsCopy := make([]common.Pgid, len(ids)) | ||
copy(idsCopy, ids) | ||
// Make sure they're sorted. | ||
sort.Sort(common.Pgids(idsCopy)) | ||
|
||
t.Init(idsCopy) | ||
} | ||
} | ||
|
||
func (s *SortedSerializer) EstimatedWritePageSize(t Interface) int { | ||
n := t.Count() | ||
if n >= 0xFFFF { | ||
// The first element will be used to store the count. See freelist.write. | ||
n++ | ||
} | ||
return int(common.PageHeaderSize) + (int(unsafe.Sizeof(common.Pgid(0))) * n) | ||
} | ||
|
||
func (s *SortedSerializer) Write(t Interface, p *common.Page) { | ||
// Combine the old free pgids and pgids waiting on an open transaction. | ||
|
||
// Update the header flag. | ||
p.SetFlags(common.FreelistPageFlag) | ||
|
||
// The page.count can only hold up to 64k elements so if we overflow that | ||
// number then we handle it by putting the size in the first element. | ||
l := t.Count() | ||
if l == 0 { | ||
p.SetCount(uint16(l)) | ||
} else if l < 0xFFFF { | ||
p.SetCount(uint16(l)) | ||
data := common.UnsafeAdd(unsafe.Pointer(p), unsafe.Sizeof(*p)) | ||
ids := unsafe.Slice((*common.Pgid)(data), l) | ||
copyall(t, ids) | ||
} else { | ||
p.SetCount(0xFFFF) | ||
data := common.UnsafeAdd(unsafe.Pointer(p), unsafe.Sizeof(*p)) | ||
ids := unsafe.Slice((*common.Pgid)(data), l+1) | ||
ids[0] = common.Pgid(l) | ||
copyall(t, ids[1:]) | ||
} | ||
} | ||
|
||
// copyall copies a list of all free ids and all pending ids in one sorted list. | ||
// f.count returns the minimum length required for dst. | ||
func copyall(t Interface, dst []common.Pgid) { | ||
m := make(common.Pgids, 0, t.PendingCount()) | ||
for _, txp := range t.pendingPageIds() { | ||
m = append(m, txp.ids...) | ||
} | ||
sort.Sort(m) | ||
common.Mergepgids(dst, t.FreePageIds(), m) | ||
} | ||
|
||
func NewSortedSerializer() ReadWriter { | ||
return &SortedSerializer{} | ||
} |
Oops, something went wrong.