new histtory tests

This commit is contained in:
Radu Ioan Fericean
2014-01-24 19:15:49 +02:00
parent 5b424d0e70
commit 8177e64f8b
14 changed files with 179 additions and 236 deletions

View File

@@ -67,8 +67,8 @@ var (
stats = flag.Bool("stats", false, "Generates statsistics about given data.")
fromStorDb = flag.Bool("from_stordb", false, "Load the tariff plan from storDb to dataDb")
toStorDb = flag.Bool("to_stordb", false, "Import the tariff plan from files to storDb")
historyServer = flag.String("history_server", cgrConfig.HistoryServer, "The history server address:port, empty to disable automaticautomatic history archiving")
raterAddress = flag.String("rater_address", cgrConfig.MediatorRater, "Rater service to contact for cache reloads, empty to disable automatic cache reloads")
historyServer = flag.String("history_server", cgrConfig.RPCGOBListen, "The history server address:port, empty to disable automaticautomatic history archiving")
raterAddress = flag.String("rater_address", cgrConfig.RPCGOBListen, "Rater service to contact for cache reloads, empty to disable automatic cache reloads")
runId = flag.String("runid", "", "Uniquely identify an import/load, postpended to some automatic fields")
)
@@ -157,8 +157,8 @@ func main() {
log.Fatalf("Could not connect to history server, error: %s. Make sure you have properly configured it via -history_server flag.", err.Error())
return
} else {
gob.Register(engine.Destination{})
engine.SetHistoryScribe(scribeAgent)
gob.Register(&engine.Destination{})
defer scribeAgent.Client.Close()
}
} else {

View File

@@ -96,6 +96,9 @@ func SetDebitPeriod(d time.Duration) {
// Exported method to set the history scribe.
func SetHistoryScribe(scribe history.Scribe) {
history.RegisterRecordFilename(&Destination{})
history.RegisterRecordFilename(&RatingPlan{})
history.RegisterRecordFilename(&RatingProfile{})
historyScribe = scribe
}

View File

@@ -53,3 +53,8 @@ func (d *Destination) String() (result string) {
func (d *Destination) AddPrefix(pfx string) {
d.Prefixes = append(d.Prefixes, pfx)
}
// history record method
func (d *Destination) GetId() string {
return d.Id
}

View File

@@ -27,24 +27,26 @@ import (
func TestHistoryRatinPlans(t *testing.T) {
scribe := historyScribe.(*history.MockScribe)
if !strings.Contains(scribe.RpBuf.String(), `{"Key":"*out:vdf:0:minu","Object":{"Id":"*out:vdf:0:minu","RatingPlanActivations":[{"ActivationTime":"2012-01-01T00:00:00Z","RatingPlanId":"EVENING","FallbackKeys":null}]}}`) {
t.Error("Error in destination history content:", scribe.RpBuf.String())
buf := scribe.BufMap["ratingprofiles.json"]
if !strings.Contains(buf.String(), `{"Id":"*out:vdf:0:minu","RatingPlanActivations":[{"ActivationTime":"2012-01-01T00:00:00Z","RatingPlanId":"EVENING","FallbackKeys":null}]}`) {
t.Error("Error in destination history content:", buf.String())
}
}
func TestHistoryDestinations(t *testing.T) {
scribe := historyScribe.(*history.MockScribe)
expected := `[{"Key":"ALL","Object":{"Id":"ALL","Prefixes":["49","41","43"]}}
{"Key":"GERMANY","Object":{"Id":"GERMANY","Prefixes":["49"]}}
{"Key":"GERMANY_O2","Object":{"Id":"GERMANY_O2","Prefixes":["41"]}}
{"Key":"GERMANY_PREMIUM","Object":{"Id":"GERMANY_PREMIUM","Prefixes":["43"]}}
{"Key":"NAT","Object":{"Id":"NAT","Prefixes":["0256","0257","0723"]}}
{"Key":"PSTN_70","Object":{"Id":"PSTN_70","Prefixes":["+4970"]}}
{"Key":"PSTN_71","Object":{"Id":"PSTN_71","Prefixes":["+4971"]}}
{"Key":"PSTN_72","Object":{"Id":"PSTN_72","Prefixes":["+4972"]}}
{"Key":"RET","Object":{"Id":"RET","Prefixes":["0723","0724"]}}
{"Key":"nat","Object":{"Id":"nat","Prefixes":["0257","0256","0723"]}}]`
if scribe.DestBuf.String() != expected {
t.Error("Error in destination history content:", scribe.DestBuf.String())
buf := scribe.BufMap["destinations.json"]
expected := `[{"Id":"ALL","Prefixes":["49","41","43"]},
{"Id":"GERMANY","Prefixes":["49"]},
{"Id":"GERMANY_O2","Prefixes":["41"]},
{"Id":"GERMANY_PREMIUM","Prefixes":["43"]},
{"Id":"NAT","Prefixes":["0256","0257","0723"]},
{"Id":"PSTN_70","Prefixes":["+4970"]},
{"Id":"PSTN_71","Prefixes":["+4971"]},
{"Id":"PSTN_72","Prefixes":["+4972"]},
{"Id":"RET","Prefixes":["0723","0724"]},
{"Id":"nat","Prefixes":["0257","0256","0723"]}]`
if buf.String() != expected {
t.Error("Error in destination history content:", buf.String())
}
}

View File

@@ -97,3 +97,8 @@ func (rp *RatingPlan) AddRateInterval(dId string, ris ...*RateInterval) {
func (rp *RatingPlan) Equal(o *RatingPlan) bool {
return rp.Id == o.Id
}
// history record method
func (rp *RatingPlan) GetId() string {
return rp.Id
}

View File

@@ -146,3 +146,8 @@ func (rp *RatingProfile) GetRatingPlansForPrefix(cd *CallDescriptor) (err error)
return errors.New("not found")
}
// history record method
func (rpf *RatingProfile) GetId() string {
return rpf.Id
}

View File

@@ -22,11 +22,10 @@ import (
"errors"
"fmt"
"github.com/cgrates/cgrates/cache2go"
"github.com/cgrates/cgrates/history"
"github.com/cgrates/cgrates/utils"
"strings"
"time"
"github.com/cgrates/cgrates/cache2go"
"github.com/cgrates/cgrates/utils"
)
type MapStorage struct {
@@ -123,7 +122,7 @@ func (ms *MapStorage) SetRatingPlan(rp *RatingPlan) (err error) {
result, err := ms.ms.Marshal(rp)
ms.dict[RATING_PLAN_PREFIX+rp.Id] = result
response := 0
go historyScribe.Record(&history.Record{RATING_PLAN_PREFIX + rp.Id, rp}, &response)
go historyScribe.Record(rp, &response)
cache2go.Cache(RATING_PLAN_PREFIX+rp.Id, rp)
return
}
@@ -151,7 +150,7 @@ func (ms *MapStorage) SetRatingProfile(rpf *RatingProfile) (err error) {
result, err := ms.ms.Marshal(rpf)
ms.dict[RATING_PROFILE_PREFIX+rpf.Id] = result
response := 0
go historyScribe.Record(&history.Record{RATING_PROFILE_PREFIX + rpf.Id, rpf}, &response)
go historyScribe.Record(rpf, &response)
cache2go.Cache(RATING_PROFILE_PREFIX+rpf.Id, rpf)
return
}
@@ -180,7 +179,7 @@ func (ms *MapStorage) SetDestination(dest *Destination) (err error) {
result, err := ms.ms.Marshal(dest)
ms.dict[DESTINATION_PREFIX+dest.Id] = result
response := 0
go historyScribe.Record(&history.Record{DESTINATION_PREFIX + dest.Id, dest}, &response)
go historyScribe.Record(dest, &response)
cache2go.Cache(DESTINATION_PREFIX+dest.Id, dest)
return
}

View File

@@ -20,11 +20,10 @@ package engine
import (
"fmt"
"github.com/cgrates/cgrates/history"
"labix.org/v2/mgo"
"labix.org/v2/mgo/bson"
"log"
"time"
"labix.org/v2/mgo"
"labix.org/v2/mgo/bson"
)
type MongoStorage struct {
@@ -137,7 +136,7 @@ func (ms *MongoStorage) GetRatingPlan(key string) (rp *RatingPlan, err error) {
func (ms *MongoStorage) SetRatingPlan(rp *RatingPlan) error {
if historyScribe != nil {
response := 0
historyScribe.Record(&history.Record{RATING_PLAN_PREFIX + rp.Id, rp}, &response)
historyScribe.Record(rp, &response)
}
return ms.db.C("ratingplans").Insert(rp)
}
@@ -151,7 +150,7 @@ func (ms *MongoStorage) GetRatingProfile(key string) (rp *RatingProfile, err err
func (ms *MongoStorage) SetRatingProfile(rp *RatingProfile) error {
if historyScribe != nil {
response := 0
historyScribe.Record(&history.Record{RATING_PROFILE_PREFIX + rp.Id, rp}, &response)
historyScribe.Record(rp, &response)
}
return ms.db.C("ratingprofiles").Insert(rp)
}
@@ -168,7 +167,7 @@ func (ms *MongoStorage) GetDestination(key string) (result *Destination, err err
func (ms *MongoStorage) SetDestination(dest *Destination) error {
if historyScribe != nil {
response := 0
historyScribe.Record(&history.Record{DESTINATION_PREFIX + dest.Id, dest}, &response)
historyScribe.Record(dest, &response)
}
return ms.db.C("destinations").Insert(dest)
}

View File

@@ -25,7 +25,6 @@ import (
"fmt"
"github.com/cgrates/cgrates/cache2go"
"github.com/cgrates/cgrates/history"
"github.com/cgrates/cgrates/utils"
"github.com/hoisie/redis"
@@ -195,7 +194,7 @@ func (rs *RedisStorage) SetRatingPlan(rp *RatingPlan) (err error) {
err = rs.db.Set(RATING_PLAN_PREFIX+rp.Id, b.Bytes())
if err == nil && historyScribe != nil {
response := 0
go historyScribe.Record(&history.Record{RATING_PLAN_PREFIX + rp.Id, rp}, &response)
go historyScribe.Record(rp, &response)
}
//cache2go.Cache(RATING_PLAN_PREFIX+rp.Id, rp)
return
@@ -223,7 +222,7 @@ func (rs *RedisStorage) SetRatingProfile(rpf *RatingProfile) (err error) {
err = rs.db.Set(RATING_PROFILE_PREFIX+rpf.Id, result)
if err == nil && historyScribe != nil {
response := 0
go historyScribe.Record(&history.Record{RATING_PROFILE_PREFIX + rpf.Id, rpf}, &response)
go historyScribe.Record(rpf, &response)
}
//cache2go.Cache(RATING_PROFILE_PREFIX+rpf.Id, rpf)
return
@@ -272,7 +271,7 @@ func (rs *RedisStorage) SetDestination(dest *Destination) (err error) {
err = rs.db.Set(DESTINATION_PREFIX+dest.Id, b.Bytes())
if err == nil && historyScribe != nil {
response := 0
go historyScribe.Record(&history.Record{DESTINATION_PREFIX + dest.Id, dest}, &response)
go historyScribe.Record(dest, &response)
}
//cache2go.Cache(DESTINATION_PREFIX+dest.Id, dest)
return

View File

@@ -22,31 +22,22 @@ import (
"bufio"
"encoding/json"
"errors"
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"strings"
"sync"
"time"
)
const (
DESTINATIONS_FILE = "destinations.json"
RATING_PLANS_FILE = "rating_plans.json"
RATING_PROFILES_FILE = "rating_profiles.json"
)
type FileScribe struct {
mu sync.Mutex
fileRoot string
gitCommand string
destinations records
ratingPlans records
ratingProfiles records
loopChecker chan int
waitingFile string
savePeriod time.Duration
mu sync.Mutex
fileRoot string
gitCommand string
loopChecker chan int
waitingFile string
savePeriod time.Duration
}
func NewFileScribe(fileRoot string, saveInterval time.Duration) (*FileScribe, error) {
@@ -58,31 +49,20 @@ func NewFileScribe(fileRoot string, saveInterval time.Duration) (*FileScribe, er
s := &FileScribe{fileRoot: fileRoot, gitCommand: gitCommand, savePeriod: saveInterval}
s.loopChecker = make(chan int)
s.gitInit()
if err := s.load(DESTINATIONS_FILE); err != nil {
return nil, err
}
if err := s.load(RATING_PLANS_FILE); err != nil {
return nil, err
}
if err := s.load(RATING_PROFILES_FILE); err != nil {
return nil, err
for fn, _ := range recordsMap {
if err := s.load(fn); err != nil {
return nil, err
}
}
return s, nil
}
func (s *FileScribe) Record(rec *Record, out *int) error {
func (s *FileScribe) Record(rec Record, out *int) error {
s.mu.Lock()
var fileToSave string
switch {
case strings.HasPrefix(rec.Key, DESTINATION_PREFIX):
s.destinations = s.destinations.SetOrAdd(&Record{rec.Key[len(DESTINATION_PREFIX):], rec.Object})
fileToSave = DESTINATIONS_FILE
case strings.HasPrefix(rec.Key, RATING_PLAN_PREFIX):
s.ratingPlans = s.ratingPlans.SetOrAdd(&Record{rec.Key[len(RATING_PLAN_PREFIX):], rec.Object})
fileToSave = RATING_PLANS_FILE
case strings.HasPrefix(rec.Key, RATING_PROFILE_PREFIX):
s.ratingProfiles = s.ratingProfiles.SetOrAdd(&Record{rec.Key[len(RATING_PROFILE_PREFIX):], rec.Object})
fileToSave = RATING_PROFILES_FILE
fileToSave := GetRFN(rec)
if records, ok := recordsMap[fileToSave]; ok {
records.SetOrAdd(rec)
}
// flood protection for save method (do not save on every loop iteration)
@@ -126,21 +106,14 @@ func (s *FileScribe) gitInit() error {
if out, err := cmd.Output(); err != nil {
return errors.New(string(out) + " " + err.Error())
}
if f, err := os.Create(filepath.Join(s.fileRoot, DESTINATIONS_FILE)); err != nil {
return errors.New("<History> Error writing destinations file: " + err.Error())
} else {
f.Close()
}
if f, err := os.Create(filepath.Join(s.fileRoot, RATING_PLANS_FILE)); err != nil {
return errors.New("<History> Error writing rating plans file: " + err.Error())
} else {
f.Close()
}
if f, err := os.Create(filepath.Join(s.fileRoot, RATING_PROFILES_FILE)); err != nil {
return errors.New("<History> Error writing rating profiles file: " + err.Error())
} else {
f.Close()
for fn, _ := range recordsMap {
if f, err := os.Create(filepath.Join(s.fileRoot, fn)); err != nil {
return fmt.Errorf("<History> Error writing %s file: %s", fn, err.Error())
} else {
f.Close()
}
}
cmd = exec.Command(s.gitCommand, "add", ".")
cmd.Dir = s.fileRoot
if out, err := cmd.Output(); err != nil {
@@ -169,23 +142,11 @@ func (s *FileScribe) load(filename string) error {
defer f.Close()
d := json.NewDecoder(f)
switch filename {
case DESTINATIONS_FILE:
if err := d.Decode(&s.destinations); err != nil && err != io.EOF {
return errors.New("<History> Error loading destinations: " + err.Error())
}
s.destinations.Sort()
case RATING_PLANS_FILE:
if err := d.Decode(&s.ratingPlans); err != nil && err != io.EOF {
return errors.New("<History> Error loading rating plans: " + err.Error())
}
s.ratingPlans.Sort()
case RATING_PROFILES_FILE:
if err := d.Decode(&s.ratingProfiles); err != nil && err != io.EOF {
return errors.New("<History> Error loading rating profiles: " + err.Error())
}
s.ratingProfiles.Sort()
records := recordsMap[filename]
if err := d.Decode(&records); err != nil && err != io.EOF {
return fmt.Errorf("<History> Error loading %s: %s", filename, err.Error())
}
records.Sort()
return nil
}
@@ -198,38 +159,11 @@ func (s *FileScribe) save(filename string) error {
}
b := bufio.NewWriter(f)
switch filename {
case DESTINATIONS_FILE:
if err := s.format(b, s.destinations); err != nil {
return err
}
case RATING_PLANS_FILE:
if err := s.format(b, s.ratingPlans); err != nil {
return err
}
case RATING_PROFILES_FILE:
if err := s.format(b, s.ratingProfiles); err != nil {
return err
}
records := recordsMap[filename]
if err := format(b, records); err != nil {
return err
}
b.Flush()
f.Close()
return s.gitCommit()
}
func (s *FileScribe) format(b io.Writer, recs records) error {
recs.Sort()
b.Write([]byte("["))
for i, r := range recs {
src, err := json.Marshal(r)
if err != nil {
return err
}
b.Write(src)
if i < len(recs)-1 {
b.Write([]byte(",\n"))
}
}
b.Write([]byte("]"))
return nil
}

View File

@@ -21,85 +21,38 @@ package history
import (
"bufio"
"bytes"
"encoding/json"
"io"
"strings"
"sync"
)
type MockScribe struct {
mu sync.Mutex
destinations records
ratingPlans records
ratingProfiles records
DestBuf bytes.Buffer
RplBuf bytes.Buffer
RpBuf bytes.Buffer
mu sync.Mutex
BufMap map[string]*bytes.Buffer
}
func NewMockScribe() (*MockScribe, error) {
return &MockScribe{}, nil
return &MockScribe{BufMap: map[string]*bytes.Buffer{
"destinations.json": bytes.NewBuffer(nil),
"ratingplans.json": bytes.NewBuffer(nil),
"ratingprofiles.json": bytes.NewBuffer(nil),
}}, nil
}
func (s *MockScribe) Record(rec *Record, out *int) error {
switch {
case strings.HasPrefix(rec.Key, DESTINATION_PREFIX):
s.destinations = s.destinations.SetOrAdd(&Record{rec.Key[len(DESTINATION_PREFIX):], rec.Object})
s.save(DESTINATIONS_FILE)
case strings.HasPrefix(rec.Key, RATING_PLAN_PREFIX):
s.ratingPlans = s.ratingPlans.SetOrAdd(&Record{rec.Key[len(RATING_PLAN_PREFIX):], rec.Object})
s.save(RATING_PLANS_FILE)
case strings.HasPrefix(rec.Key, RATING_PROFILE_PREFIX):
s.ratingProfiles = s.ratingProfiles.SetOrAdd(&Record{rec.Key[len(RATING_PROFILE_PREFIX):], rec.Object})
s.save(RATING_PROFILES_FILE)
}
*out = 0
func (s *MockScribe) Record(rec Record, out *int) error {
fn := GetRFN(rec)
recordsMap[fn] = recordsMap[fn].SetOrAdd(rec)
s.save(fn)
return nil
}
func (s *MockScribe) save(filename string) error {
s.mu.Lock()
defer s.mu.Unlock()
switch filename {
case DESTINATIONS_FILE:
s.DestBuf.Reset()
b := bufio.NewWriter(&s.DestBuf)
defer b.Flush()
if err := s.format(b, s.destinations); err != nil {
return err
}
case RATING_PLANS_FILE:
s.RplBuf.Reset()
b := bufio.NewWriter(&s.RplBuf)
defer b.Flush()
if err := s.format(b, s.ratingPlans); err != nil {
return err
}
case RATING_PROFILES_FILE:
s.RpBuf.Reset()
b := bufio.NewWriter(&s.RpBuf)
defer b.Flush()
if err := s.format(b, s.ratingProfiles); err != nil {
return err
}
records := recordsMap[filename]
s.BufMap[filename].Reset()
b := bufio.NewWriter(s.BufMap[filename])
defer b.Flush()
if err := format(b, records); err != nil {
return err
}
return nil
}
func (s *MockScribe) format(b io.Writer, recs records) error {
recs.Sort()
b.Write([]byte("["))
for i, r := range recs {
src, err := json.Marshal(r)
if err != nil {
return err
}
b.Write(src)
if i < len(recs)-1 {
b.Write([]byte("\n"))
}
}
b.Write([]byte("]"))
return nil
}

View File

@@ -18,11 +18,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package history
import "net/rpc"
const (
JSON = "json"
GOB = "gob"
import (
"encoding/gob"
"log"
"net/rpc"
)
type ProxyScribe struct {
@@ -38,6 +37,12 @@ func NewProxyScribe(addr string) (*ProxyScribe, error) {
return &ProxyScribe{Client: client}, nil
}
func (ps *ProxyScribe) Record(rec *Record, out *int) error {
return ps.Client.Call("Scribe.Record", rec, out)
func RRR(r interface{}) {
gob.Register(r)
}
func (ps *ProxyScribe) Record(rec Record, out *int) error {
err := ps.Client.Call("Scribe.Record", &rec, out)
log.Printf("Result for %v: %v", rec, err)
return err
}

View File

@@ -19,25 +19,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package history
import (
"encoding/json"
"io"
"reflect"
"sort"
)
const (
RATING_PLAN_PREFIX = "rpl_"
RATING_PROFILE_PREFIX = "rpf_"
DESTINATION_PREFIX = "dst_"
"strings"
)
type Scribe interface {
Record(record *Record, out *int) error
Record(Record, *int) error
}
type Record struct {
Key string
Object interface{}
type Record interface {
GetId() string
}
type records []*Record
type records []Record
var (
recordsMap = make(map[string]records)
filenameMap = make(map[reflect.Type]string)
)
func (rs records) Len() int {
return len(rs)
@@ -48,19 +50,19 @@ func (rs records) Swap(i, j int) {
}
func (rs records) Less(i, j int) bool {
return rs[i].Key < rs[j].Key
return rs[i].GetId() < rs[j].GetId()
}
func (rs records) Sort() {
sort.Sort(rs)
}
func (rs records) SetOrAdd(rec *Record) records {
func (rs records) SetOrAdd(rec Record) records {
//rs.Sort()
n := len(rs)
i := sort.Search(n, func(i int) bool { return rs[i].Key >= rec.Key })
if i < n && rs[i].Key == rec.Key {
rs[i].Object = rec.Object
i := sort.Search(n, func(i int) bool { return rs[i].GetId() >= rec.GetId() })
if i < n && rs[i].GetId() == rec.GetId() {
rs[i] = rec
} else {
// i is the index where it would be inserted.
rs = append(rs, nil)
@@ -70,10 +72,10 @@ func (rs records) SetOrAdd(rec *Record) records {
return rs
}
func (rs records) SetOrAddOld(rec *Record) records {
/*func (rs records) SetOrAdd(rec Record) records {
found := false
for _, r := range rs {
if r.Key == rec.Key {
if r.GetId() == rec.GetId() {
found = true
r.Object = rec.Object
return rs
@@ -83,4 +85,36 @@ func (rs records) SetOrAddOld(rec *Record) records {
rs = append(rs, rec)
}
return rs
}*/
func format(b io.Writer, recs records) error {
recs.Sort()
b.Write([]byte("["))
for i, r := range recs {
src, err := json.Marshal(r)
if err != nil {
return err
}
b.Write(src)
if i < len(recs)-1 {
b.Write([]byte(",\n"))
}
}
b.Write([]byte("]"))
return nil
}
func GetRFN(rec Record) string {
if fn, ok := filenameMap[reflect.TypeOf(rec)]; ok {
return fn
} else {
typ := reflect.TypeOf(rec)
typeSegments := strings.Split(typ.String(), ".")
fn = strings.ToLower(typeSegments[len(typeSegments)-1]) + "s.json"
filenameMap[typ] = fn
recordsMap[fn] = make(records, 0)
return fn
}
}
var RegisterRecordFilename = GetRFN // will create a key in filename and records map

View File

@@ -23,18 +23,28 @@ import (
"testing"
)
type TestRecord struct {
Id string
}
func (tr *TestRecord) GetId() string {
return tr.Id
}
func TestHistorySet(t *testing.T) {
rs := records{&Record{"first", "test"}}
rs.SetOrAdd(&Record{"first", "new value"})
if len(rs) != 1 || rs[0].Object != "new value" {
rs := records{&TestRecord{"first"}}
second := &TestRecord{"first"}
rs.SetOrAdd(second)
if len(rs) != 1 || rs[0] != second {
t.Error("error setting new value: ", rs[0])
}
}
func TestHistoryAdd(t *testing.T) {
rs := records{&Record{"first", "test"}}
rs = rs.SetOrAdd(&Record{"second", "new value"})
if len(rs) != 2 || rs[1].Object != "new value" {
rs := records{&TestRecord{"first"}}
second := &TestRecord{"second"}
rs = rs.SetOrAdd(second)
if len(rs) != 2 || rs[1] != second {
t.Error("error setting new value: ", rs)
}
}
@@ -42,19 +52,9 @@ func TestHistoryAdd(t *testing.T) {
func BenchmarkSetOrAdd(b *testing.B) {
var rs records
for i := 0; i < 1000; i++ {
rs = rs.SetOrAdd(&Record{strconv.Itoa(i), strconv.Itoa(i)})
rs = rs.SetOrAdd(&TestRecord{strconv.Itoa(i)})
}
for i := 0; i < b.N; i++ {
rs.SetOrAdd(&Record{"400", "test"})
}
}
func BenchmarkSetOrAddOld(b *testing.B) {
var rs records
for i := 0; i < 1000; i++ {
rs = rs.SetOrAddOld(&Record{strconv.Itoa(i), strconv.Itoa(i)})
}
for i := 0; i < b.N; i++ {
rs.SetOrAddOld(&Record{"400", "test"})
rs.SetOrAdd(&TestRecord{"400"})
}
}