mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
revrted to my own serialization/deserialization
This commit is contained in:
@@ -20,6 +20,8 @@ package timespans
|
||||
import (
|
||||
"time"
|
||||
//"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -40,3 +42,57 @@ func (ap *ActivationPeriod) AddInterval(is ...*Interval) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Serializes the activation periods for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (ap *ActivationPeriod) store() (result string) {
|
||||
result += strconv.FormatInt(ap.ActivationTime.UnixNano(), 10) + ";"
|
||||
for _, i := range ap.Intervals {
|
||||
var is string
|
||||
is = strconv.Itoa(int(i.Month)) + "|"
|
||||
is += strconv.Itoa(i.MonthDay) + "|"
|
||||
for _, wd := range i.WeekDays {
|
||||
is += strconv.Itoa(int(wd)) + ","
|
||||
}
|
||||
is = strings.TrimRight(is, ",") + "|"
|
||||
is += i.StartTime + "|"
|
||||
is += i.EndTime + "|"
|
||||
is += strconv.FormatFloat(i.Ponder, 'f', -1, 64) + "|"
|
||||
is += strconv.FormatFloat(i.ConnectFee, 'f', -1, 64) + "|"
|
||||
is += strconv.FormatFloat(i.Price, 'f', -1, 64) + "|"
|
||||
is += strconv.FormatFloat(i.BillingUnit, 'f', -1, 64)
|
||||
result += is + ";"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
De-serializes the activation periods for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (ap *ActivationPeriod) restore(input string) {
|
||||
elements := strings.Split(input, ";")
|
||||
unixNano, _ := strconv.ParseInt(elements[0], 10, 64)
|
||||
ap.ActivationTime = time.Unix(0, unixNano).In(time.UTC)
|
||||
ap.Intervals = make([]*Interval, 0)
|
||||
for _, is := range elements[1 : len(elements)-1] {
|
||||
i := &Interval{}
|
||||
ise := strings.Split(is, "|")
|
||||
month, _ := strconv.Atoi(ise[0])
|
||||
i.Month = time.Month(month)
|
||||
i.MonthDay, _ = strconv.Atoi(ise[1])
|
||||
for _, d := range strings.Split(ise[2], ",") {
|
||||
if d != "" {
|
||||
wd, _ := strconv.Atoi(d)
|
||||
i.WeekDays = append(i.WeekDays, time.Weekday(wd))
|
||||
}
|
||||
}
|
||||
i.StartTime = ise[3]
|
||||
i.EndTime = ise[4]
|
||||
i.Ponder, _ = strconv.ParseFloat(ise[5], 64)
|
||||
i.ConnectFee, _ = strconv.ParseFloat(ise[6], 64)
|
||||
i.Price, _ = strconv.ParseFloat(ise[7], 64)
|
||||
i.BillingUnit, _ = strconv.ParseFloat(ise[8], 64)
|
||||
|
||||
ap.Intervals = append(ap.Intervals, i)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,8 +47,6 @@ func TestApRestoreRedis(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestApStoreRestore(t *testing.T) {
|
||||
getter, _ := NewKyotoStorage("test.kch")
|
||||
defer getter.Close()
|
||||
d := time.Date(2012, time.February, 1, 14, 30, 1, 0, time.UTC)
|
||||
i := &Interval{Month: time.February,
|
||||
MonthDay: 1,
|
||||
@@ -57,22 +55,29 @@ func TestApStoreRestore(t *testing.T) {
|
||||
EndTime: "15:00:00"}
|
||||
ap := &ActivationPeriod{ActivationTime: d}
|
||||
ap.AddInterval(i)
|
||||
|
||||
getter.SetActivationPeriods("storerestore", []*ActivationPeriod{ap})
|
||||
aps, err := getter.GetActivationPeriods("storerestore")
|
||||
if err != nil || len(aps) != 1 || !reflect.DeepEqual(ap, aps[0]) {
|
||||
t.Log(aps)
|
||||
t.Errorf("Expected %v was %v ", ap, aps)
|
||||
result := ap.store()
|
||||
expected := "1328106601000000000;2|1|3,4|14:30:00|15:00:00|0|0|0|0;"
|
||||
if result != expected {
|
||||
t.Errorf("Expected %q was %q", expected, result)
|
||||
}
|
||||
ap1 := ActivationPeriod{}
|
||||
ap1.restore(result)
|
||||
if reflect.DeepEqual(ap, ap1) {
|
||||
t.Errorf("Expected %v was %v", ap, ap1)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**************************** Benchmarks *************************************/
|
||||
|
||||
func BenchmarkActivationPeriodRestore(b *testing.B) {
|
||||
ap := ActivationPeriod{}
|
||||
for i := 0; i < b.N; i++ {
|
||||
ap.restore("1328106601;2|1|3,4|14:30:00|15:00:00|0|0|0|0;")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkActivationPeriodStoreRestore(b *testing.B) {
|
||||
b.StopTimer()
|
||||
getter, _ := NewKyotoStorage("test.kch")
|
||||
defer getter.Close()
|
||||
d := time.Date(2012, time.February, 1, 14, 30, 1, 0, time.UTC)
|
||||
i := &Interval{Month: time.February,
|
||||
MonthDay: 1,
|
||||
@@ -82,9 +87,10 @@ func BenchmarkActivationPeriodStoreRestore(b *testing.B) {
|
||||
ap := &ActivationPeriod{ActivationTime: d}
|
||||
ap.AddInterval(i)
|
||||
|
||||
ap1 := ActivationPeriod{}
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
getter.SetActivationPeriods("storerestore", []*ActivationPeriod{ap})
|
||||
getter.GetActivationPeriods("storerestore")
|
||||
result := ap.store()
|
||||
ap1.restore(result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ func TestMaxSessionTimeNoUserBudget(t *testing.T) {
|
||||
defer getter.Close()
|
||||
cd := &CallDescriptor{CstmId: "vdf", Subject: "rif", DestinationPrefix: "0723", storageGetter: getter, Amount: 1000}
|
||||
result, err := cd.GetMaxSessionTime()
|
||||
if result != 1000 || err == nil {
|
||||
if result != 1000 || err != nil {
|
||||
t.Errorf("Expected %v was %v", 1000, result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package timespans
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
/*
|
||||
Structure that gathers multiple destination prefixes under a common id.
|
||||
*/
|
||||
@@ -25,6 +29,21 @@ type Destination struct {
|
||||
Prefixes []string
|
||||
}
|
||||
|
||||
/*
|
||||
Serializes the destination for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (d *Destination) store() (result string) {
|
||||
for _, p := range d.Prefixes {
|
||||
result += p + ","
|
||||
}
|
||||
result = strings.TrimRight(result, ",")
|
||||
return
|
||||
}
|
||||
|
||||
func (d *Destination) restore(input string) {
|
||||
d.Prefixes = strings.Split(input, ",")
|
||||
}
|
||||
|
||||
/*
|
||||
De-serializes the destination for the storage. Used for key-value storages.
|
||||
*/
|
||||
|
||||
@@ -15,123 +15,83 @@ GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package timespans
|
||||
|
||||
import (
|
||||
"bitbucket.org/ww/cabinet"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"github.com/fsouza/gokabinet/kc"
|
||||
//"log"
|
||||
"sync"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type KyotoStorage struct {
|
||||
//db *kc.DB
|
||||
db *cabinet.KCDB
|
||||
buf bytes.Buffer
|
||||
dec *json.Decoder
|
||||
enc *json.Encoder
|
||||
mux sync.Mutex // we need norma lock because we reset the buf variable
|
||||
db *kc.DB
|
||||
}
|
||||
|
||||
func NewKyotoStorage(filaName string) (*KyotoStorage, error) {
|
||||
ndb := cabinet.New()
|
||||
err := ndb.Open(filaName, cabinet.KCOWRITER|cabinet.KCOCREATE)
|
||||
ks := &KyotoStorage{db: ndb}
|
||||
|
||||
ks.dec = json.NewDecoder(&ks.buf)
|
||||
ks.enc = json.NewEncoder(&ks.buf)
|
||||
return ks, err
|
||||
ndb, err := kc.Open(filaName, kc.WRITE)
|
||||
return &KyotoStorage{db: ndb}, err
|
||||
}
|
||||
|
||||
func (ks *KyotoStorage) Close() {
|
||||
ks.db.Close()
|
||||
}
|
||||
|
||||
func (ks *KyotoStorage) SetActivationPeriods(key string, aps []*ActivationPeriod) error {
|
||||
ks.mux.Lock()
|
||||
defer ks.mux.Unlock()
|
||||
func (ks *KyotoStorage) GetActivationPeriods(key string) (aps []*ActivationPeriod, err error) {
|
||||
values, err := ks.db.Get(key)
|
||||
|
||||
ks.buf.Reset()
|
||||
ks.enc.Encode(aps)
|
||||
return ks.db.Set([]byte(key), ks.buf.Bytes())
|
||||
if err == nil {
|
||||
for _, ap_string := range strings.Split(values, "\n") {
|
||||
if len(ap_string) > 0 {
|
||||
ap := &ActivationPeriod{}
|
||||
ap.restore(ap_string)
|
||||
aps = append(aps, ap)
|
||||
}
|
||||
}
|
||||
}
|
||||
return aps, err
|
||||
}
|
||||
|
||||
func (ks *KyotoStorage) GetActivationPeriods(key string) (aps []*ActivationPeriod, err error) {
|
||||
ks.mux.Lock()
|
||||
defer ks.mux.Unlock()
|
||||
func (ks *KyotoStorage) SetActivationPeriods(key string, aps []*ActivationPeriod) error {
|
||||
result := ""
|
||||
for _, ap := range aps {
|
||||
result += ap.store() + "\n"
|
||||
}
|
||||
return ks.db.Set(key, result)
|
||||
}
|
||||
|
||||
values, err := ks.db.Get([]byte(key))
|
||||
if err == nil {
|
||||
ks.buf.Reset()
|
||||
ks.buf.Write(values)
|
||||
err = ks.dec.Decode(&aps)
|
||||
func (ks *KyotoStorage) GetDestination(key string) (dest *Destination, err error) {
|
||||
if values, err := ks.db.Get(key); err == nil {
|
||||
dest = &Destination{Id: key}
|
||||
dest.restore(values)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (ks *KyotoStorage) SetDestination(dest *Destination) error {
|
||||
ks.mux.Lock()
|
||||
defer ks.mux.Unlock()
|
||||
|
||||
ks.buf.Reset()
|
||||
ks.enc.Encode(dest)
|
||||
return ks.db.Set([]byte(dest.Id), ks.buf.Bytes())
|
||||
return ks.db.Set(dest.Id, dest.store())
|
||||
}
|
||||
|
||||
func (ks *KyotoStorage) GetDestination(key string) (dest *Destination, err error) {
|
||||
ks.mux.Lock()
|
||||
defer ks.mux.Unlock()
|
||||
|
||||
values, err := ks.db.Get([]byte(key))
|
||||
if err == nil {
|
||||
ks.buf.Reset()
|
||||
ks.buf.Write(values)
|
||||
err = ks.dec.Decode(&dest)
|
||||
func (ks *KyotoStorage) GetTariffPlan(key string) (tp *TariffPlan, err error) {
|
||||
if values, err := ks.db.Get(key); err == nil {
|
||||
tp = &TariffPlan{Id: key}
|
||||
tp.restore(values)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (ks *KyotoStorage) SetTariffPlan(tp *TariffPlan) error {
|
||||
ks.mux.Lock()
|
||||
defer ks.mux.Unlock()
|
||||
|
||||
ks.buf.Reset()
|
||||
ks.enc.Encode(tp)
|
||||
return ks.db.Set([]byte(tp.Id), ks.buf.Bytes())
|
||||
return ks.db.Set(tp.Id, tp.store())
|
||||
}
|
||||
|
||||
func (ks *KyotoStorage) GetTariffPlan(key string) (tp *TariffPlan, err error) {
|
||||
ks.mux.Lock()
|
||||
defer ks.mux.Unlock()
|
||||
|
||||
values, err := ks.db.Get([]byte(key))
|
||||
if err == nil {
|
||||
ks.buf.Reset()
|
||||
ks.buf.Write(values)
|
||||
err = ks.dec.Decode(&tp)
|
||||
func (ks *KyotoStorage) GetUserBudget(key string) (ub *UserBudget, err error) {
|
||||
if values, err := ks.db.Get(key); err == nil {
|
||||
ub = &UserBudget{Id: key}
|
||||
ub.restore(values)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (ks *KyotoStorage) SetUserBudget(ub *UserBudget) error {
|
||||
ks.mux.Lock()
|
||||
defer ks.mux.Unlock()
|
||||
|
||||
ks.buf.Reset()
|
||||
ks.enc.Encode(ub)
|
||||
return ks.db.Set([]byte(ub.Id), ks.buf.Bytes())
|
||||
}
|
||||
|
||||
func (ks *KyotoStorage) GetUserBudget(key string) (ub *UserBudget, err error) {
|
||||
ks.mux.Lock()
|
||||
defer ks.mux.Unlock()
|
||||
|
||||
values, err := ks.db.Get([]byte(key))
|
||||
if err == nil {
|
||||
ks.buf.Reset()
|
||||
ks.buf.Write(values)
|
||||
ks.dec.Decode(&ub)
|
||||
}
|
||||
return
|
||||
return ks.db.Set(ub.Id, ub.store())
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ package timespans
|
||||
import (
|
||||
// "log"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type MinuteBucket struct {
|
||||
@@ -31,6 +33,28 @@ type MinuteBucket struct {
|
||||
precision int
|
||||
}
|
||||
|
||||
/*
|
||||
Serializes the minute bucket for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (mb *MinuteBucket) store() (result string) {
|
||||
result += strconv.Itoa(int(mb.Seconds)) + "|"
|
||||
result += strconv.Itoa(int(mb.Priority)) + "|"
|
||||
result += strconv.FormatFloat(mb.Price, 'f', -1, 64) + "|"
|
||||
result += mb.DestinationId
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
De-serializes the minute bucket for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (mb *MinuteBucket) restore(input string) {
|
||||
elements := strings.Split(input, "|")
|
||||
mb.Seconds, _ = strconv.ParseFloat(elements[0], 64)
|
||||
mb.Priority, _ = strconv.Atoi(elements[1])
|
||||
mb.Price, _ = strconv.ParseFloat(elements[2], 64)
|
||||
mb.DestinationId = elements[3]
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the destination loading it from the storage if necessary.
|
||||
*/
|
||||
|
||||
@@ -18,126 +18,86 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package timespans
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"github.com/simonz05/godis"
|
||||
// "log"
|
||||
"sync"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type RedisStorage struct {
|
||||
dbNb int
|
||||
db *godis.Client
|
||||
buf bytes.Buffer
|
||||
dec *json.Decoder
|
||||
enc *json.Encoder
|
||||
mux sync.Mutex
|
||||
}
|
||||
|
||||
func NewRedisStorage(address string, db int) (*RedisStorage, error) {
|
||||
ndb := godis.New(address, db, "")
|
||||
rs := &RedisStorage{db: ndb, dbNb: db}
|
||||
rs.dec = json.NewDecoder(&rs.buf)
|
||||
rs.enc = json.NewEncoder(&rs.buf)
|
||||
return rs, nil
|
||||
return &RedisStorage{db: ndb, dbNb: db}, nil
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) Close() {
|
||||
rs.db.Quit()
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) SetActivationPeriods(key string, aps []*ActivationPeriod) error {
|
||||
//.db.Select(rs.dbNb)
|
||||
rs.mux.Lock()
|
||||
defer rs.mux.Unlock()
|
||||
|
||||
rs.buf.Reset()
|
||||
rs.enc.Encode(aps)
|
||||
return rs.db.Set(key, rs.buf.Bytes())
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) GetActivationPeriods(key string) (aps []*ActivationPeriod, err error) {
|
||||
//rs.db.Select(rs.dbNb)
|
||||
rs.mux.Lock()
|
||||
defer rs.mux.Unlock()
|
||||
elem, err := rs.db.Get(key)
|
||||
values := elem.String()
|
||||
if err == nil {
|
||||
rs.buf.Reset()
|
||||
rs.buf.Write(elem.Bytes())
|
||||
|
||||
err = rs.dec.Decode(&aps)
|
||||
for _, ap_string := range strings.Split(values, "\n") {
|
||||
if len(ap_string) > 0 {
|
||||
ap := &ActivationPeriod{}
|
||||
ap.restore(ap_string)
|
||||
aps = append(aps, ap)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
return aps, err
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) SetDestination(dest *Destination) error {
|
||||
//rs.db.Select(rs.dbNb + 1)
|
||||
rs.mux.Lock()
|
||||
defer rs.mux.Unlock()
|
||||
|
||||
rs.buf.Reset()
|
||||
rs.enc.Encode(dest)
|
||||
return rs.db.Set(dest.Id, rs.buf.Bytes())
|
||||
func (rs *RedisStorage) SetActivationPeriods(key string, aps []*ActivationPeriod) error {
|
||||
//.db.Select(rs.dbNb)
|
||||
result := ""
|
||||
for _, ap := range aps {
|
||||
result += ap.store() + "\n"
|
||||
}
|
||||
return rs.db.Set(key, result)
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) GetDestination(key string) (dest *Destination, err error) {
|
||||
//rs.db.Select(rs.dbNb + 1)
|
||||
rs.mux.Lock()
|
||||
defer rs.mux.Unlock()
|
||||
if values, err := rs.db.Get(key); err == nil {
|
||||
dest = &Destination{Id: key}
|
||||
dest.restore(values.String())
|
||||
}
|
||||
return
|
||||
}
|
||||
func (rs *RedisStorage) SetDestination(dest *Destination) error {
|
||||
//rs.db.Select(rs.dbNb + 1)
|
||||
return rs.db.Set(dest.Id, dest.store())
|
||||
}
|
||||
|
||||
elem, err := rs.db.Get(key)
|
||||
if err == nil {
|
||||
rs.buf.Reset()
|
||||
rs.buf.Write(elem.Bytes())
|
||||
err = rs.dec.Decode(&dest)
|
||||
func (rs *RedisStorage) GetTariffPlan(key string) (tp *TariffPlan, err error) {
|
||||
//rs.db.Select(rs.dbNb + 2)
|
||||
if values, err := rs.db.Get(key); err == nil {
|
||||
tp = &TariffPlan{Id: key}
|
||||
tp.restore(values.String())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) SetTariffPlan(tp *TariffPlan) error {
|
||||
//rs.db.Select(rs.dbNb + 2)
|
||||
rs.mux.Lock()
|
||||
defer rs.mux.Unlock()
|
||||
|
||||
rs.buf.Reset()
|
||||
rs.enc.Encode(tp)
|
||||
return rs.db.Set(tp.Id, rs.buf.Bytes())
|
||||
return rs.db.Set(tp.Id, tp.store())
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) GetTariffPlan(key string) (tp *TariffPlan, err error) {
|
||||
//rs.db.Select(rs.dbNb + 2)
|
||||
rs.mux.Lock()
|
||||
defer rs.mux.Unlock()
|
||||
|
||||
elem, err := rs.db.Get(key)
|
||||
if err == nil {
|
||||
rs.buf.Reset()
|
||||
rs.buf.Write(elem.Bytes())
|
||||
err = rs.dec.Decode(&tp)
|
||||
func (rs *RedisStorage) GetUserBudget(key string) (ub *UserBudget, err error) {
|
||||
//rs.db.Select(rs.dbNb + 3)
|
||||
if values, err := rs.db.Get(key); err == nil {
|
||||
ub = &UserBudget{Id: key}
|
||||
ub.restore(values.String())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) SetUserBudget(ub *UserBudget) error {
|
||||
//rs.db.Select(rs.dbNb + 3)
|
||||
rs.mux.Lock()
|
||||
defer rs.mux.Unlock()
|
||||
|
||||
rs.buf.Reset()
|
||||
rs.enc.Encode(ub)
|
||||
return rs.db.Set(ub.Id, rs.buf.Bytes())
|
||||
}
|
||||
|
||||
func (rs *RedisStorage) GetUserBudget(key string) (ub *UserBudget, err error) {
|
||||
//rs.db.Select(rs.dbNb + 3)
|
||||
rs.mux.Lock()
|
||||
defer rs.mux.Unlock()
|
||||
|
||||
elem, err := rs.db.Get(key)
|
||||
if err == nil {
|
||||
rs.buf.Reset()
|
||||
rs.buf.Write(elem.Bytes())
|
||||
err = rs.dec.Decode(&ub)
|
||||
}
|
||||
return
|
||||
return rs.db.Set(ub.Id, ub.store())
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ package timespans
|
||||
|
||||
import (
|
||||
// "log"
|
||||
"strings"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -35,6 +37,62 @@ type TariffPlan struct {
|
||||
VolumeDiscountThresholds []*VolumeDiscount
|
||||
}
|
||||
|
||||
/*
|
||||
Serializes the tariff plan for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (tp *TariffPlan) store() (result string) {
|
||||
result += strconv.FormatFloat(tp.SmsCredit, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(tp.Traffic, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(tp.ReceivedCallSecondsLimit, 'f', -1, 64) + ";"
|
||||
if tp.RecivedCallBonus == nil {
|
||||
tp.RecivedCallBonus = &RecivedCallBonus{}
|
||||
}
|
||||
result += tp.RecivedCallBonus.store() + ";"
|
||||
for i, mb := range tp.MinuteBuckets {
|
||||
if i > 0 {
|
||||
result += ","
|
||||
}
|
||||
result += mb.store()
|
||||
}
|
||||
if tp.VolumeDiscountThresholds != nil {
|
||||
result += ";"
|
||||
}
|
||||
for i, vd := range tp.VolumeDiscountThresholds {
|
||||
if i > 0 {
|
||||
result += ","
|
||||
}
|
||||
result += strconv.FormatFloat(vd.Volume, 'f', -1, 64) + "|" + strconv.FormatFloat(vd.Discount, 'f', -1, 64)
|
||||
}
|
||||
result = strings.TrimRight(result, ";")
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
De-serializes the tariff plan for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (tp *TariffPlan) restore(input string) {
|
||||
elements := strings.Split(input, ";")
|
||||
tp.SmsCredit, _ = strconv.ParseFloat(elements[0], 64)
|
||||
tp.Traffic, _ = strconv.ParseFloat(elements[1], 64)
|
||||
tp.ReceivedCallSecondsLimit, _ = strconv.ParseFloat(elements[2], 64)
|
||||
tp.RecivedCallBonus = &RecivedCallBonus{}
|
||||
tp.RecivedCallBonus.restore(elements[3])
|
||||
for _, mbs := range strings.Split(elements[4], ",") {
|
||||
mb := &MinuteBucket{}
|
||||
mb.restore(mbs)
|
||||
tp.MinuteBuckets = append(tp.MinuteBuckets, mb)
|
||||
}
|
||||
if len(elements) > 5 {
|
||||
for _, vdss := range strings.Split(elements[5], ",") {
|
||||
vd := &VolumeDiscount{}
|
||||
vds := strings.Split(vdss, "|")
|
||||
vd.Volume, _ = strconv.ParseFloat(vds[0], 64)
|
||||
vd.Discount, _ = strconv.ParseFloat(vds[1], 64)
|
||||
tp.VolumeDiscountThresholds = append(tp.VolumeDiscountThresholds, vd)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Structure that holds the thresholds and for which
|
||||
*/
|
||||
@@ -52,3 +110,31 @@ type RecivedCallBonus struct {
|
||||
Traffic float64
|
||||
MinuteBucket *MinuteBucket
|
||||
}
|
||||
|
||||
/*
|
||||
Serializes the tariff plan for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (rcb *RecivedCallBonus) store() (result string) {
|
||||
result += strconv.FormatFloat(rcb.Credit, 'f', -1, 64) + ","
|
||||
result += strconv.FormatFloat(rcb.SmsCredit, 'f', -1, 64) + ","
|
||||
result += strconv.FormatFloat(rcb.Traffic, 'f', -1, 64)
|
||||
if rcb.MinuteBucket != nil {
|
||||
result += ","
|
||||
result += rcb.MinuteBucket.store()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
De-serializes the tariff plan for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (rcb *RecivedCallBonus) restore(input string) {
|
||||
elements := strings.Split(input, ",")
|
||||
rcb.Credit, _ = strconv.ParseFloat(elements[0], 64)
|
||||
rcb.SmsCredit, _ = strconv.ParseFloat(elements[1], 64)
|
||||
rcb.Traffic, _ = strconv.ParseFloat(elements[2], 64)
|
||||
if len(elements) > 3 {
|
||||
rcb.MinuteBucket = &MinuteBucket{}
|
||||
rcb.MinuteBucket.restore(elements[3])
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -21,6 +21,8 @@ import (
|
||||
// "log"
|
||||
"sort"
|
||||
"sync"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -68,6 +70,50 @@ func (bs bucketsorter) Less(j, i int) bool {
|
||||
bs[i].Price > bs[j].Price
|
||||
}
|
||||
|
||||
/*
|
||||
Serializes the user budget for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (ub *UserBudget) store() (result string) {
|
||||
result += strconv.FormatFloat(ub.Credit, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(ub.SmsCredit, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(ub.Traffic, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(ub.VolumeDiscountSeconds, 'f', -1, 64) + ";"
|
||||
result += strconv.FormatFloat(ub.ReceivedCallSeconds, 'f', -1, 64) + ";"
|
||||
result += strconv.Itoa(ub.ResetDayOfTheMonth) + ";"
|
||||
result += ub.TariffPlanId
|
||||
if ub.MinuteBuckets != nil {
|
||||
result += ";"
|
||||
}
|
||||
for i, mb := range ub.MinuteBuckets {
|
||||
if i > 0 {
|
||||
result += ","
|
||||
}
|
||||
result += mb.store()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
De-serializes the user budget for the storage. Used for key-value storages.
|
||||
*/
|
||||
func (ub *UserBudget) restore(input string) {
|
||||
elements := strings.Split(input, ";")
|
||||
ub.Credit, _ = strconv.ParseFloat(elements[0], 64)
|
||||
ub.SmsCredit, _ = strconv.ParseFloat(elements[1], 64)
|
||||
ub.Traffic, _ = strconv.ParseFloat(elements[2], 64)
|
||||
ub.VolumeDiscountSeconds, _ = strconv.ParseFloat(elements[3], 64)
|
||||
ub.ReceivedCallSeconds, _ = strconv.ParseFloat(elements[4], 64)
|
||||
ub.ResetDayOfTheMonth, _ = strconv.Atoi(elements[5])
|
||||
ub.TariffPlanId = elements[6]
|
||||
if len(elements) > 7 {
|
||||
for _, mbs := range strings.Split(elements[7], ",") {
|
||||
mb := &MinuteBucket{}
|
||||
mb.restore(mbs)
|
||||
ub.MinuteBuckets = append(ub.MinuteBuckets, mb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the tariff plan loading it from the storage if necessary.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user