diff --git a/field.go b/field.go index 9b49d03b6..c803ea36c 100644 --- a/field.go +++ b/field.go @@ -143,6 +143,7 @@ func OptFieldTypeInt(min, max int64) FieldOption { fo.Type = FieldTypeInt fo.Min = min fo.Max = max + fo.Base = bsiBase(min, max) return nil } } @@ -499,7 +500,7 @@ func (f *Field) loadMeta() error { // Initialize "base" to "min" when upgrading from v1 BSI format. if pb.BitDepth == 0 { - pb.Base = pb.Min + pb.Base = bsiBase(pb.Min, pb.Max) pb.BitDepth = uint64(bitDepthInt64(pb.Max - pb.Min)) if pb.BitDepth == 0 { pb.BitDepth = 1 @@ -1501,6 +1502,18 @@ func isValidBSIGroupType(v string) bool { } } +// bsiBase is a helper function used to determine the default value +// for base. Because base is not exposed as a field option argument, +// it defaults to min, max, or 0 depending on the min/max range. +func bsiBase(min, max int64) int64 { + if min > 0 { + return min + } else if max < 0 { + return max + } + return 0 +} + // bsiGroup represents a group of range-encoded rows on a field. type bsiGroup struct { Name string `json:"name,omitempty"` diff --git a/field_internal_test.go b/field_internal_test.go index 13851a493..1ce7c8237 100644 --- a/field_internal_test.go +++ b/field_internal_test.go @@ -412,3 +412,29 @@ func TestField_PersistAvailableShardsFootprint(t *testing.T) { } } + +// Ensure that FieldOptions.Base defaults to the correct value. +func TestBSIGroup_BaseDefaultValue(t *testing.T) { + for i, tt := range []struct { + min int64 + max int64 + expBase int64 + }{ + {100, 200, 100}, + {-100, 100, 0}, + {-200, -100, -100}, + } { + fn := OptFieldTypeInt(tt.min, tt.max) + + // Apply functional option. + fo := FieldOptions{} + err := fn(&fo) + if err != nil { + t.Fatalf("test %d, applying functional option: %s", i, err.Error()) + } + + if fo.Base != tt.expBase { + t.Fatalf("test %d, unexpected FieldOptions.Base value. expected: %d, but got: %d", i, tt.expBase, fo.Base) + } + } +}