Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(752)

Side by Side Diff: go/src/infra/libs/bit_field/bf.go

Issue 1153883002: go: infra/libs/* now live in luci-go. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: move the rest too Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « go/src/infra/libs/auth/service_test.go ('k') | go/src/infra/libs/bit_field/bf_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package bf
6
7 import (
8 "fmt"
9 )
10
11 // BitField is a AppEngine-serializable bit field implementation. It should
12 // be nice and fast for non-AppEngine use as well.
13 //
14 // You should construct a new one with bf.Make, rather than by direct
15 // construction. The field names are public due to an appengine artifact.
16 type BitField struct {
17 // fields are public so that datastore can see them... but don't touch t hem if
18 // you know what's good for you.
19
20 // Data is the actual bits data. rightmost bit of 0th number is the firs t bit.
21 Data []int64 `datastore:",noindex"`
22
23 // NumBits is the number of bits held in this BitField. It's stored as a
24 // casted uint64 since datastore can't store unsigned things, apparently .
25 NumBits int64 `datastore:",noindex"`
26 }
27
28 // Make creates a new properly-initialized BitField.
29 func Make(size uint64) BitField {
30 return BitField{
31 Data: make([]int64, (size+64-1)>>6),
32 NumBits: int64(size),
33 }
34 }
35
36 // Size returns the number of bits which this BitField can hold.
37 func (bf BitField) Size() uint64 {
38 return uint64(bf.NumBits)
39 }
40
41 // Set turns the given bit to true, regardless of its previous value. Error
42 // returned is for bounds checking.
43 func (bf BitField) Set(idx uint64) error {
44 if idx >= bf.Size() {
45 return fmt.Errorf("Cannot set bit %d in BitField of size %d", id x, bf.Size())
46 }
47 bf.Data[idx>>6] |= 1 << (idx % 64)
48 return nil
49 }
50
51 // Clear turns the given bit to false, regardless of its previous value. Error
52 // returned is for bounds checking.
53 func (bf BitField) Clear(idx uint64) error {
54 if idx >= bf.Size() {
55 return fmt.Errorf("Cannot clear bit %d in BitField of size %d", idx, bf.Size())
56 }
57 bf.Data[idx>>6] &^= 1 << (idx % 64)
58 return nil
59 }
60
61 // All returns true iff all of the bits are equal to `val`.
62 func (bf BitField) All(val bool) bool {
63 targ := bf.Size()
64 if !val {
65 targ = 0
66 }
67 return bf.CountSet() == targ
68 }
69
70 func countBitsSet(v uint64) uint8 {
71 // https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetPara llel
72 const (
73 maxUint64 = ^(uint64(0))
74 eightyfives = maxUint64 / 3 // 0x555555...
75 fiftyones = maxUint64 / 15 * 3 // 0x333333...
76 fifteens = maxUint64 / 255 * 15 // 0x0f0f0f...
77 ones = maxUint64 / 255 // 0x010101...
78 offset = (64/8 - 1) * 8 // 56
79 )
80
81 v -= v >> 1 & eightyfives
82 v = v&fiftyones + v>>2&fiftyones
83 v = (v + v>>4) & fifteens
84 return uint8(v * ones >> offset)
85 }
86
87 // CountSet returns the number of true bits.
88 func (bf BitField) CountSet() uint64 {
89 ret := uint64(0)
90 for _, word := range bf.Data {
91 if word != 0 {
92 ret += uint64(countBitsSet(uint64(word)))
93 }
94 }
95 return ret
96 }
97
98 // IsSet returns the value of a given bit.
99 func (bf BitField) IsSet(idx uint64) bool {
100 return idx < bf.Size() && ((bf.Data[idx>>6] & (1 << (idx % 64))) != 0)
101 }
OLDNEW
« no previous file with comments | « go/src/infra/libs/auth/service_test.go ('k') | go/src/infra/libs/bit_field/bf_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698