diff --git a/index/upside_down/row_merge.go b/index/upside_down/row_merge.go index fb9d987a..bb0e5e39 100644 --- a/index/upside_down/row_merge.go +++ b/index/upside_down/row_merge.go @@ -61,8 +61,9 @@ func (m *upsideDownMerge) FullMerge(key, existingValue []byte, operands [][]byte func (m *upsideDownMerge) PartialMerge(key, leftOperand, rightOperand []byte) ([]byte, bool) { left := int64(binary.LittleEndian.Uint64(leftOperand)) right := int64(binary.LittleEndian.Uint64(rightOperand)) - binary.LittleEndian.PutUint64(leftOperand, uint64(left+right)) - return leftOperand, true + rv := make([]byte, 8) + binary.LittleEndian.PutUint64(rv, uint64(left+right)) + return rv, true } func (m *upsideDownMerge) Name() string { diff --git a/index/upside_down/row_merge_test.go b/index/upside_down/row_merge_test.go new file mode 100644 index 00000000..eee3f071 --- /dev/null +++ b/index/upside_down/row_merge_test.go @@ -0,0 +1,52 @@ +// Copyright (c) 2014 Couchbase, Inc. +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software distributed under the +// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. + +package upside_down + +import ( + "bytes" + "encoding/binary" + "testing" +) + +func TestPartialMerge(t *testing.T) { + + tests := []struct { + in [][]byte + out uint64 + }{ + { + in: [][]byte{dictionaryTermIncr, dictionaryTermIncr, dictionaryTermIncr, dictionaryTermIncr, dictionaryTermIncr}, + out: 5, + }, + } + + mo := &upsideDownMerge{} + for _, test := range tests { + curr := test.in[0] + for _, next := range test.in[1:] { + var ok bool + curr, ok = mo.PartialMerge([]byte("key"), curr, next) + if !ok { + t.Errorf("expected partial merge ok") + } + } + actual := decodeCount(curr) + if actual != test.out { + t.Errorf("expected %d, got %d", test.out, actual) + } + } + +} + +func decodeCount(in []byte) uint64 { + buf := bytes.NewBuffer(in) + count, _ := binary.ReadUvarint(buf) + return count +}