Skip to content

Commit

Permalink
Added new Closer interface to IterCh, to allow for better control ove…
Browse files Browse the repository at this point in the history
…r record-sending goroutines
  • Loading branch information
umpc committed Jul 4, 2017
1 parent 636ae3d commit d4a8b10
Show file tree
Hide file tree
Showing 18 changed files with 384 additions and 217 deletions.
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ func main() {

// Select values >= lowerBound and values <= upperBound.
// Loop through the values, in reverse order:
if ch, ok := sm.BoundedIterCh(reversed, lowerBound, upperBound); ok {
for rec := range ch {
fmt.Printf("%+v\n", rec)
}
} else {
fmt.Println("No values found that were equal to or within the given bounds.")
iterCh, err := sm.BoundedIterCh(reversed, lowerBound, upperBound)
if err != nil {
fmt.Println(err)
}
defer iterCh.Close()

for rec := range iterCh.Records() {
fmt.Printf("%+v\n", rec)
}
}
```
Expand Down
File renamed without changes.
13 changes: 8 additions & 5 deletions delete.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package sortedmap

import "sort"
import (
"errors"
"sort"
)

func (sm *SortedMap) delete(key interface{}) bool {
if val, ok := sm.idx[key]; ok {
Expand All @@ -27,16 +30,16 @@ func (sm *SortedMap) delete(key interface{}) bool {
return false
}

func (sm *SortedMap) boundedDelete(lowerBound, upperBound interface{}) bool {
func (sm *SortedMap) boundedDelete(lowerBound, upperBound interface{}) error {
iterBounds := sm.boundsIdxSearch(lowerBound, upperBound)
if iterBounds == nil {
return false
return errors.New(noValuesErr)
}
for i := iterBounds[0]; i <= iterBounds[1]-i; i++ {
delete(sm.idx, sm.sorted[i])
sm.sorted = deleteInterface(sm.sorted, i)
}
return true
return nil
}

// Delete removes a value from the collection, using the given key.
Expand All @@ -56,6 +59,6 @@ func (sm *SortedMap) BatchDelete(keys []interface{}) []bool {

// BoundedDelete removes values that are between the given values from the collection.
// BoundedDelete returns true if the operation was successful, or false otherwise.
func (sm *SortedMap) BoundedDelete(lowerBound, upperBound interface{}) bool {
func (sm *SortedMap) BoundedDelete(lowerBound, upperBound interface{}) error {
return sm.boundedDelete(lowerBound, upperBound)
}
81 changes: 59 additions & 22 deletions delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,22 @@ func TestDelete(t *testing.T) {
if err != nil {
t.Fatal(err)
}

if sm.Delete("") {
t.Fatalf("Delete: %v", invalidDelete)
}

for _, rec := range records {
sm.Delete(rec.Key)
}
if err := verifyRecords(sm.IterCh(), false); err != nil {

iterCh := sm.IterCh()
if err != nil {
t.Fatal(err)
}
defer iterCh.Close()

if err := verifyRecords(iterCh.Records(), false); err != nil {
t.Fatal(err)
}
}
Expand All @@ -40,7 +49,11 @@ func TestBatchDelete(t *testing.T) {
t.Fatalf("BatchDelete: %v", invalidDelete)
}
}
if err := verifyRecords(sm.IterCh(), false); err != nil {

iterCh := sm.IterCh()
defer iterCh.Close()

if err := verifyRecords(iterCh.Records(), false); err != nil {
t.Fatal(err)
}
}
Expand All @@ -58,39 +71,63 @@ func TestBoundedDelete(t *testing.T) {

earlierDate := time.Date(200, 1, 1, 0, 0, 0, 0, time.UTC)

if !sm.BoundedDelete(nil, nil) {
t.Fatalf("TestBoundedDelete failed: %v", generalBoundsErr)
if err := sm.BoundedDelete(nil, nil); err != nil {
t.Fatal(err)
}

if !sm.BoundedDelete(nil, time.Now()) {
t.Fatalf("TestBoundedDelete failed: %v", generalBoundsErr)
if err := sm.BoundedDelete(nil, time.Now()); err != nil {
t.Fatal(err)
}

if !sm.BoundedDelete(time.Now(), nil) {
t.Fatalf("TestBoundedDelete failed: %v", generalBoundsErr)
}
if err := verifyRecords(sm.IterCh(), false); err != nil {
if err := sm.BoundedDelete(time.Now(), nil); err != nil {
t.Fatal(err)
}

if !sm.BoundedDelete(earlierDate, time.Now()) {
t.Fatalf("TestBoundedDelete failed: %v", generalBoundsErr)
}
if err := verifyRecords(sm.IterCh(), false); err != nil {
func() {
iterCh := sm.IterCh()
defer iterCh.Close()

if err := verifyRecords(iterCh.Records(), false); err != nil {
t.Fatal(err)
}
}()

if err := sm.BoundedDelete(earlierDate, time.Now()); err != nil {
t.Fatal(err)
}

if !sm.BoundedDelete(time.Now(), earlierDate) {
t.Fatalf("TestBoundedDelete failed: %v", generalBoundsErr)
}
if err := verifyRecords(sm.IterCh(), false); err != nil {
func() {
iterCh := sm.IterCh()
defer iterCh.Close()

if err := verifyRecords(iterCh.Records(), false); err != nil {
t.Fatal(err)
}
}()

if err := sm.BoundedDelete(time.Now(), earlierDate); err != nil {
t.Fatal(err)
}

if sm.BoundedDelete(earlierDate, earlierDate) {
t.Fatalf("TestBoundedDelete failed: %v", generalBoundsErr)
}
if err := verifyRecords(sm.IterCh(), false); err != nil {
func() {
iterCh := sm.IterCh()
defer iterCh.Close()

if err := verifyRecords(iterCh.Records(), false); err != nil {
t.Fatal(err)
}
}()

if err := sm.BoundedDelete(earlierDate, earlierDate); err == nil {
t.Fatal(err)
}

func() {
iterCh := sm.IterCh()
defer iterCh.Close()

if err := verifyRecords(iterCh.Records(), false); err != nil {
t.Fatal(err)
}
}()
}
File renamed without changes.
3 changes: 3 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package sortedmap

const noValuesErr = "No values found that were equal to or within the given bounds."
35 changes: 22 additions & 13 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,6 @@ SortedMap supports three specific ways of processing iterable data:

```IterCh``` is a simple way of iterating over the entire set, in order.

Be aware that the writing goroutine cannot exit until it finishes sending all of its records. To get around this default behavior, please use ```CustomIterCh``` and set a timeout.

```go
package main

Expand All @@ -138,7 +136,10 @@ func main() {
// BatchInsert the example records:
sm.BatchInsert(records)

for rec := range sm.IterCh() {
iterCh := sm.IterCh()
defer iterCh.Close()

for rec := range iterCh.Records() {
fmt.Printf("%+v\n", rec)
}
}
Expand Down Expand Up @@ -170,10 +171,14 @@ func main() {
// BatchInsert the example records:
sm.BatchInsert(records)

if ch, ok := sm.BoundedIterCh(false, time.Time{}, time.Now()); ok {
for rec := range ch {
fmt.Printf("%+v\n", rec)
}
iterCh, err := sm.BoundedIterCh(false, time.Time{}, time.Now())
if err != nil {
fmt.Println(err)
}
defer iterCh.Close()

for rec := range iterCh.Records() {
fmt.Printf("%+v\n", rec)
}
}
```
Expand Down Expand Up @@ -211,10 +216,14 @@ func main() {
Reversed: true,
}

if ch, ok := sm.CustomIterCh(params); ok {
for rec := range ch {
fmt.Printf("%+v\n", rec)
}
iterCh, err := sm.CustomIterCh(false, time.Time{}, time.Now())
if err != nil {
fmt.Println(err)
}
defer iterCh.Close()

for rec := range iterCh.Records() {
fmt.Printf("%+v\n", rec)
}
}
```
Expand Down Expand Up @@ -385,8 +394,8 @@ func main() {
sm.BatchInsert(records)

// Delete values equal to or within the given bound values.
if !sm.BoundedDelete(time.Time{}, time.Now()) {
fmt.Println("No values fall within the specified bounds.")
if err := sm.BoundedDelete(time.Time{}, time.Now()); err != nil {
fmt.Println(err)
}
}
```
Expand Down
14 changes: 12 additions & 2 deletions get_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ func TestGet(t *testing.T) {
if err != nil {
t.Fatal(err)
}

for i := range records {
if val, ok := sm.Get(records[i].Key); val == nil || !ok {
t.Fatalf("TestGet failed: %v", notFoundErr)
}
}
if err := verifyRecords(sm.IterCh(), false); err != nil {

iterCh := sm.IterCh()
defer iterCh.Close()

if err := verifyRecords(iterCh.Records(), false); err != nil {
t.Fatal(err)
}
}
Expand All @@ -22,13 +27,18 @@ func TestBatchGet(t *testing.T) {
if err != nil {
t.Fatal(err)
}

values, results := sm.BatchGet(keys)
for i, ok := range results {
if values[i] == nil || !ok {
t.Fatalf("TestBatchGet failed: %v", notFoundErr)
}
}
if err := verifyRecords(sm.IterCh(), false); err != nil {

iterCh := sm.IterCh()
defer iterCh.Close()

if err := verifyRecords(iterCh.Records(), false); err != nil {
t.Fatal(err)
}
}
14 changes: 12 additions & 2 deletions has_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ func TestHas(t *testing.T) {
if err != nil {
t.Fatal(err)
}

for i := range records {
if !sm.Has(records[i].Key) {
t.Fatalf("TestHas failed: %v", notFoundErr)
}
}
if err := verifyRecords(sm.IterCh(), false); err != nil {

iterCh := sm.IterCh()
defer iterCh.Close()

if err := verifyRecords(iterCh.Records(), false); err != nil {
t.Fatal(err)
}
}
Expand All @@ -22,12 +27,17 @@ func TestBatchHas(t *testing.T) {
if err != nil {
t.Fatal(err)
}

for _, ok := range sm.BatchHas(keys) {
if !ok {
t.Fatalf("TestBatchHas failed: %v", notFoundErr)
}
}
if err := verifyRecords(sm.IterCh(), false); err != nil {

iterCh := sm.IterCh()
defer iterCh.Close()

if err := verifyRecords(iterCh.Records(), false); err != nil {
t.Fatal(err)
}
}
7 changes: 5 additions & 2 deletions insert.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package sortedmap

import "fmt"
import (
"errors"
"fmt"
)

func (sm *SortedMap) insert(key, val interface{}) bool {
if _, ok := sm.idx[key]; !ok {
Expand Down Expand Up @@ -59,6 +62,6 @@ func (sm *SortedMap) BatchInsertMap(v interface{}) error {
return sm.batchInsertMapStringKeys(m)

default:
return fmt.Errorf("%s", unsupportedTypeErr)
return errors.New(unsupportedTypeErr)
}
}
Loading

0 comments on commit d4a8b10

Please sign in to comment.