aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/corpus/fenwik.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/corpus/fenwik.go')
-rw-r--r--pkg/corpus/fenwik.go61
1 files changed, 61 insertions, 0 deletions
diff --git a/pkg/corpus/fenwik.go b/pkg/corpus/fenwik.go
new file mode 100644
index 000000000..3a49219ac
--- /dev/null
+++ b/pkg/corpus/fenwik.go
@@ -0,0 +1,61 @@
+package corpus
+
+type fenwikTree struct {
+ array []int64
+ data []int64
+ fullSum int64
+
+ size int
+ capacity int
+}
+
+func (t *fenwikTree) addNew(val int64) {
+ if t.size+1 >= t.capacity {
+ t.extendAndRebuild()
+ }
+
+ t.size++
+ t.add(t.size, val)
+}
+
+func (t *fenwikTree) add(ind int, val int64) {
+ t.fullSum += val
+ t.array[ind] += val
+ for ind < t.capacity {
+ t.data[ind] += val
+ ind += ind & -ind
+ }
+}
+
+func (t *fenwikTree) get(ind int) int64 {
+ return t.array[ind]
+}
+
+func (t *fenwikTree) set(ind int, val int64) {
+ t.add(ind, val-t.get(ind))
+}
+
+func (t *fenwikTree) prefixSumTo(ind int) (sum int64) {
+ for ind > 0 {
+ sum += t.data[ind]
+ ind -= ind & -ind
+ }
+ return
+}
+
+func (t *fenwikTree) extendAndRebuild() {
+ if t.capacity == 0 {
+ t.capacity = 16
+ } else {
+ t.capacity *= 2
+ }
+
+ oldArray := t.array
+ t.array = make([]int64, t.capacity)
+ t.data = make([]int64, t.capacity)
+ t.fullSum = 0
+
+ for i := 1; i < len(oldArray); i++ {
+ t.add(i, oldArray[i])
+ }
+}