Browse Source

Merge pull request #317 from Shopify/partitioner-api

Make partitioner implementations private
Evan Huus 11 years ago
parent
commit
f730eab982
2 changed files with 18 additions and 46 deletions
  1. 17 30
      partitioner.go
  2. 1 16
      partitioner_test.go

+ 17 - 30
partitioner.go

@@ -22,35 +22,35 @@ type Partitioner interface {
 // PartitionerConstructor is the type for a function capable of constructing new Partitioners.
 // PartitionerConstructor is the type for a function capable of constructing new Partitioners.
 type PartitionerConstructor func() Partitioner
 type PartitionerConstructor func() Partitioner
 
 
-// RandomPartitioner implements the Partitioner interface by choosing a random partition each time.
-type RandomPartitioner struct {
+type randomPartitioner struct {
 	generator *rand.Rand
 	generator *rand.Rand
 }
 }
 
 
+// NewRandomPartitioner returns a Partitioner which chooses a random partition each time.
 func NewRandomPartitioner() Partitioner {
 func NewRandomPartitioner() Partitioner {
-	p := new(RandomPartitioner)
+	p := new(randomPartitioner)
 	p.generator = rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
 	p.generator = rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
 	return p
 	return p
 }
 }
 
 
-func (p *RandomPartitioner) Partition(key Encoder, numPartitions int32) (int32, error) {
+func (p *randomPartitioner) Partition(key Encoder, numPartitions int32) (int32, error) {
 	return int32(p.generator.Intn(int(numPartitions))), nil
 	return int32(p.generator.Intn(int(numPartitions))), nil
 }
 }
 
 
-func (p *RandomPartitioner) RequiresConsistency() bool {
+func (p *randomPartitioner) RequiresConsistency() bool {
 	return false
 	return false
 }
 }
 
 
-// RoundRobinPartitioner implements the Partitioner interface by walking through the available partitions one at a time.
-type RoundRobinPartitioner struct {
+type roundRobinPartitioner struct {
 	partition int32
 	partition int32
 }
 }
 
 
+// NewRoundRobinPartitioner returns a Partitioner which walks through the available partitions one at a time.
 func NewRoundRobinPartitioner() Partitioner {
 func NewRoundRobinPartitioner() Partitioner {
-	return &RoundRobinPartitioner{}
+	return &roundRobinPartitioner{}
 }
 }
 
 
-func (p *RoundRobinPartitioner) Partition(key Encoder, numPartitions int32) (int32, error) {
+func (p *roundRobinPartitioner) Partition(key Encoder, numPartitions int32) (int32, error) {
 	if p.partition >= numPartitions {
 	if p.partition >= numPartitions {
 		p.partition = 0
 		p.partition = 0
 	}
 	}
@@ -59,26 +59,26 @@ func (p *RoundRobinPartitioner) Partition(key Encoder, numPartitions int32) (int
 	return ret, nil
 	return ret, nil
 }
 }
 
 
-func (p *RoundRobinPartitioner) RequiresConsistency() bool {
+func (p *roundRobinPartitioner) RequiresConsistency() bool {
 	return false
 	return false
 }
 }
 
 
-// HashPartitioner implements the Partitioner interface. If the key is nil, or fails to encode, then a random partition
-// is chosen. Otherwise the FNV-1a hash of the encoded bytes is used modulus the number of partitions. This ensures that messages
-// with the same key always end up on the same partition.
-type HashPartitioner struct {
+type hashPartitioner struct {
 	random Partitioner
 	random Partitioner
 	hasher hash.Hash32
 	hasher hash.Hash32
 }
 }
 
 
+// NewHashPartitioner returns a Partitioner which behaves as follows. If the key is nil, or fails to encode, then a random partition
+// is chosen. Otherwise the FNV-1a hash of the encoded bytes is used modulus the number of partitions. This ensures that messages
+// with the same key always end up on the same partition.
 func NewHashPartitioner() Partitioner {
 func NewHashPartitioner() Partitioner {
-	p := new(HashPartitioner)
+	p := new(hashPartitioner)
 	p.random = NewRandomPartitioner()
 	p.random = NewRandomPartitioner()
 	p.hasher = fnv.New32a()
 	p.hasher = fnv.New32a()
 	return p
 	return p
 }
 }
 
 
-func (p *HashPartitioner) Partition(key Encoder, numPartitions int32) (int32, error) {
+func (p *hashPartitioner) Partition(key Encoder, numPartitions int32) (int32, error) {
 	if key == nil {
 	if key == nil {
 		return p.random.Partition(key, numPartitions)
 		return p.random.Partition(key, numPartitions)
 	}
 	}
@@ -98,19 +98,6 @@ func (p *HashPartitioner) Partition(key Encoder, numPartitions int32) (int32, er
 	return hash % numPartitions, nil
 	return hash % numPartitions, nil
 }
 }
 
 
-func (p *HashPartitioner) RequiresConsistency() bool {
-	return true
-}
-
-// ConstantPartitioner implements the Partitioner interface by just returning a constant value.
-type ConstantPartitioner struct {
-	Constant int32
-}
-
-func (p *ConstantPartitioner) Partition(key Encoder, numPartitions int32) (int32, error) {
-	return p.Constant, nil
-}
-
-func (p *ConstantPartitioner) RequiresConsistency() bool {
+func (p *hashPartitioner) RequiresConsistency() bool {
 	return true
 	return true
 }
 }

+ 1 - 16
partitioner_test.go

@@ -47,7 +47,7 @@ func TestRandomPartitioner(t *testing.T) {
 }
 }
 
 
 func TestRoundRobinPartitioner(t *testing.T) {
 func TestRoundRobinPartitioner(t *testing.T) {
-	partitioner := RoundRobinPartitioner{}
+	partitioner := NewRoundRobinPartitioner()
 
 
 	choice, err := partitioner.Partition(nil, 1)
 	choice, err := partitioner.Partition(nil, 1)
 	if err != nil {
 	if err != nil {
@@ -98,18 +98,3 @@ func TestHashPartitioner(t *testing.T) {
 		assertPartitioningConsistent(t, partitioner, ByteEncoder(buf), 50)
 		assertPartitioningConsistent(t, partitioner, ByteEncoder(buf), 50)
 	}
 	}
 }
 }
-
-func TestConstantPartitioner(t *testing.T) {
-	var partitioner Partitioner
-	partitioner = &ConstantPartitioner{Constant: 0}
-
-	for i := 1; i < 50; i++ {
-		choice, err := partitioner.Partition(nil, 50)
-		if err != nil {
-			t.Error(partitioner, err)
-		}
-		if choice != 0 {
-			t.Error("Returned partition", choice, "instead of 0.")
-		}
-	}
-}