From 321b4df295dfb45fcffa2da2c8e4c2a2c0c75a7b Mon Sep 17 00:00:00 2001 From: DEV Date: Sat, 4 May 2024 02:41:05 +0200 Subject: [PATCH] reestructurando el codigo e incorporando las librerias de active2 --- A/go.mod | 2 +- A/test/field_benchmarks_test.go | 81 ++-- A/test/go.mod | 2 +- base/apcks/go.mod | 3 + {apcks => base/apcks}/state/active.go | 0 {apcks => base/apcks}/state/builder_state.go | 0 {apcks => base/apcks}/state/element.go | 0 {apcks => base/apcks}/state/err_code.go | 0 core/bits/active.go | 44 +++ core/bits/bflags_16.go | 97 +++++ core/bits/g_bflags.go | 106 ++++++ core/bits/go.mod | 3 + core/cdcs/base32/writer.go | 70 ++++ core/cdcs/base64/writer.go | 76 ++++ core/cdcs/cjson/active.go | 73 ++++ core/cdcs/cjson/char_att.go | 45 +++ core/cdcs/cjson/writer.go | 193 ++++++++++ core/cdcs/go.mod | 3 + core/crns/active.go | 66 ++++ core/crns/chrono.go | 108 ++++++ core/crns/chronometer.go | 59 +++ core/crns/expiration.go | 182 +++++++++ core/crns/expiration_source.go | 62 +++ core/crns/expirer.go | 57 +++ core/crns/go.mod | 4 + core/crns/pulsar.go | 169 +++++++++ core/crns/time_task.go | 48 +++ core/crns/timer_queue.go | 188 ++++++++++ core/crns/timer_state.go | 81 ++++ core/crns/timer_task.go | 60 +++ core/crns/timer_task_heap.go | 89 +++++ core/crps/active.go | 35 ++ core/crps/crypter.go | 35 ++ core/crps/decrypter.go | 43 +++ core/crps/encrypter.go | 42 +++ core/crps/go.mod | 4 + core/ctxs/cancel.go | 76 ++++ core/ctxs/go.mod | 3 + core/dtes/active.go | 83 +++++ core/dtes/bdates/active.go | 55 +++ core/dtes/bdates/bmonth.go | 34 ++ core/dtes/bdates/bweek.go | 125 +++++++ core/dtes/bdates/byear.go | 128 +++++++ core/dtes/bdates/byear_att.go | 51 +++ core/dtes/bdates/err.go | 33 ++ core/dtes/date_days.go | 102 +++++ core/dtes/date_days_range.go | 94 +++++ core/dtes/duration_formatter.go | 83 +++++ core/dtes/go.mod | 5 + core/dtes/time_formatter.go | 145 +++++++ core/iosys/ansi/active.go | 140 +++++++ core/iosys/ansi/code.go | 256 +++++++++++++ core/iosys/ansi/color.go | 65 ++++ core/iosys/ansi/go.mod | 3 + core/iosys/ansi/non_escape_writer.go | 117 ++++++ core/iosys/ansi/style.go | 77 ++++ core/iosys/flusher.go | 52 +++ core/iosys/go.mod | 3 + core/iosys/writer_flusher.go | 53 +++ core/mems/pool.go | 2 +- core/opts/g_option.go | 79 ++++ core/opts/go.mod | 4 + core/rsls/bytes.go | 93 +++++ core/rsls/g_result.go | 86 +++++ core/rsls/go.mod | 3 + core/rsls/int.go | 80 ++++ core/rsls/result.go | 44 +++ core/rsls/string.go | 80 ++++ core/syns/abool.go | 109 ++++++ core/syns/aduration.go | 117 ++++++ core/syns/aerror.go | 90 +++++ core/syns/aint32.go | 121 ++++++ core/syns/aint64.go | 121 ++++++ core/syns/ananos.go | 155 ++++++++ core/syns/auint32.go | 121 ++++++ core/syns/auint64.go | 121 ++++++ core/syns/b32_aint.go | 64 ++++ core/syns/b32_uint.go | 64 ++++ core/syns/b64_int.go | 124 ++++++ core/syns/b64_uint.go | 124 ++++++ core/syns/ctasks/active.go | 63 ++++ core/syns/ctasks/completer.go | 42 +++ core/syns/ctasks/completion.go | 373 +++++++++++++++++++ core/syns/ctasks/context.go | 39 ++ core/syns/ctasks/mode.go | 92 +++++ core/syns/ctasks/result.go | 51 +++ core/syns/ctasks/result_error.go | 74 ++++ core/syns/ctasks/result_kind.go | 87 +++++ core/syns/ctasks/result_list.go | 88 +++++ core/syns/ctasks/result_value.go | 74 ++++ core/syns/ctasks/result_void.go | 70 ++++ core/syns/ctasks/state.go | 58 +++ core/syns/go.mod | 4 + core/syns/locker_read.go | 50 +++ core/syns/locker_rw.go | 49 +++ core/syns/locker_write.go | 50 +++ core/syns/nop_locker.go | 45 +++ core/syns/pools/g_pool.go | 134 +++++++ core/syns/pools/pool_call_sizes.go | 44 +++ core/syns/pools/pool_stats.go | 39 ++ core/syns/pools/pool_stats_info.go | 64 ++++ core/syns/queue/g_queue.go | 87 +++++ core/syns/signaler.go | 27 ++ core/syns/works/active.go | 56 +++ core/syns/works/pool.go | 282 ++++++++++++++ core/syns/works/pool_state.go | 40 ++ core/syns/works/worker.go | 38 ++ core/typs/astrings/active.go | 113 ++++++ core/typs/astrings/camel.go | 88 +++++ core/typs/astrings/err_astrings.go | 51 +++ core/typs/astrings/snake.go | 117 ++++++ core/typs/astrings/string.go | 59 +++ core/typs/astrings/transformer.go | 42 +++ core/typs/astrings/transformers.go | 58 +++ core/typs/go.mod | 3 + core/typs/numbers.go | 51 +++ core/typs/slices/strings.go | 58 +++ core/vals/active.go | 24 ++ core/vals/g_name_valuer.go | 33 ++ core/vals/g_valuer.go | 40 ++ core/vals/go.mod | 3 + core/vals/key_value_getter.go | 50 +++ core/vals/key_value_setter.go | 42 +++ core/vals/name_valuer.go | 35 ++ core/vals/namer.go | 38 ++ core/vals/scope.go | 98 +++++ core/vals/scope_att.go | 36 ++ core/vals/scope_ops.go | 33 ++ core/vals/valuer.go | 71 ++++ go.work | 11 +- 130 files changed, 8947 insertions(+), 42 deletions(-) create mode 100644 base/apcks/go.mod rename {apcks => base/apcks}/state/active.go (100%) rename {apcks => base/apcks}/state/builder_state.go (100%) rename {apcks => base/apcks}/state/element.go (100%) rename {apcks => base/apcks}/state/err_code.go (100%) create mode 100644 core/bits/active.go create mode 100644 core/bits/bflags_16.go create mode 100644 core/bits/g_bflags.go create mode 100644 core/bits/go.mod create mode 100644 core/cdcs/base32/writer.go create mode 100644 core/cdcs/base64/writer.go create mode 100644 core/cdcs/cjson/active.go create mode 100644 core/cdcs/cjson/char_att.go create mode 100644 core/cdcs/cjson/writer.go create mode 100644 core/cdcs/go.mod create mode 100644 core/crns/active.go create mode 100644 core/crns/chrono.go create mode 100644 core/crns/chronometer.go create mode 100644 core/crns/expiration.go create mode 100644 core/crns/expiration_source.go create mode 100644 core/crns/expirer.go create mode 100644 core/crns/go.mod create mode 100644 core/crns/pulsar.go create mode 100644 core/crns/time_task.go create mode 100644 core/crns/timer_queue.go create mode 100644 core/crns/timer_state.go create mode 100644 core/crns/timer_task.go create mode 100644 core/crns/timer_task_heap.go create mode 100644 core/crps/active.go create mode 100644 core/crps/crypter.go create mode 100644 core/crps/decrypter.go create mode 100644 core/crps/encrypter.go create mode 100644 core/crps/go.mod create mode 100644 core/ctxs/cancel.go create mode 100644 core/ctxs/go.mod create mode 100644 core/dtes/active.go create mode 100644 core/dtes/bdates/active.go create mode 100644 core/dtes/bdates/bmonth.go create mode 100644 core/dtes/bdates/bweek.go create mode 100644 core/dtes/bdates/byear.go create mode 100644 core/dtes/bdates/byear_att.go create mode 100644 core/dtes/bdates/err.go create mode 100644 core/dtes/date_days.go create mode 100644 core/dtes/date_days_range.go create mode 100644 core/dtes/duration_formatter.go create mode 100644 core/dtes/go.mod create mode 100644 core/dtes/time_formatter.go create mode 100644 core/iosys/ansi/active.go create mode 100644 core/iosys/ansi/code.go create mode 100644 core/iosys/ansi/color.go create mode 100644 core/iosys/ansi/go.mod create mode 100644 core/iosys/ansi/non_escape_writer.go create mode 100644 core/iosys/ansi/style.go create mode 100644 core/iosys/flusher.go create mode 100644 core/iosys/go.mod create mode 100644 core/iosys/writer_flusher.go create mode 100644 core/opts/g_option.go create mode 100644 core/opts/go.mod create mode 100644 core/rsls/bytes.go create mode 100644 core/rsls/g_result.go create mode 100644 core/rsls/go.mod create mode 100644 core/rsls/int.go create mode 100644 core/rsls/result.go create mode 100644 core/rsls/string.go create mode 100644 core/syns/abool.go create mode 100644 core/syns/aduration.go create mode 100644 core/syns/aerror.go create mode 100644 core/syns/aint32.go create mode 100644 core/syns/aint64.go create mode 100644 core/syns/ananos.go create mode 100644 core/syns/auint32.go create mode 100644 core/syns/auint64.go create mode 100644 core/syns/b32_aint.go create mode 100644 core/syns/b32_uint.go create mode 100644 core/syns/b64_int.go create mode 100644 core/syns/b64_uint.go create mode 100644 core/syns/ctasks/active.go create mode 100644 core/syns/ctasks/completer.go create mode 100644 core/syns/ctasks/completion.go create mode 100644 core/syns/ctasks/context.go create mode 100644 core/syns/ctasks/mode.go create mode 100644 core/syns/ctasks/result.go create mode 100644 core/syns/ctasks/result_error.go create mode 100644 core/syns/ctasks/result_kind.go create mode 100644 core/syns/ctasks/result_list.go create mode 100644 core/syns/ctasks/result_value.go create mode 100644 core/syns/ctasks/result_void.go create mode 100644 core/syns/ctasks/state.go create mode 100644 core/syns/go.mod create mode 100644 core/syns/locker_read.go create mode 100644 core/syns/locker_rw.go create mode 100644 core/syns/locker_write.go create mode 100644 core/syns/nop_locker.go create mode 100644 core/syns/pools/g_pool.go create mode 100644 core/syns/pools/pool_call_sizes.go create mode 100644 core/syns/pools/pool_stats.go create mode 100644 core/syns/pools/pool_stats_info.go create mode 100644 core/syns/queue/g_queue.go create mode 100644 core/syns/signaler.go create mode 100644 core/syns/works/active.go create mode 100644 core/syns/works/pool.go create mode 100644 core/syns/works/pool_state.go create mode 100644 core/syns/works/worker.go create mode 100644 core/typs/astrings/active.go create mode 100644 core/typs/astrings/camel.go create mode 100644 core/typs/astrings/err_astrings.go create mode 100644 core/typs/astrings/snake.go create mode 100644 core/typs/astrings/string.go create mode 100644 core/typs/astrings/transformer.go create mode 100644 core/typs/astrings/transformers.go create mode 100644 core/typs/go.mod create mode 100644 core/typs/numbers.go create mode 100644 core/typs/slices/strings.go create mode 100644 core/vals/active.go create mode 100644 core/vals/g_name_valuer.go create mode 100644 core/vals/g_valuer.go create mode 100644 core/vals/go.mod create mode 100644 core/vals/key_value_getter.go create mode 100644 core/vals/key_value_setter.go create mode 100644 core/vals/name_valuer.go create mode 100644 core/vals/namer.go create mode 100644 core/vals/scope.go create mode 100644 core/vals/scope_att.go create mode 100644 core/vals/scope_ops.go create mode 100644 core/vals/valuer.go diff --git a/A/go.mod b/A/go.mod index 0959576..76c3651 100644 --- a/A/go.mod +++ b/A/go.mod @@ -1,3 +1,3 @@ -module A +module a go 1.22 diff --git a/A/test/field_benchmarks_test.go b/A/test/field_benchmarks_test.go index 96d01d8..5c855a3 100644 --- a/A/test/field_benchmarks_test.go +++ b/A/test/field_benchmarks_test.go @@ -24,6 +24,7 @@ package test import ( + "flds" "testing" ) @@ -31,14 +32,14 @@ import ( func BenchmarkAflds (b *testing.B) { for i := 0; i < b.N; i++ { - aflds.NewFieldString("f1", "value") - aflds.NewFieldUint("f2", 11) - aflds.NewFieldInt("f3", -11) - aflds.NewFieldFloat("f4", 2.3) - aflds.NewFieldBinary("f5", []byte{1,2,2,4,3,3,3,3}) - aflds.NewDFieldInt("d1",func()int{ return -3 }) - aflds.NewDFieldUint("d2",func()uint{ return uint(3) }) - aflds.NewDFieldFloat("f2",func()float64{ return 3.2}) + flds.NewFieldString("f1", "value") + flds.NewFieldUint("f2", 11) + flds.NewFieldInt("f3", -11) + flds.NewFieldFloat("f4", 2.3) + flds.NewFieldBinary("f5", []byte{1,2,2,4,3,3,3,3}) + flds.NewDFieldInt("d1",func()int{ return -3 }) + flds.NewDFieldUint("d2",func()uint{ return uint(3) }) + flds.NewDFieldFloat("f2",func()float64{ return 3.2}) } } @@ -47,15 +48,15 @@ func BenchmarkAflds (b *testing.B) { func BenchmarkAfldsAcc (b *testing.B) { var d[8]any - flds := []aflds.Field { - aflds.NewFieldString("f1", "value"), - aflds.NewFieldUint("f2", 11), - aflds.NewFieldInt("f3", -11), - aflds.NewFieldFloat("f4", 2.3), - aflds.NewFieldBinary("f5", []byte{1,2,2,4,3,3,3,3}), - aflds.NewDFieldInt("d1",func()int{ return -3 }), - aflds.NewDFieldUint("d2",func()uint{ return uint(3) }), - aflds.NewDFieldFloat("f2",func()float64{ return 3.2}), + flds := []flds.Field { + flds.NewFieldString("f1", "value"), + flds.NewFieldUint("f2", 11), + flds.NewFieldInt("f3", -11), + flds.NewFieldFloat("f4", 2.3), + flds.NewFieldBinary("f5", []byte{1,2,2,4,3,3,3,3}), + flds.NewDFieldInt("d1",func()int{ return -3 }), + flds.NewDFieldUint("d2",func()uint{ return uint(3) }), + flds.NewDFieldFloat("f2",func()float64{ return 3.2}), } for i := 0; i < b.N; i++ { for i:=0; i<8; i++ { @@ -67,15 +68,15 @@ func BenchmarkAfldsAcc (b *testing.B) { func BenchmarkAfldsAcDf (b *testing.B) { var d[8]any - flds := []aflds.Field { - aflds.NewDFieldInt("d1",func()int{ return -3 }), - aflds.NewDFieldInt("d1",func()int{ return -3 }), - aflds.NewDFieldInt("d1",func()int{ return -3 }), - aflds.NewDFieldInt("d1",func()int{ return -3 }), - aflds.NewDFieldInt("d1",func()int{ return -3 }), - aflds.NewDFieldInt("d1",func()int{ return -3 }), - aflds.NewDFieldInt("d1",func()int{ return -3 }), - aflds.NewDFieldInt("d1",func()int{ return -3 }), + flds := []flds.Field { + flds.NewDFieldInt("d1",func()int{ return -3 }), + flds.NewDFieldInt("d1",func()int{ return -3 }), + flds.NewDFieldInt("d1",func()int{ return -3 }), + flds.NewDFieldInt("d1",func()int{ return -3 }), + flds.NewDFieldInt("d1",func()int{ return -3 }), + flds.NewDFieldInt("d1",func()int{ return -3 }), + flds.NewDFieldInt("d1",func()int{ return -3 }), + flds.NewDFieldInt("d1",func()int{ return -3 }), } for i := 0; i < b.N; i++ { for i:=0; i<8; i++ { @@ -88,15 +89,15 @@ func BenchmarkAfldsAcDf (b *testing.B) { func BenchmarkAfldsAcDo (b *testing.B) { var d[8]any - flds := []aflds.Field { - aflds.NewDOFieldInt("d1",func()int{ return -3 }), - aflds.NewDOFieldInt("d1",func()int{ return -3 }), - aflds.NewDOFieldInt("d1",func()int{ return -3 }), - aflds.NewDOFieldInt("d1",func()int{ return -3 }), - aflds.NewDOFieldInt("d1",func()int{ return -3 }), - aflds.NewDOFieldInt("d1",func()int{ return -3 }), - aflds.NewDOFieldInt("d1",func()int{ return -3 }), - aflds.NewDOFieldInt("d1",func()int{ return -3 }), + flds := []flds.Field { + flds.NewDOFieldInt("d1",func()int{ return -3 }), + flds.NewDOFieldInt("d1",func()int{ return -3 }), + flds.NewDOFieldInt("d1",func()int{ return -3 }), + flds.NewDOFieldInt("d1",func()int{ return -3 }), + flds.NewDOFieldInt("d1",func()int{ return -3 }), + flds.NewDOFieldInt("d1",func()int{ return -3 }), + flds.NewDOFieldInt("d1",func()int{ return -3 }), + flds.NewDOFieldInt("d1",func()int{ return -3 }), } for i := 0; i < b.N; i++ { for i:=0; i<8; i++ { @@ -104,3 +105,13 @@ func BenchmarkAfldsAcDo (b *testing.B) { } } } + + +func BenchmarkAfldsAcDo1 (b *testing.B) { + flds := []flds.Field { + flds.NewDOFieldInt("d1",func()int{ return -3 }), + } + flds[0].Value() + + +} diff --git a/A/test/go.mod b/A/test/go.mod index 7ec0b44..2789056 100644 --- a/A/test/go.mod +++ b/A/test/go.mod @@ -1,3 +1,3 @@ -module AATest +module test go 1.22 diff --git a/base/apcks/go.mod b/base/apcks/go.mod new file mode 100644 index 0000000..4117d9c --- /dev/null +++ b/base/apcks/go.mod @@ -0,0 +1,3 @@ +module apcks + +go 1.22 diff --git a/apcks/state/active.go b/base/apcks/state/active.go similarity index 100% rename from apcks/state/active.go rename to base/apcks/state/active.go diff --git a/apcks/state/builder_state.go b/base/apcks/state/builder_state.go similarity index 100% rename from apcks/state/builder_state.go rename to base/apcks/state/builder_state.go diff --git a/apcks/state/element.go b/base/apcks/state/element.go similarity index 100% rename from apcks/state/element.go rename to base/apcks/state/element.go diff --git a/apcks/state/err_code.go b/base/apcks/state/err_code.go similarity index 100% rename from apcks/state/err_code.go rename to base/apcks/state/err_code.go diff --git a/core/bits/active.go b/core/bits/active.go new file mode 100644 index 0000000..17311dc --- /dev/null +++ b/core/bits/active.go @@ -0,0 +1,44 @@ +/* + * + * --------------------------------------------------------- + * Project $PROJECT_NAME + * Active Thing (activething.com) git.activething.com/go + * + * File name $FILE_NAME + * Created by ${USER} + * Modified ${DAY}/${MONTH}/${YEAR} + * + * Copyright ${YEAR} activething.com + * --------------------------------------------------------- + * // Licensed under the Apache License, Version 2.0 (the "License"); + * // you may not use this file except in compliance with the License. + * // You may obtain a copy of the License at + * // + * // http://www.apache.org/licenses/LICENSE-2.0 + * // + * // Unless required by applicable law or agreed to in writing, software + * // distributed under the License is distributed on an "AS IS" BASIS, + * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * // See the License for the specific language governing permissions and + * // limitations under the License. + * // + * / + * + */ + +package bits + +import "errs" + +var ( + + G = struct { + + ErrUnsupportedFlagType errs.ErrCode + }{ + + ErrUnsupportedFlagType : errs.ErrCode ("unsupported-bit-flag-type") , + } +) + + diff --git a/core/bits/bflags_16.go b/core/bits/bflags_16.go new file mode 100644 index 0000000..d1c756b --- /dev/null +++ b/core/bits/bflags_16.go @@ -0,0 +1,97 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name bflag_16.go +// Created by DEV +// Modified 15/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package bits + +import ( + "math/bits" +) + + +type BFlags16 uint16 + + + +func (f BFlags16) Has ( flag BFlags16) bool { + return f&flag != 0 } + + +func (f BFlags16) Add ( flag BFlags16) BFlags16 { + return f|flag } + + +func (f BFlags16) AddWithMask ( flag BFlags16, mask BFlags16) BFlags16 { + return (f&mask) | flag } + + +func (f BFlags16) Del ( flag BFlags16) BFlags16 { + return f&^flag } + + +func (f BFlags16) Invert () BFlags16 { + return ^f } + + +func (f BFlags16) Count() int { + return bits.OnesCount16(uint16(f)) } + + + +func (f BFlags16) Extract() []BFlags16 { + if f == 0 { + return []BFlags16{} + } + l := make([]BFlags16,0,16) + c := BFlags16(1) + for i:=1; i<= 7; i++ { + if c&f == c { + l = append(l,c) + } + c <<= 1 + } + return l +} + + +func (f BFlags16) FlagsToNames (namer func(flags BFlags16) string) []string { + if f == 0 { + return []string{} + } + l := make([]string,0,16) + c := BFlags16(1) + for i:=1; i<= 7; i++ { + if c&f == c { + l = append(l,namer(c)) + } + c <<= 1 + } + return l +} + + +func (f BFlags16) NamesToFlags (names []string, flagger func(name string) BFlags16) BFlags16 { + for _,s := range names { + f|=flagger(s) + } + return f +} \ No newline at end of file diff --git a/core/bits/g_bflags.go b/core/bits/g_bflags.go new file mode 100644 index 0000000..ff69395 --- /dev/null +++ b/core/bits/g_bflags.go @@ -0,0 +1,106 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name bflag.go +// Created by DEV +// Modified 15/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package bits + +import ( + "encoding/binary" + "math/bits" + "typs" +) + + + + +func Has [T typs.UnsignedAll](source T, flag T) bool { + return source&flag != 0 } + + +func Add [T typs.UnsignedAll](source T, flag T) T { + return source|flag } + + +func AddWithMask [T typs.UnsignedAll](source T, flag T, mask T) T { + return (source&mask) | flag } + + +func Del [T typs.UnsignedAll](source T, flag T) T { + return source&^flag } + + +func Invert [T typs.UnsignedAll](source T) T { + return ^source } + + +func Count[T typs.UnsignedAll](source T) int { + switch binary.Size(source) { + case 1 : return bits.OnesCount8 (uint8(source)) + case 2 : return bits.OnesCount16(uint16(source)) + case 4 : return bits.OnesCount32(uint32(source)) + case 8 : return bits.OnesCount64(uint64(source)) + default: + panic(G.ErrUnsupportedFlagType) + } +} + + + +func Extract[T typs.UnsignedAll](source T) []T { + if source == 0 { + return []T{} + } + l := make([]T,0,16) + c := T(1) + for i:=1; i<= 7; i++ { + if c&source == c { + l = append(l,c) + } + c <<= 1 + } + return l +} + + +func FlagsToNames [T typs.UnsignedAll](source T, namer func(flags T) string) []string { + if source == 0 { + return []string{} + } + l := make([]string,0,16) + c := T(1) + for i:=1; i<= 7; i++ { + if c&source == c { + l = append(l,namer(c)) + } + c <<= 1 + } + return l +} + + +func NamesToFlags [T typs.UnsignedAll](names []string, flagger func(name string) T) T { + var f T + for _,s := range names { + f|=flagger(s) + } + return f +} \ No newline at end of file diff --git a/core/bits/go.mod b/core/bits/go.mod new file mode 100644 index 0000000..5fb1807 --- /dev/null +++ b/core/bits/go.mod @@ -0,0 +1,3 @@ +module bits + +go 1.22 diff --git a/core/cdcs/base32/writer.go b/core/cdcs/base32/writer.go new file mode 100644 index 0000000..abc27fe --- /dev/null +++ b/core/cdcs/base32/writer.go @@ -0,0 +1,70 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name writer.go +// Created by DEV +// Modified 23/04/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package base32 + +import ( + "encoding/base32" + "mems" +) + +func Write(b *mems.ABuffer, value, null, empty []byte, isQuoted bool, quote byte) (er error) { + if value == nil { + _,_ = b.Write(null) + return nil + } + if len(value) == 0 { + _,_ = b.Write(empty) + return nil + } + + p := b.Len() + if isQuoted { + b.WriteByte(quote) + } + + var t [64]byte + ln := base32.StdEncoding.EncodedLen(len(value)) + if ln <= len(t) { + dst := t[:ln] + base32.StdEncoding.Encode(dst, value) + _,er = b.Write(dst) + } else if ln <= 1024 { + dst := make([]byte, ln) + base32.StdEncoding.Encode(dst, value) + _,er = b.Write(dst) + } else if er == nil { + ec := base32.NewEncoder(base32.StdEncoding, b) + _,_ = ec.Write(value) + return ec.Close() + } + + if er == nil { + if isQuoted { + b.WriteByte(quote) + } + } else { + b.Truncate(p) + } + return er +} diff --git a/core/cdcs/base64/writer.go b/core/cdcs/base64/writer.go new file mode 100644 index 0000000..400e025 --- /dev/null +++ b/core/cdcs/base64/writer.go @@ -0,0 +1,76 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name writer.go +// Created by DEV +// Modified 23/04/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package base64 + +import ( + "encoding/base64" + "mems" +) + + + +func Write(b *mems.ABuffer, value, null, empty []byte, isQuoted bool, quote byte) (er error) { + if value == nil { + _,_ = b.Write(null) + return nil + } + if len(value) == 0 { + _,_ = b.Write(empty) + return nil + } + + p := b.Len() + if isQuoted { + b.WriteByte(quote) + } + + var t [64]byte + ln := base64.StdEncoding.EncodedLen(len(value)) + if ln <= len(t) { + dst := t[:ln] + base64.StdEncoding.Encode(dst, value) + _,er = b.Write(dst) + } else if ln <= 1024 { + dst := make([]byte, ln) + base64.StdEncoding.Encode(dst, value) + _,er = b.Write(dst) + } else if er == nil { + ec := base64.NewEncoder(base64.StdEncoding, b) + _,_ = ec.Write(value) + er = ec.Close() + } + + if er == nil { + if isQuoted { + b.WriteByte(quote) + } + } else { + b.Truncate(p) + } + + return er +} + + + diff --git a/core/cdcs/cjson/active.go b/core/cdcs/cjson/active.go new file mode 100644 index 0000000..444f8a9 --- /dev/null +++ b/core/cdcs/cjson/active.go @@ -0,0 +1,73 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name active.go +// Created by DEV +// Modified 21/04/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package cjson + +import "unicode/utf8" + +var ( + + G = struct { + Hex string + JSONChars [utf8.RuneSelf]CharAtt + + NullValue []byte + EmptyValue []byte + ZeroValue []byte + TrueValue []byte + FalseValue []byte + + FloatNaN []byte + FloatInfPos []byte + FloatInfNeg []byte + } { + + Hex: "0123456789abcdef", + JSONChars: initJSONChars(), + + NullValue: []byte{'n', 'u', 'l', 'l'}, + ZeroValue: []byte{'0'}, + EmptyValue: []byte{'"','"'}, + TrueValue: []byte{'"','t', 'r', 'u', 'e','"'}, + FalseValue: []byte{'"','f', 'a', 'l', 's', 'e','"'}, + + FloatNaN: []byte{'"', 'N', 'a', 'N', '"'}, + FloatInfPos: []byte{'"', 'I', 'n', 'f', '"'}, + FloatInfNeg: []byte{'"', '-', 'I', 'n', 'f', '"'}, + } +) + + +func initJSONChars() [utf8.RuneSelf]CharAtt { + var tb = [utf8.RuneSelf]CharAtt{ + '"': CharAttAllUnsafe, + '&': CharAttHtmlUnsafe, + '<': CharAttHtmlUnsafe, + '>': CharAttHtmlUnsafe, + '\\': CharAttAllUnsafe, + } + for i := 0; i <= 31; i++ { + tb[i] = CharAttAllUnsafe + } + return tb +} diff --git a/core/cdcs/cjson/char_att.go b/core/cdcs/cjson/char_att.go new file mode 100644 index 0000000..ba52b37 --- /dev/null +++ b/core/cdcs/cjson/char_att.go @@ -0,0 +1,45 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name char_att.go +// Created by DEV +// Modified 21/04/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package cjson + + +const ( + CharAttUnsafe CharAtt = 1 << iota + CharAttHtmlUnsafe + + CharAttAllUnsafe = CharAttUnsafe | CharAttHtmlUnsafe +) + +type CharAtt uint8 + + + +func (a CharAtt) IsUnsafe() bool { + return a&CharAttUnsafe != 0 } + +func (a CharAtt) IsHtmlUnsafe() bool { + return a&CharAttHtmlUnsafe != 0 } + + + diff --git a/core/cdcs/cjson/writer.go b/core/cdcs/cjson/writer.go new file mode 100644 index 0000000..def6ef1 --- /dev/null +++ b/core/cdcs/cjson/writer.go @@ -0,0 +1,193 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name writer.go +// Created by DEV +// Modified 21/04/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package cjson + +import ( + "codecs/base32" + "codecs/base64" + "math" + "mems" + "strconv" + "time" + "unicode/utf8" +) + + +func WriteString(b *mems.ABuffer, value string, escapeHTML bool ) { + if len(value) == 0 { + b.Write2Byte('"', '"') + return + } + + b.WriteByte('"') + start := 0 + for i := 0; i < len(value); { + if ch := value[i]; ch < utf8.RuneSelf { + + if !G.JSONChars[ch].IsHtmlUnsafe() || (!escapeHTML && !G.JSONChars[ch].IsUnsafe()) { + i++ + continue + } + + if start < i { + b.WriteString(value[start:i]) + } + b.WriteByte('\\') + switch ch { + case '\\', '"': + b.WriteByte(ch) + case '\n': + b.WriteByte('n') + case '\r': + b.WriteByte('r') + case '\t': + b.WriteByte('t') + default: + b.WriteString(`u00`) + b.Write2Byte(G.Hex[ch>>4], G.Hex[ch&0xF]) + } + i++ + start = i + continue + } + c, size := utf8.DecodeRuneInString(value[i:]) + if c == utf8.RuneError && size == 1 { + if start < i { + b.WriteString(value[start:i]) + } + b.WriteString(`\ufffd`) + i += size + start = i + continue + } + + if c == '\u2028' || c == '\u2029' { + if start < i { + b.WriteString(value[start:i]) + } + b.WriteString(`\u202`) + b.WriteByte(G.Hex[c&0xF]) + i += size + start = i + continue + } + i += size + } + if start < len(value) { + b.WriteString(value[start:]) + } + b.WriteByte('"') +} + + + +func WriteUint (b *mems.ABuffer, value uint64 , quoted bool) { + if quoted { + b.WriteByte('"') + } + if value == 0 { + b.WriteByte('0') + } else { + b.WriteUIntStr(value, 10) + } + if quoted { + b.WriteByte('"') + } +} + + +func WriteBool (b *mems.ABuffer, value bool , quoted bool) { + if value { + b.WOQ(quoted,'"', G.TrueValue) + } else { + b.WOQ(quoted,'"', G.FalseValue) + } +} + + +func WriteInt (b *mems.ABuffer, value int64 , quoted bool) { + if quoted { + b.WriteByte('"') + } + if value == 0 { + b.WriteByte('0') + } else { + b.WriteIntStr(value, 10) + } + if quoted { + b.WriteByte('"') + } +} + + +func WriteFloat (b *mems.ABuffer, f float64, bits int, quoted bool) { + var t [64]byte + if math.IsInf(f, 0) || math.IsNaN(f) { + _,_ = b.Write(G.FloatNaN) + return + } + + abs := math.Abs(f) + fm := byte('f') + + if abs != 0 { + if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) { + fm = 'e' + } + } + bf := t[:0] + bf = strconv.AppendFloat(bf, f, fm, -1, int(bits)) + if fm == 'e' { + // clean up e-09 to e-9 + n := len(bf) + if n >= 4 && bf[n-4] == 'e' && bf[n-3] == '-' && bf[n-2] == '0' { + bf[n-2] = bf[n-1] + bf = bf[:n-1] + } + } + + b.WOQ(quoted,'"',bf) +} + + +func WriteDate(b *mems.ABuffer, value time.Time, layout string, quote bool) { + if layout == "" { + layout = time.RFC3339 + } + if quote { + b.WriteByte('"') + } + b.WriteDateStr(value,layout) + if quote { + b.WriteByte('"') + } +} + + +func WriteBase64(b *mems.ABuffer, value []byte) (er error) { + return base64.Write(b,value,G.NullValue,G.EmptyValue,true,'"') } + + +func WriteBase32(b *mems.ABuffer, value []byte) (er error) { + return base32.Write(b,value,G.NullValue,G.EmptyValue,true,'"') } \ No newline at end of file diff --git a/core/cdcs/go.mod b/core/cdcs/go.mod new file mode 100644 index 0000000..f1a9eb0 --- /dev/null +++ b/core/cdcs/go.mod @@ -0,0 +1,3 @@ +module cdcs + +go 1.22 diff --git a/core/crns/active.go b/core/crns/active.go new file mode 100644 index 0000000..c0a2bc6 --- /dev/null +++ b/core/crns/active.go @@ -0,0 +1,66 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name rkey.go +// Created by DEV +// Modified 05/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package crns + +import "errs" + +var ( + + + G = struct { + ErrExpired errs.ErrCode + ErrTimeout errs.ErrCode + ErrIntervalInvalid errs.ErrCode + ErrNotStarted errs.ErrCode + ErrNotPaused errs.ErrCode + ErrAlreadyStarted errs.ErrCode + ErrTransitionInvalid errs.ErrCode + ErrTimerTaskInvalid errs.ErrCode + } { + + ErrExpired: errs.ErrCode("expired"), + ErrTimeout: errs.ErrCode("timeout"), + ErrIntervalInvalid: errs.ErrCode("interval_invalid"), + ErrNotStarted: errs.ErrCode("not_started"), + ErrNotPaused: errs.ErrCode("not_paused"), + ErrAlreadyStarted: errs.ErrCode("already_started"), + ErrTransitionInvalid: errs.ErrCode("transition_invalid"), + ErrTimerTaskInvalid: errs.ErrCode("timer_task_invalid"), + } + + +) + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/crns/chrono.go b/core/crns/chrono.go new file mode 100644 index 0000000..656cee0 --- /dev/null +++ b/core/crns/chrono.go @@ -0,0 +1,108 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name rkey.go +// Created by DEV +// Modified 05/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package crns + +import ( + "sync/atomic" + "time" + +) + +type ( + + + Chrono struct { + started int64 + stopped int64 + } +) + + +func NewChrono(str bool) *Chrono { + ch := &Chrono{} + if str { + ch.Start() + } + return ch +} + + +func (c *Chrono) Started() time.Time { + return time.Unix(0,atomic.LoadInt64(&c.started)) } + + +func (c *Chrono) Stopped() time.Time { + return time.Unix(0,atomic.LoadInt64(&c.stopped)) } + + +func (c *Chrono) Elapsed() time.Duration { + st := atomic.LoadInt64(&c.started) + if st == 0 { + return 0 + } + sp := atomic.LoadInt64(&c.stopped) + if sp == 0 { + return time.Now().Sub(time.Unix(0, int64(st))) + } + return time.Duration(sp - st) +} + + +func (c *Chrono) Reset() { + atomic.StoreInt64(&c.started,0) + atomic.StoreInt64(&c.stopped,0) +} + + +func (c *Chrono) Start() (tm time.Time) { + tm = time.Now() + atomic.CompareAndSwapInt64(&c.started,0,tm.UnixNano()) + return +} + + +func (c *Chrono) Stop() (tm time.Time) { + tm = time.Now() + atomic.CompareAndSwapInt64(&c.stopped,0,tm.UnixNano()) + return +} + + +func (c *Chrono) SetTimes(str, stp time.Time) { + atomic.StoreInt64(&c.started,str.UnixNano()) + atomic.StoreInt64(&c.stopped,str.UnixNano()) +} + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/crns/chronometer.go b/core/crns/chronometer.go new file mode 100644 index 0000000..ac35531 --- /dev/null +++ b/core/crns/chronometer.go @@ -0,0 +1,59 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name rkey.go +// Created by DEV +// Modified 05/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +package crns + +import ( + "time" +) + +type ( + + + Chronometer interface { + + Started() time.Time + + Stopped() time.Time + + Elapsed() time.Duration + + } + +) + + + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/crns/expiration.go b/core/crns/expiration.go new file mode 100644 index 0000000..eeab799 --- /dev/null +++ b/core/crns/expiration.go @@ -0,0 +1,182 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name rkey.go +// Created by DEV +// Modified 05/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package crns + +import ( + "sync/atomic" + "time" + + +) + +type ( + + + Expiration struct { + timer *time.Timer + times Chrono + + state uint32 + source uint32 + timeout int64 + deadline int64 + + expireFn func() + } +) + + +func NewExpiration(duration time.Duration, expirer func()) *Expiration { + ex := &Expiration{ + times: *NewChrono(false), + state: uint32(TimerStateCreated), + source: uint32(ExpirationSourceSelf), + timeout: int64(duration), + expireFn: expirer, + } + if duration > 0 { + atomic.StoreUint32(&ex.source,uint32(ExpirationSourceTimer)) + } + return ex +} + + + +func (e *Expiration) Reset() { + e.times.Reset() + atomic.StoreUint32(&e.state ,uint32(TimerStateCreated)) + atomic.StoreUint32(&e.source,uint32(ExpirationSourceSelf)) + atomic.StoreInt64 (&e.timeout ,0) + atomic.StoreInt64 (&e.deadline,0) + if e.timer != nil { + if !e.timer.Stop() { + select { + case <- e.timer.C: + default: + } + } + } +} + + + +func (e *Expiration) State() TimerState { + return TimerState(atomic.LoadUint32(&e.state)) } + + + +func (e *Expiration) Chono() Chronometer { + return &e.times } + + +func (e *Expiration) Source() ExpirationSource { + return ExpirationSource(atomic.LoadUint32(&e.source)) } + + + +func (e *Expiration) Timeout() time.Duration { + return time.Duration(atomic.LoadInt64(&e.timeout)) } + + +func (e *Expiration) Deadline() time.Time { + return time.Unix(0,atomic.LoadInt64(&e.deadline)) } + + + +func (e *Expiration) Start(expirer Expirer) error { + if !atomic.CompareAndSwapUint32(&e.state,uint32(TimerStateCreated),uint32(TimerStateStarted)) { + return G.ErrAlreadyStarted + } + + st := e.times.Start() + to := time.Duration(atomic.LoadInt64(&e.timeout)) + dl := st.Add(to) + + if expirer != nil { + pd, ph := expirer.Deadline() + if ph { + if pd.Before(st) { + atomic.StoreUint32(&e.state ,uint32(TimerStateExpired)) + atomic.StoreUint32(&e.source,uint32(ExpirationSourceParent)) + return G.ErrExpired + } + if pd.Before(dl) { + atomic.StoreInt64 (&e.deadline,pd.UnixNano()) + atomic.StoreUint32(&e.source ,uint32(ExpirationSourceParent)) + return nil + } + } + } + + if atomic.LoadUint32(&e.source) == uint32(ExpirationSourceTimer) { + atomic.StoreInt64 (&e.deadline,dl.UnixNano()) + if e.timer == nil { + e.timer = time.NewTimer(to) + } else { + e.timer.Reset(to) + } + go func(ex *Expiration) { + select { + case <-ex.timer.C: + atomic.StoreUint32(&ex.state,uint32(TimerStateExpired)) + ex.times.Stop() + if ex.expireFn != nil { + ex.expireFn() + } + return + } + }(e) + + + } + + return nil +} + + +func (e *Expiration) Stop() error { + if !atomic.CompareAndSwapUint32(&e.state,uint32(TimerStateStarted), uint32(TimerStateStopped)) { + return G.ErrNotStarted + } + e.times.Stop() + if e.timer != nil && !e.timer.Stop() { + select { + case <-e.timer.C: + } + } + return nil +} + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/crns/expiration_source.go b/core/crns/expiration_source.go new file mode 100644 index 0000000..54a5a30 --- /dev/null +++ b/core/crns/expiration_source.go @@ -0,0 +1,62 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name rkey.go +// Created by DEV +// Modified 05/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package crns + +const ( + + //ExpirationSource + + ExpirationSourceSelf ExpirationSource = iota + ExpirationSourceParent + ExpirationSourceTimer +) + +type ( + + ExpirationSource uint32 +) + + +func (c ExpirationSource) String() string { + switch c { + case ExpirationSourceSelf : return "self" + case ExpirationSourceParent : return "parent" + case ExpirationSourceTimer : return "timer" + default: + return "unknown" + } +} + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/crns/expirer.go b/core/crns/expirer.go new file mode 100644 index 0000000..7614530 --- /dev/null +++ b/core/crns/expirer.go @@ -0,0 +1,57 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name rkey.go +// Created by DEV +// Modified 05/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package crns + +import ( + "time" +) + +type ( + + + Expirer interface { + + Deadline() (time.Time, bool) + } + + + DeadlineFnc func() (time.Time, bool) +) + + +func (f DeadlineFnc) Deadline() (time.Time, bool) { + return f() } + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/crns/go.mod b/core/crns/go.mod new file mode 100644 index 0000000..a4e6667 --- /dev/null +++ b/core/crns/go.mod @@ -0,0 +1,4 @@ +module crns + + +go 1.20 \ No newline at end of file diff --git a/core/crns/pulsar.go b/core/crns/pulsar.go new file mode 100644 index 0000000..3e21088 --- /dev/null +++ b/core/crns/pulsar.go @@ -0,0 +1,169 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name rkey.go +// Created by DEV +// Modified 05/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package crns + +import ( + "context" + "ctxs" + "sync/atomic" + "time" +) + +type ( + + + Pulsar struct { + state uint32 + pulse int64 + err atomic.Value + cancel ctxs.Cancel + workFn PulsarWorkFnc + } + + + PulsarWorkFnc func(ctx context.Context) error + +) + + +func NewPulsar(pulse time.Duration, work PulsarWorkFnc) *Pulsar { + return &Pulsar{ + state: uint32(TimerStateCreated), + cancel: *ctxs.NewCancel(), + pulse: int64(pulse), + workFn: work, + } +} + + +func (p *Pulsar) State() TimerState { + return TimerState(atomic.LoadUint32(&p.state)) } + + +func (p *Pulsar) Pulse() time.Duration { + return time.Duration(atomic.LoadInt64(&p.pulse)) } + + +func (p *Pulsar) Err() error { + if v := p.err.Load(); v != nil { + return v.(error) + } + return nil +} + + +func (p *Pulsar) Start(ctx context.Context) error { + if !atomic.CompareAndSwapUint32(&p.state,uint32(TimerStateCreated),uint32(TimerStateStarted)) { + return G.ErrAlreadyStarted + } + to := atomic.LoadInt64(&p.pulse) + if to <= 0 { + atomic.StoreUint32(&p.state,uint32(TimerStateExpired)) + return G.ErrIntervalInvalid + } + + cx := ctx + if cx == nil { + cx = context.Background() + } else if ctx.Err() != nil { + atomic.StoreUint32(&p.state,uint32(TimerStateCanceled)) + return context.Canceled + } + + go func(pl *Pulsar, tk *time.Ticker, cx context.Context) { + EXIT: + for { + select { + case <-cx.Done(): + atomic.StoreUint32(&pl.state,uint32(TimerStateCanceled)) + break EXIT + + case <-pl.cancel.Done(): + break EXIT + + case <-tk.C: + if TimerState(atomic.LoadUint32(&pl.state)) == TimerStateStarted { + if er := pl.workFn(cx); er != nil { + pl.err.Store(er) + atomic.StoreUint32(&pl.state,uint32(TimerStateCanceled)) + break EXIT + } + } + } + } + tk.Stop() + pl.cancel.Cancel() + + }(p, time.NewTicker(time.Duration(to)), cx) + + return nil +} + + +func (p *Pulsar) Stop() error { + if atomic.CompareAndSwapUint32(&p.state,uint32(TimerStateStarted), uint32(TimerStateStopped)) || + atomic.CompareAndSwapUint32(&p.state,uint32(TimerStatePaused), uint32(TimerStateStopped)) { + p.cancel.Cancel() + return nil + } + return G.ErrNotStarted +} + + +func (p *Pulsar) Pause() error { + if atomic.CompareAndSwapUint32(&p.state,uint32(TimerStateStarted), uint32(TimerStatePaused)) { + return nil + } + return G.ErrNotStarted +} + + +func (p *Pulsar) Continue() error { + if atomic.CompareAndSwapUint32(&p.state,uint32(TimerStatePaused), uint32(TimerStateStarted)) { + return nil + } + return G.ErrNotPaused +} + + +func (p *Pulsar) Done() <-chan struct{} { + return p.cancel.Done() } + + +func (p *Pulsar) Wait() { + <-p.cancel.Done() } + + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/crns/time_task.go b/core/crns/time_task.go new file mode 100644 index 0000000..2096221 --- /dev/null +++ b/core/crns/time_task.go @@ -0,0 +1,48 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name rkey.go +// Created by DEV +// Modified 05/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package crns + +import ( + "context" + "time" +) + +type ( + + + TimeTaskFnc func(now time.Time, ctx context.Context) +) + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/crns/timer_queue.go b/core/crns/timer_queue.go new file mode 100644 index 0000000..d06aa87 --- /dev/null +++ b/core/crns/timer_queue.go @@ -0,0 +1,188 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name rkey.go +// Created by DEV +// Modified 05/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package crns + +import ( + "container/heap" + "context" + "opts" + "sync/atomic" + "time" +) + +const ( + timerQueueLen = 4096 + timerQueueTime = time.Hour * 86400 +) + +type ( + + + TimerQueue struct { + heap TimerTaskHeap + state uint32 + + pushCh chan *TimerTask + ctx context.Context + ctxCancelFn context.CancelFunc + + nextTask *time.Time + timer *time.Timer + } + + +) + + +func NewTimerQueue(options ... opts.GOptionFnc[TimerQueue]) *TimerQueue { + tq := &TimerQueue{ + heap : TimerTaskHeap{}, + state: uint32(TimerStateCreated), + } + heap.Init(&tq.heap) + opts.GApply(tq, options ...) + if tq.pushCh == nil { + tq.pushCh = make(chan *TimerTask, timerQueueLen) + } + return tq +} + + +func (q *TimerQueue) State() TimerState { + return TimerState(atomic.LoadUint32(&q.state)) } + + +func (q *TimerQueue) Start(ctx context.Context) error { + if !atomic.CompareAndSwapUint32(&q.state,uint32(TimerStateCreated),uint32(TimerStateStarted)) { + // error already started + return G.ErrAlreadyStarted + } + if q.timer == nil { + q.timer = time.NewTimer(timerQueueTime) + } else { + q.timer.Reset(timerQueueTime) + } + + q.ctx, q.ctxCancelFn = context.WithCancel(ctx) + go func(qu *TimerQueue, cx context.Context) { + ts := make([]*TimerTask, 0, 10) + EXIT: + for { + select { + //-- + case <-cx.Done(): + atomic.CompareAndSwapUint32(&qu.state,uint32(TimerStateStarted),uint32(TimerStateCanceled)) + break EXIT + //-- + case nw := <-qu.timer.C: + ts = ts[:0] + for ix, ln := 0, qu.heap.Len(); ix < ln; ix++ { + pk := qu.heap[0] + if pk.RunAt.Before(nw) { + pp := heap.Pop(&qu.heap).(*TimerTask) + ts = append(ts, pp) + continue + } + break + } + + if len(ts) > 0 { + go func(tm time.Time, tk []*TimerTask) { + for _, tt := range tk { + tt.TaskFn(tm, ctx) + } + }(nw, ts) + } + + if qu.heap.Len() > 0 { + nr := qu.heap[0].RunAt + qu.nextTask = &nr + qu.timer.Reset(nr.Sub(time.Now())) + } else { + qu.timer.Stop() + qu.nextTask = nil + } + //-- + case tt := <-q.pushCh: + heap.Push(&q.heap, tt) + if qu.nextTask == nil || qu.nextTask.After(tt.RunAt) { + if qu.nextTask != nil && !qu.timer.Stop() { + <-qu.timer.C + } + qu.timer.Reset(tt.RunAt.Sub(time.Now())) + qu.nextTask = &tt.RunAt + } + } + } + + if !q.timer.Stop() { + <-qu.timer.C + } + qu.heap.Reset() + + }(q, q.ctx) + + return nil +} + + +func (q *TimerQueue) Stop() error { + if atomic.CompareAndSwapUint32(&q.state,uint32(TimerStateStarted),uint32(TimerStateCanceled)) { + q.ctxCancelFn() + return nil + } + return G.ErrNotStarted +} + + +func (q *TimerQueue) Push(runAt time.Time, task TimeTaskFnc) error { + switch { + case runAt.Before(time.Now()): + return G.ErrExpired + case task == nil: + return G.ErrTimerTaskInvalid + case TimerState(atomic.LoadUint32(&q.state)) != TimerStateStarted: + return G.ErrNotStarted + default: + select { + case q.pushCh <- NewTimerTask(runAt, task): + return nil + case <-q.ctx.Done(): + return context.Canceled + } + } +} + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/crns/timer_state.go b/core/crns/timer_state.go new file mode 100644 index 0000000..9fe9e0e --- /dev/null +++ b/core/crns/timer_state.go @@ -0,0 +1,81 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name rkey.go +// Created by DEV +// Modified 05/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package crns + +const ( + + //Enum values for TimerState + TimerStateCreated TimerState = 1 << iota + TimerStateStarted + TimerStatePaused + TimerStateExpired + TimerStateStopped + TimerStateCanceled + + timerStateActive = TimerStateStarted + TimerStatePaused +) + +type ( + + + TimerState uint32 +) + + + +func (t TimerState) String() string { + switch t { + case TimerStateCreated: + return "created" + case TimerStateStarted: + return "started" + case TimerStatePaused: + return "paused" + case TimerStateExpired: + return "expired" + case TimerStateStopped: + return "stopped" + case TimerStateCanceled: + return "canceled" + default: + return "unknown" + } +} + + +func (t TimerState) IsActive() bool { + return t != timerStateActive } + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/crns/timer_task.go b/core/crns/timer_task.go new file mode 100644 index 0000000..24f5c49 --- /dev/null +++ b/core/crns/timer_task.go @@ -0,0 +1,60 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name rkey.go +// Created by DEV +// Modified 05/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +package crns + +import ( + "time" +) + +type ( + + + TimerTask struct { + + RunAt time.Time + TaskFn TimeTaskFnc + } +) + + +func NewTimerTask(runAt time.Time, task TimeTaskFnc) *TimerTask { + return &TimerTask{ + RunAt: runAt, + TaskFn: task, + } +} + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/crns/timer_task_heap.go b/core/crns/timer_task_heap.go new file mode 100644 index 0000000..326e7c2 --- /dev/null +++ b/core/crns/timer_task_heap.go @@ -0,0 +1,89 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name rkey.go +// Created by DEV +// Modified 05/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package crns + +type ( + + + TimerTaskHeap []*TimerTask +) + + +func (h *TimerTaskHeap) Reset() { + *h = (*h)[:0] } + + +func (h *TimerTaskHeap) PushTimerTask(ele *TimerTask) { + if ele != nil { + *h = append(*h, ele) + } +} + +func (h *TimerTaskHeap) PopTimerTask() *TimerTask { + th := *h + if ln := len(th); ln > 0 { + tt := th[ln-1] + *h = th[:ln-1] + return tt + } + return nil +} + + +func (h *TimerTaskHeap) Push(ele interface{}) { + h.PushTimerTask(ele.(*TimerTask)) } + + +func (h *TimerTaskHeap) Pop() interface{} { + return h.PopTimerTask() } + + +func (h TimerTaskHeap) Len() int { + return len(h) } + + +func (h TimerTaskHeap) Less(i, j int) bool { + return h[i].RunAt.Before(h[j].RunAt) } + + +func (h TimerTaskHeap) Swap(i, j int) { + h[i], h[j] = h[j], h[i] } + + + + + + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/crps/active.go b/core/crps/active.go new file mode 100644 index 0000000..f980072 --- /dev/null +++ b/core/crps/active.go @@ -0,0 +1,35 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name gogo.go +// Created by DEV +// Modified 16/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package crypts + +import "errs" + +var ( + + G = struct { + ErrNotImplemented errs.ErrCode + }{ + ErrNotImplemented:errs.ErrCode("crypter-not-implemented"), + } +) \ No newline at end of file diff --git a/core/crps/crypter.go b/core/crps/crypter.go new file mode 100644 index 0000000..768b461 --- /dev/null +++ b/core/crps/crypter.go @@ -0,0 +1,35 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name crypter.go +// Created by DEV +// Modified 16/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package crypts + + +type ( + + Crypter interface { + Encrypter + Decrypter + } +) + + diff --git a/core/crps/decrypter.go b/core/crps/decrypter.go new file mode 100644 index 0000000..e46a6d4 --- /dev/null +++ b/core/crps/decrypter.go @@ -0,0 +1,43 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name decrypter.go +// Created by DEV +// Modified 16/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package crypts + +import "results" + +type ( + + Decrypter interface { + Decrypt (data []byte) results.Bytes + } + + + DecrypterNop struct {} + +) + + + +func (_ DecrypterNop) Decrypt (_ []byte) results.Bytes { + return results.MakeBytesError(G.ErrNotImplemented) } + diff --git a/core/crps/encrypter.go b/core/crps/encrypter.go new file mode 100644 index 0000000..7f45e8b --- /dev/null +++ b/core/crps/encrypter.go @@ -0,0 +1,42 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name encrypter.go +// Created by DEV +// Modified 16/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package crypts + +import "results" + +type ( + + + Encrypter interface { + Encrypt (data []byte) results.Bytes + } + + + + EncrypterNop struct {} +) + + +func (_ EncrypterNop) Encrypt (_ []byte) results.Bytes { + return results.MakeBytesError(G.ErrNotImplemented) } \ No newline at end of file diff --git a/core/crps/go.mod b/core/crps/go.mod new file mode 100644 index 0000000..9df0914 --- /dev/null +++ b/core/crps/go.mod @@ -0,0 +1,4 @@ +module crps + + +go 1.20 diff --git a/core/ctxs/cancel.go b/core/ctxs/cancel.go new file mode 100644 index 0000000..4c3e918 --- /dev/null +++ b/core/ctxs/cancel.go @@ -0,0 +1,76 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name rkey.go +// Created by DEV +// Modified 05/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +package ctxs + +import "sync/atomic" + +type ( + + + Cancel struct { + active uint32 + doneCh chan struct{} + } +) + + +func NewCancel() *Cancel { + return &Cancel{ + active: 1, + doneCh: make(chan struct{}), + } +} + + +func (c *Cancel) Cancel() { + if atomic.CompareAndSwapUint32(&c.active,1,0) { + close(c.doneCh) + } +} + + +func (c *Cancel) Done() <-chan struct{} { + return c.doneCh } + + +func (c *Cancel) IsDone() bool { + return atomic.LoadUint32(&c.active) == 1 } + + +func (c *Cancel) Wait() { + <-c.doneCh } + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/ctxs/go.mod b/core/ctxs/go.mod new file mode 100644 index 0000000..4eb489b --- /dev/null +++ b/core/ctxs/go.mod @@ -0,0 +1,3 @@ +module ctxs + +go 1.22 diff --git a/core/dtes/active.go b/core/dtes/active.go new file mode 100644 index 0000000..dbe3b62 --- /dev/null +++ b/core/dtes/active.go @@ -0,0 +1,83 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name gogo.go +// Created by DEV +// Modified 21/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package dates + +import "errs" + +const( + + secondsDay = 24 * 60 * 60 + +) + + +var ( + + G = struct { + + ErrInvalidDateRange errs.ErrCode + }{ + + ErrInvalidDateRange : errs.ErrCode ("invalid-date-range"), + } + +) + + + + +func IsYearLeap (year int) bool { + return year%4 == 0 && (year%100 != 0 || year%400 == 0) } + + +func DaysInYear (year int) int { + if IsYearLeap(year) { + return 366 } + return 365 +} + + +func DaysIn (year, month int) int { + if month <= 0 || month > 12 { + return 0 } + d := [12]int{ 31,28,31,30,31,30,31,30,31,30,31 } + if month == 2 && IsYearLeap(year) { + return 29 } + return d[month] +} + + +func DayOfWeek (year, month, day int) int { + if month < 3 { + month += 12 + year-- + } + J := year / 100 + K := year % 100 + h := (day + (13*(month+1))/5 + K + K/4 + J/4 + 5*J) % 7 + if h <= 1 { + return h+6 + } + return h-1 +} diff --git a/core/dtes/bdates/active.go b/core/dtes/bdates/active.go new file mode 100644 index 0000000..d4fbf23 --- /dev/null +++ b/core/dtes/bdates/active.go @@ -0,0 +1,55 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name gogo.go +// Created by DEV +// Modified 21/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package bdates + +import "errs" + +const( + + minBYear int = 1900 + maxBYear int = 2155 +) + +var ( + + + G = struct { + ErrInvalidDay Err + ErrInvalidMonth Err + ErrInvalidYear Err + }{ + ErrInvalidDay : Err{errs.ErrCode("invalid-day")}, + ErrInvalidMonth : Err{errs.ErrCode("invalid-month")}, + ErrInvalidYear : Err{errs.ErrCode("invalid-year")}, + } +) + + +func checkDayNumber (day int) bool { + return day >=1 && day <=7 } + + +func checkMonthNumber(month int) bool { + return month >=1 && month <=12 } + diff --git a/core/dtes/bdates/bmonth.go b/core/dtes/bdates/bmonth.go new file mode 100644 index 0000000..2335813 --- /dev/null +++ b/core/dtes/bdates/bmonth.go @@ -0,0 +1,34 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name bmonth.go +// Created by DEV +// Modified 21/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package bdates + + + +type ( + + BMonth uint32 +) + + + diff --git a/core/dtes/bdates/bweek.go b/core/dtes/bdates/bweek.go new file mode 100644 index 0000000..cfd1690 --- /dev/null +++ b/core/dtes/bdates/bweek.go @@ -0,0 +1,125 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name bweek.go +// Created by DEV +// Modified 21/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package bdates + +import "math/bits" + +const( + + BWeekDaysMon BWeekDays = 1 << iota + BWeekDaysTue + BWeekDaysWed + BWeekDaysThu + BWeekDaysFri + BWeekDaysSat + BWeekDaysSun + + _BWeekFlag + + BWeekDaysAll = 0x1111111 + + +) + +type ( + + // BWeekDays + // Type: uint8 + // Desc: Representa una lista de los dias de la semana + // a través de un byte + BWeekDays uint8 + +) + + +func (w BWeekDays) GetFlag() bool { + return w&_BWeekFlag==_BWeekFlag } + + +func (w BWeekDays) SetFlag(val bool) BWeekDays { + if val { + return w|_BWeekFlag + } + return w&^_BWeekFlag +} + + + + +func (w BWeekDays) SetDay (num int, val bool) BWeekDays { + if num < 0 || num > 7 { + return w + } + if val { + w |= 1 << num-1 + } else { + w &^= 1 << num-1 + } + return w +} + + +func (w BWeekDays) GetDay (num int) bool { + if num < 0 || num > 7 { + return false + } + c := BWeekDays(1 << num-1) + return (w&c)==c +} + + +func (w BWeekDays) Invert () BWeekDays { + return ^w } + + +func (w BWeekDays) Count () int { + return bits.OnesCount8(uint8(w)) } + + +func (w BWeekDays) List () []int { + c := BWeekDays(1) + r := make([]int,0,7) + for i:=1; i<=7; i++ { + if c&w == c { + r = append(r,i) + } + c <<=1 + } + return r +} + + +func (w BWeekDays) ToSlice () []bool { + c := BWeekDays(1) + r := make([]bool,7) + for i:=0; i<7; i++ { + r[i]=c&w == c + c <<=1 + } + return r +} + + + +func (w BWeekDays) Common (dst BWeekDays) BWeekDays { return w & dst } diff --git a/core/dtes/bdates/byear.go b/core/dtes/bdates/byear.go new file mode 100644 index 0000000..3491d1a --- /dev/null +++ b/core/dtes/bdates/byear.go @@ -0,0 +1,128 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name byear.go +// Created by DEV +// Modified 21/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package bdates + +import "times" + +type ( + + BYear struct { + atts BYearAtt + first byte + year byte + months [12]BMonth + } + + +) + + + +func NewBYear (year int) *BYear { + if year < minBYear || year > maxBYear { + panic(G.ErrInvalidYear) + } + at := BYearAtt(BYearAttSet) + if dates.IsYearLeap(year) { + at|=BYearAttLeap + } + return &BYear { + atts : at, + first: byte(dates.DayOfWeek(year,1,1)), + year : byte(year-1900), + } +} + + +func (y *BYear) Atts () BYearAtt { + return y.atts } + +func (y *BYear) First () int { + return int(y.first) } + +func (y *BYear) Year () int { + return minBYear + int(y.year) } + + +func (y *BYear) Clear (month ...int) { + if len(month) == 0 { + for i := 0; i < 12; i++ { + y.months[i] = 0 + } + return + } + for _,i := range month { + if !checkMonthNumber(i){ + panic(G.ErrInvalidMonth) + } + y.months[i]=0 + } +} + + +func (y *BYear) GetDay (month, day int) bool { + if !checkMonthNumber(month) { + panic(G.ErrInvalidMonth ) + } + if day < 1 || day > y.daysInMonth(month) { + panic(G.ErrInvalidDay) + } + return (uint32(1 << day) & uint32(y.months[month])) != 0 +} + +func (y *BYear) SetDay (month, day int, active bool) { + if !checkMonthNumber(month) { + panic(G.ErrInvalidMonth ) + } + if day < 1 || day > y.daysInMonth(month) { + panic(G.ErrInvalidDay) + } + month-=1 + if active { + y.months[month] = y.months[month] | BMonth(1 << day) + return + } + y.months[month] = y.months[month] &^ BMonth(1 << day) +} + + + +func (y *BYear) GetMonth (month int) BMonth { + if !checkMonthNumber(month) { + panic(G.ErrInvalidMonth) + } + return y.months[month-1] +} + + + + + +func (y BYear) daysInMonth (month int) int { + d := [12]int{ 31,28,31,30,31,30,31,30,31,30,31 } + if month == 2 && y.Atts().IsLeap() { + return 29 + } + return d[month-1] +} diff --git a/core/dtes/bdates/byear_att.go b/core/dtes/bdates/byear_att.go new file mode 100644 index 0000000..a02ea4c --- /dev/null +++ b/core/dtes/bdates/byear_att.go @@ -0,0 +1,51 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name byear_att.go +// Created by DEV +// Modified 21/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package bdates + + +const( + + BYearAttSet BYearAtt = iota << 1 + BYearAttLeap + +) + + +type BYearAtt byte + + +func (a BYearAtt) IsSet () bool { + return a&BYearAttSet != 0 } + + +func (a BYearAtt) IsLeap () bool { + return a&BYearAttLeap != 0 } + + + + + + + + diff --git a/core/dtes/bdates/err.go b/core/dtes/bdates/err.go new file mode 100644 index 0000000..b5a511a --- /dev/null +++ b/core/dtes/bdates/err.go @@ -0,0 +1,33 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name err_bdates.go +// Created by DEV +// Modified 20/04/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package bdates + +import "errs" + +type ( + + Err struct { errs.ErrCode } +) + + diff --git a/core/dtes/date_days.go b/core/dtes/date_days.go new file mode 100644 index 0000000..711c7c1 --- /dev/null +++ b/core/dtes/date_days.go @@ -0,0 +1,102 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name days.go +// Created by DEV +// Modified 21/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package dates + +import "time" + + +type ( + + DateDays int32 + +) + + + + +func (d DateDays) AddDate(years, months, days int) DateDays { + return TimeToDays(d.ToTime().AddDate(years,months,days)) } + + +func (d DateDays) ToTime() time.Time { + return DaysToTime(d) } + +func (d DateDays) Before (days DateDays) bool { + return d < days } + +func (d DateDays) After (days DateDays) bool { + return d > days } + +func (d DateDays) Compare(days DateDays) int { + if d < days { + return -1 } + if d == days { + return 0 } + return 1 +} + +func (d DateDays) Min (days DateDays) DateDays { + if d > days { + return days + } + return d +} + +func (d DateDays) Max (days DateDays) DateDays { + if d < days { + return days + } + return d +} + + + + + + +func TimeToDays (time time.Time) DateDays { + _,x := time.Zone() + s := time.Unix() + int64(x) + if s >= 0 { + return DateDays(s/ secondsDay) } + return -DateDays((secondsDay -1 -s)/ secondsDay) +} + + +func DaysToTime(days DateDays) time.Time { + return time.Unix(int64(days) *secondsDay,0).UTC() } + + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/dtes/date_days_range.go b/core/dtes/date_days_range.go new file mode 100644 index 0000000..3417350 --- /dev/null +++ b/core/dtes/date_days_range.go @@ -0,0 +1,94 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name date_days_range.go +// Created by DEV +// Modified 21/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package dates + +type ( + + DateDaysRange struct { + Start DateDays + End DateDays + } + + + DateDaysRangeFnc func(daysRange *DateDaysRange) +) + +func NewDateRange (options ...DateDaysRangeFnc) *DateDaysRange { + dr := &DateDaysRange{} + for _,o := range options { + o(dr) + } + return dr +} + + + + + +func (r DateDaysRange) IsZero () bool { + return r.End-r.Start <= 0 } + + +func (r DateDaysRange) Size () DateDays { + return DateDays(r.End -r.Start) } + + +func (r DateDaysRange) Contains (days DateDays) bool { + if r.IsZero() { + return false } + return r.Start < days && r.End > days +} + + +func (r DateDaysRange) ContainsRange (drange DateDaysRange) bool { + if r.IsZero() { + return false } + return r.Start > drange.Start && r.End < drange.End +} + + +func (r DateDaysRange) IsRangeOverlap (drange DateDaysRange) bool { + if r.IsZero() { + return false } + if r.Start == drange.Start || r.Start == drange.End || r.End == drange.End { + return true } + if r.Start > drange.Start { + return drange.End < r.End + } + return r.End > drange.Start +} + + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/dtes/duration_formatter.go b/core/dtes/duration_formatter.go new file mode 100644 index 0000000..eab99e1 --- /dev/null +++ b/core/dtes/duration_formatter.go @@ -0,0 +1,83 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name rkey.go +// Created by DEV +// Modified 05/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +package dates + +import ( + "strconv" + "time" +) + +type ( + + + DurationFormatter interface { + + FormatDuration (dur time.Duration, dst []byte) []byte + } + + + FormatDurationFnc func (dur time.Duration, dst []byte) []byte + +) + + +func (f FormatDurationFnc) FormatDuration (dur time.Duration, dst []byte) []byte { + return f(dur,dst) } + + +func WrapDurationFormatterQuoted (dfm DurationFormatter, qte byte) DurationFormatter { + return FormatDurationFnc(func(tme time.Duration, dst []byte) []byte { + dst = append(dst, qte) + dst = dfm.FormatDuration(tme, dst) + return append(dst, qte) + }) +} + + +func DurationMillis (dur time.Duration, dst []byte) []byte { + return strconv.AppendFloat(dst, float64(dur)/float64(time.Millisecond), 'f', -1, 64) } + + + +func DurationNanos(dur time.Duration, dst []byte) []byte { + return strconv.AppendInt(dst, int64(dur), 10) } + + + +func DurationSecs(dur time.Duration, dst []byte) []byte { + return strconv.AppendFloat(dst, float64(dur)/float64(time.Second), 'f', -1, 64) } + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/dtes/go.mod b/core/dtes/go.mod new file mode 100644 index 0000000..b555897 --- /dev/null +++ b/core/dtes/go.mod @@ -0,0 +1,5 @@ +module dtes + + + +go 1.20 \ No newline at end of file diff --git a/core/dtes/time_formatter.go b/core/dtes/time_formatter.go new file mode 100644 index 0000000..90ffaaa --- /dev/null +++ b/core/dtes/time_formatter.go @@ -0,0 +1,145 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name rkey.go +// Created by DEV +// Modified 05/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +package dates + +import ( + "strconv" + "time" +) + +type ( + + + TimeFormatter interface { + + FormatTime (tme time.Time, dst []byte) []byte + } + + + FormatTimeFnc func (tme time.Time, dst []byte) []byte + +) + + +func (f FormatTimeFnc) FormatTime (tme time.Time, dst []byte) []byte { + return f(tme,dst) } + + + + +func WrapTimeFormatterQuoted (tmf TimeFormatter, qte byte) TimeFormatter { + return FormatTimeFnc(func(tme time.Time, dst []byte) []byte { + dst = append(dst, qte) + dst = tmf.FormatTime(tme, dst) + return append(dst, qte) + }) +} + + +func TimeRFC3339Nano(tme time.Time, dst []byte) []byte { + return tme.AppendFormat(dst, time.RFC3339Nano) } + + +func TimeANSIC(tme time.Time, dst []byte) []byte { + return tme.AppendFormat(dst, time.ANSIC) } + + +func TimeUnixDate(tme time.Time, dst []byte) []byte { + return tme.AppendFormat(dst, time.UnixDate) } + + +func TimeRubyDate(tme time.Time, dst []byte) []byte { + return tme.AppendFormat(dst, time.RubyDate) } + + +func TimeRFC822(tme time.Time, dst []byte) []byte { + return tme.AppendFormat(dst, time.RFC822) } + + +func TimeRFC822Z(tme time.Time, dst []byte) []byte { + return tme.AppendFormat(dst, time.RFC822Z) } + + +func TimeRFC850(tme time.Time, dst []byte) []byte { + return tme.AppendFormat(dst, time.RFC850) } + + +func TimeRFC1123(tme time.Time, dst []byte) []byte { + return tme.AppendFormat(dst, time.RFC1123) } + + +func TimeRFC1123Z(tme time.Time, dst []byte) []byte { + return tme.AppendFormat(dst, time.RFC1123Z) } + + +func TimeRFC3339(tme time.Time, dst []byte) []byte { + return tme.AppendFormat(dst, time.RFC3339) } + + +func TimeKitchen(tme time.Time, dst []byte) []byte { + return tme.AppendFormat(dst, time.Kitchen) } + + +func TimeISO8601(tme time.Time, dst []byte) []byte { + return tme.AppendFormat(dst, "2006-01-02T15:04:05.000Z0700") } + + + +func TimeEpoch(tme time.Time, dst []byte) []byte { + return strconv.AppendFloat(dst, float64(tme.UnixNano())/float64(time.Second), 'f', -1, 64) } + + +func TimeEpochMillis(tme time.Time, dst []byte) []byte { + return strconv.AppendFloat(dst, float64(tme.UnixNano())/float64(time.Millisecond), 'f', -1, 64) } + + +func TimeStamp(tme time.Time, dst []byte) []byte { + return tme.AppendFormat(dst, time.Stamp) } + + +func TimeStampMilli(tme time.Time, dst []byte) []byte { + return tme.AppendFormat(dst, time.StampMilli) } + + +func TimeStampMicro(tme time.Time, dst []byte) []byte { + return tme.AppendFormat(dst, time.StampMicro) } + + +func TimeStampNano(tme time.Time, dst []byte) []byte { + return tme.AppendFormat(dst, time.StampNano) } + + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/iosys/ansi/active.go b/core/iosys/ansi/active.go new file mode 100644 index 0000000..328cf06 --- /dev/null +++ b/core/iosys/ansi/active.go @@ -0,0 +1,140 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File n active.go +// Created by DEV +// Modified 05/04/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package ansi + +import ( + "bytes" +) + + +const ( + + styleAttsStart Code = 1024 + + bgMask Code = 0b1111110000011111 + fgMask Code = 0b1111111111100000 + clMask Code = 0b0000001111111111 + txMask Code = 0b1111110000000000 + bgShift int = 5 + stShift int = 10 + styleNumOps int = 3 + +) + + +var ( + + g = struct { + beginEscIni []byte + beginEscEnd []byte + endEsc []byte + charsEscs []byte + endEscStr string + + ics []struct { n []byte; f []byte; b []byte } + itx []struct { n []byte; s []byte } + }{ + + beginEscIni : []byte("\x1b["), + beginEscEnd : []byte{'m'}, + endEsc : []byte("\x1b[0m"), + endEscStr : "\x1b[0m", + + ics : []struct { n []byte; f []byte; b []byte } { + {[]byte("none"), []byte{},[]byte{}}, + {[]byte("black"), []byte{'3','0'},[]byte{'4','0'}}, + {[]byte("red"), []byte{'3','1'},[]byte{'4','1'}}, + {[]byte("green"), []byte{'3','2'},[]byte{'4','2'}}, + {[]byte("yellow"), []byte{'3','3'},[]byte{'4','3'}}, + {[]byte("blue"), []byte{'3','4'},[]byte{'4','4'}}, + {[]byte("magenta"), []byte{'3','5'},[]byte{'4','5'}}, + {[]byte("cyan"), []byte{'3','6'},[]byte{'4','6'}}, + {[]byte("white"), []byte{'3','7'},[]byte{'4','7'}}, + {[]byte("hblack"), []byte{'9','0'},[]byte{'1','0','0'}}, + {[]byte("hred"), []byte{'9','1'},[]byte{'1','0','1'}}, + {[]byte("hgreen"), []byte{'9','2'},[]byte{'1','0','2'}}, + {[]byte("hyellow"), []byte{'9','3'},[]byte{'1','0','3'}}, + {[]byte("hblue"), []byte{'9','4'},[]byte{'1','0','4'}}, + {[]byte("hmagent"), []byte{'9','5'},[]byte{'1','0','5'}}, + {[]byte("hcyan"), []byte{'9','6'},[]byte{'1','0','6'}}, + {[]byte("hwhite"), []byte{'9','7'},[]byte{'1','0','7'}}, + {[]byte("default"), []byte{'3','7'},[]byte{'4','9'}}, + }, + + itx : []struct { n []byte; s []byte }{ + {[]byte("bold-on"), []byte{'1'}}, + {[]byte("underline-on"), []byte{'4'}}, + {[]byte("blink-on"), []byte{'5'}}, + {[]byte("bold-off"), []byte{'2','2'}}, + {[]byte("underline-off"),[]byte{'2','5'}}, + {[]byte("blink-off"), []byte{'2','7'}}, + }, + + charsEscs : genCharEscapes(), + } + +) + + +func genCharEscapes () []byte { + r := make([]byte,255) + r['@']=1 + for i:=int('A'); i<=int('Z'); i++ { + r[i]=1 + r[i+32]=1 + } + return r +} + + +func Esc (code Code) string { + return code.Begin() } + +func EscEnd () string { + return g.endEscStr } + + +func FilterEscapes (data []byte) []byte { + var buf bytes.Buffer + + for i := 0; i < len(data); { + if data[i] != 0x1b { + buf.WriteByte(data[i]) + i++ + continue + } + // Si encuentra una secuencia de escape, salta hasta encontrar un carácter alfabético. + next := i + 1 + for next < len(data) && g.charsEscs[data[next]] == 0 { + next++ + } + i = next + } + + return buf.Bytes() +} + + + + diff --git a/core/iosys/ansi/code.go b/core/iosys/ansi/code.go new file mode 100644 index 0000000..958d3af --- /dev/null +++ b/core/iosys/ansi/code.go @@ -0,0 +1,256 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File n code.go +// Created by DEV +// Modified 06/04/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package ansi + +import ( + "bytes" + "fmt" + "io" + "strings" +) + + + + + +type ( + + Code uint16 +) + + +func (c Code) Atts () string { + if c == 0 { + return "" + } + var r []string + m := c & txMask + if m != 0 { + dc := styleAttsStart + for i:=0; i<6; i++ { + if m & dc != 0 { + r = append(r,string(g.itx[i].n)) + } + dc <<= 1 + } + } + r = append(r,strings.Join([]string{c.FgColor().Name(),c.BgColor().Name()},":")) + return strings.Join(r,";") +} + + + +func (c Code) Clear () Code { + return 0 } + +func (c Code) ClearColor () Code { + return c & txMask +} + +func (c Code) ClearText () Code { + return c & clMask +} + + +func (c Code) FgColor() Color { + return Color((c & clMask) & bgMask) } + +func (c Code) SetFgColor(color Color) Code { + if !color.IsValid() { + return c + } + return (c & fgMask) | Code(color)&bgMask +} + +func (c Code) ResetFgColor() Code { + return (c & fgMask) | Code(colorDefault)&bgMask +} + + +func (c Code) BgColor() Color { + return Color(((c & clMask) & fgMask) >> bgShift) } + +func (c Code) SetBgColor(color Color) Code { + if !color.IsValid() { + return c + } + return (c & bgMask) | (Code(color)<> 10) } + + +func (c Code) SetStyle (sty Style) Code { + if !sty.IsValid() { + return c + } + v := Code(sty) << stShift + return ((((c &txMask) >>styleNumOps) &^ v) <>styleNumOps | v) | c &clMask +} + + + +func (c Code) scapeStyle () []byte { + m := c & txMask + if m == 0 { + return nil + } + var r []byte + dc := styleAttsStart + for i:=0; i<6; i++ { + if m & dc != 0 { + if r != nil { + r = append(r,';') + } else { + r = append(r,'0',';') + } + r = append(r, g.itx[i].s...) + } + dc <<= 1 + } + return r +} + + +func (c Code) scapeColor () []byte { + m := c & clMask + if m == 0 { + return nil + } + var r []byte + f := m & bgMask + b := (m & fgMask) >> bgShift + if f != 0 { + r = append(r, g.ics[f].f...) + } + if b != 0 { + if f > 0 { + r=append(r,';') + } + r = append(r, g.ics[b].b...) + } + return r +} + + +func (c Code) escape () []byte { + if c == 0 { + return []byte{'0'} + } + st := c.scapeStyle() + sc := c.scapeColor() + if len(sc) == 0 { + return st + } + if len(st) == 0 { + return sc + } + return append(st,append([]byte{';'},sc...)...) +} + + +func (c Code) stringValues() string { + return string(c.escape()) } + + +func (c Code) Begin() string { + if c == 0 { + return "" + } + r := c.escape() + return string(append(g.beginEscIni, append(r, g.beginEscEnd...)...)) +} + +func (c Code) End () string { + if c == 0 { + return "" + } + return g.endEscStr +} + + + + + +func (c Code) Errorf (format string, params ...any) error { + return fmt.Errorf(c.Sprintf(format,params...)) } + +func (c Code) Fprint (writer io.Writer, format string, params ...any) (n int, e error) { + return fmt.Fprint(writer,c.Sprintf(format,params...)) } + +func (c Code) Fprintln (writer io.Writer, format string, params ...any) (n int, e error) { + return fmt.Fprintln(writer,c.Sprintf(format,params...)) } + +func (c Code) Print (input ...any) (n int, e error) { + return fmt.Print(c.wrap(input ...)) } + +func (c Code) Printf (format string, params ...any) { + fmt.Printf(c.Sprintf(format,params...)) } + + +func (c Code) Sprint (format string, params ...any) string { + return fmt.Sprint(c.Sprintf(format,params...)) +} + +func (c Code) Sprintf (format string, params ...any) string { + if len(format) == 0 && len(params) == 0 { + return "" + } + s := fmt.Sprintf(format,params...) + if c == 0 { + return s + } + return c.wrap(s) +} + +func (c Code) Sprintln(format string, params ...any) string { + return fmt.Sprintln(c.Sprintf(format,params...)) } + + + +func (c Code) wrap(str ...any) string { + b := bytes.Buffer{} + b.WriteString(c.Begin()) + for _,s := range str { + b.WriteString(fmt.Sprint(s)) + } + b.WriteString(g.endEscStr) + return b.String() +} + diff --git a/core/iosys/ansi/color.go b/core/iosys/ansi/color.go new file mode 100644 index 0000000..acd241b --- /dev/null +++ b/core/iosys/ansi/color.go @@ -0,0 +1,65 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File n code_color.go +// Created by DEV +// Modified 06/04/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package ansi + + +const ( + + ColorNone Color = iota + ColorBlack + ColorRed + ColorGreen + ColorYellow + ColorBlue + ColorMagenta + ColorCyan + ColorWhite + ColorHBlack + ColorHRed + ColorHGreen + ColorHYellow + ColorHBlue + ColorHMagenta + ColorHCyan + ColorHWhite + colorDefault +) + +type ( + + Color uint8 + +) + + +func (c Color) Name () string { + if c.IsValid() { + return string(g.ics[c].n) + } + return string(g.ics[0].n) +} + +func (c Color) IsValid () bool { + return c >= ColorNone && c <= colorDefault +} \ No newline at end of file diff --git a/core/iosys/ansi/go.mod b/core/iosys/ansi/go.mod new file mode 100644 index 0000000..c2dcb18 --- /dev/null +++ b/core/iosys/ansi/go.mod @@ -0,0 +1,3 @@ +module ansi + +go 1.22 diff --git a/core/iosys/ansi/non_escape_writer.go b/core/iosys/ansi/non_escape_writer.go new file mode 100644 index 0000000..2f5ca13 --- /dev/null +++ b/core/iosys/ansi/non_escape_writer.go @@ -0,0 +1,117 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File n non_colorable_writer.go +// Created by DEV +// Modified 06/04/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package ansi + +import ( + "bytes" + "io" +) + +type ( + + NonEscapeWriter struct { + writer io.Writer + } + +) + + +func NewNonEscapeWriter(w io.Writer) *NonEscapeWriter { + return &NonEscapeWriter{ writer: w } } + + +/* +func (w *NonEscapeWriter) Write(data []byte) (n int, e error) { + var pt bytes.ABuffer + var ef bool + + for _, b := range data { + if b == 0x1b { + ef = true + continue + } + + if ef && b == 0x5b { + ef = false + continue + } + + if ef { + ef = g.charsEscs[b] == 1 + continue + } + + pt.WriteByte(b) + } + + _, e = pt.WriteTo(w.writer) + if e != nil { + return n, e + } + + return len(data), nil +} + + */ + +func (w *NonEscapeWriter) Write(data []byte) (n int, err error) { + er := bytes.NewReader(data) + var plaintext bytes.Buffer +loop: + for { + c1, err := er.ReadByte() + if err != nil { + plaintext.WriteTo(w.writer) + break loop + } + if c1 != 0x1b { + plaintext.WriteByte(c1) + continue + } + _, err = plaintext.WriteTo(w.writer) + if err != nil { + break loop + } + c2, err := er.ReadByte() + if err != nil { + break loop + } + if c2 != 0x5b { + continue + } + + for { + c, err := er.ReadByte() + if err != nil { + break loop + } + if g.charsEscs[c] == 1 { + //if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { + break + } + } + } + + return len(data), nil +} \ No newline at end of file diff --git a/core/iosys/ansi/style.go b/core/iosys/ansi/style.go new file mode 100644 index 0000000..bf9f457 --- /dev/null +++ b/core/iosys/ansi/style.go @@ -0,0 +1,77 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name style.go +// Created by DEV +// Modified 06/04/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package ansi + +import ( + "math/bits" + "strings" +) + +const ( + + + StyleBold Style = 1 << iota + StyleUnderline + StyleBlink + + StyleNone Style = 0 + + allStyles = StyleBold | StyleUnderline | StyleBlink +) + +type ( + + Style uint8 +) + + +func (s Style) Count () int { + return bits.OnesCount8(uint8(s)) } + +func (s Style) IsValid () bool { + return s <= allStyles +} + +func (s Style) Name () string { + var r []string + for i:=0; i< styleNumOps; i++ { + + } + return strings.Join(r,",") +} + + +func (s Style) HasBold () bool { + return s&StyleBold != 0 } + +func (s Style) HasUnderline () bool { + return s&StyleUnderline != 0 } + +func (s Style) HasBlink () bool { + return s&StyleBlink != 0 } + + + + + diff --git a/core/iosys/flusher.go b/core/iosys/flusher.go new file mode 100644 index 0000000..5bec18d --- /dev/null +++ b/core/iosys/flusher.go @@ -0,0 +1,52 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name flusher.go +// Created by DEV +// Modified 25/04/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package iosys + + + + +type ( + + // Flusher + // Interface type + // + // + Flusher interface { + + Flush() error + } + + FlushFnc func() error + + + NopFlusher struct {} +) + + +func (f FlushFnc) Flush() error { + return f() } + + +func (_ NopFlusher) Flush() error { + return nil } \ No newline at end of file diff --git a/core/iosys/go.mod b/core/iosys/go.mod new file mode 100644 index 0000000..dac1d34 --- /dev/null +++ b/core/iosys/go.mod @@ -0,0 +1,3 @@ +module iosys + +go 1.22 diff --git a/core/iosys/writer_flusher.go b/core/iosys/writer_flusher.go new file mode 100644 index 0000000..f08a340 --- /dev/null +++ b/core/iosys/writer_flusher.go @@ -0,0 +1,53 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name writer_flusher.go +// Created by DEV +// Modified 25/04/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package iosys + +import "io" + +type ( + + WriterFlusher interface { + io.Writer + Flusher + } +) + + + + +func AsWriterFlusher (writer io.Writer) WriterFlusher { + if writer == nil { + return nil + } + if wf,is := writer.(WriterFlusher); is { + return wf + } + return struct { + io.Writer + Flusher + }{ + Writer : writer, + Flusher: NopFlusher{}, + } +} \ No newline at end of file diff --git a/core/mems/pool.go b/core/mems/pool.go index 7b6f103..cbfa005 100644 --- a/core/mems/pool.go +++ b/core/mems/pool.go @@ -27,7 +27,7 @@ import ( "sort" "sync" "sync/atomic" - "syncs/pools" + "syns/pools" ) diff --git a/core/opts/g_option.go b/core/opts/g_option.go new file mode 100644 index 0000000..4f8745e --- /dev/null +++ b/core/opts/g_option.go @@ -0,0 +1,79 @@ +/* +--------------------------------------------------------- + Project activething + Active Thing (activething.com) git.activething.com/go + + File name option.go + Created by DEV + Modified 23/10/2023 + + Copyright 2023 activething.com +--------------------------------------------------------- +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +*/ + +package opts + +type ( + + // GOptionFnc + // es un tipo de función que se utiliza para configurar objetos en constructores, + // permitiendo evitar largas listas de parámetros y mantener el código limpio. + GOptionFnc[T any] func(obj *T) + + // GOptionErrFnc + // es un tipo de función de opción que puede devolver un error, lo que lo hace + // adecuado para manejar configuraciones que pueden generar errores. + // + GOptionErrFnc[T any] func(obj *T) error +) + +// GApply +// aplica una serie de funciones GOptionFnc a un objeto dado y lo retorna modificado. +func GApply[T any](target *T, options ...GOptionFnc[T]) *T { + if target == nil { + return nil + } + for _, fn := range options { + fn(target) + } + return target +} + +// GApplyAndCheck +// aplica una serie de funciones GOptionErrFnc a un objeto y retorna el objeto modificado, +// junto con un posible error en caso de configuración incorrecta. +func GApplyAndCheck[T any](target *T, options ...GOptionErrFnc[T]) (*T, error) { + for _, fn := range options { + if err := fn(target); err != nil { + return nil, err + } + } + return target, nil +} + +// GApplyAndCheckAll +// aplica una serie de funciones GOptionErrFnc a un objeto y retorna el objeto modificado, +// junto con una lista de errores que se han producido durante la configuración. +func GApplyAndCheckAll[T any](target T, options ...GOptionErrFnc[T]) (T, []error) { + var lst []error + for _, fn := range options { + if err := fn(&target); err != nil { + lst = append(lst, err) + } + } + return target, lst +} + + diff --git a/core/opts/go.mod b/core/opts/go.mod new file mode 100644 index 0000000..f465690 --- /dev/null +++ b/core/opts/go.mod @@ -0,0 +1,4 @@ +module opts + + +go 1.20 diff --git a/core/rsls/bytes.go b/core/rsls/bytes.go new file mode 100644 index 0000000..6459b34 --- /dev/null +++ b/core/rsls/bytes.go @@ -0,0 +1,93 @@ +// ------------------------------------------------------------------------ +// Project active +// Active Thing (activething.com) git.activething.com/go +// +// File name bytes.go +// Created by DEV +// Modified 07/03/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package results + +type ( + + + Bytes interface { + Result + Value() []byte // GResult implementation + } + + + BytesSuccess []byte + + + BytesError struct{ + error + } + +) + +func TupleBytesSuccess(bytes []byte) ([]byte, error) { + return bytes, nil } + +func TupleBytesError(err error) ([]byte, error) { + return nil, err } + + +func MakeBytes (bytes []byte, err error) Bytes { + if err != nil { + return BytesError{ err } + } + return BytesSuccess(bytes) +} + + +// BytesSuccess -> Bytes Implementation + +func MakeBytesSuccess(success []byte) BytesSuccess { + return success } + +func (_ BytesSuccess) Ok() bool { + return true } + +func (_ BytesSuccess) Fail() error { + return nil } + +func (s BytesSuccess) Value() []byte { + return s } + +func (s BytesSuccess) Success() any { + return s } + + + +// BytesError -> Bytes Implementation + +func MakeBytesError(cause error) BytesError { + return BytesError{cause} } + +func (e BytesError) Ok() bool { + return false } + +func (e BytesError) Fail() error { + return e.error } + +func (_ BytesError) Value() []byte { + return nil } + +func (_ BytesError) Success() any { + return nil } diff --git a/core/rsls/g_result.go b/core/rsls/g_result.go new file mode 100644 index 0000000..a9bc2cf --- /dev/null +++ b/core/rsls/g_result.go @@ -0,0 +1,86 @@ +// ------------------------------------------------------------------------ +// Project active +// Active Thing (activething.com) git.activething.com/go +// +// File name result.go +// Created by DEV +// Modified 07/03/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package results + +type ( + + + GResult [T any] interface { + Result + Value() T + } + + ResultGSuccess [T any] struct { + Result T + } + + ResultGError [T any] struct { + error + } +) + + + +func TupleGSuccess[T any](res T) (T, error) { + return res, nil } + +func TupleGError[T any](err error) (T, error) { + var r T + return r, err +} + +func MakeGSuccess[T any](res T) ResultGSuccess[T] { + return ResultGSuccess[T]{res} } + +func (r ResultGSuccess[T]) Value() T { + return r.Result } + +func (r ResultGSuccess[T]) Success() any { + return r.Result } + +func (_ ResultGSuccess[T]) Ok() bool { + return true } + +func (_ ResultGSuccess[T]) Fail() error { + return nil } + + + +func MakeGError[T any](err error) ResultGError[T] { + return ResultGError[T]{error: err} } + +func (r ResultGError[T]) Value() T { + var zero T + return zero +} + +func (_ ResultGError[T]) Ok() bool { + return false } + +func (r ResultGError[T]) Success() any { + return nil } + + +func (r ResultGError[T]) Fail() error { + return r.error } diff --git a/core/rsls/go.mod b/core/rsls/go.mod new file mode 100644 index 0000000..0f10ca8 --- /dev/null +++ b/core/rsls/go.mod @@ -0,0 +1,3 @@ +module rsls + +go 1.22 diff --git a/core/rsls/int.go b/core/rsls/int.go new file mode 100644 index 0000000..b2ac35c --- /dev/null +++ b/core/rsls/int.go @@ -0,0 +1,80 @@ +// ------------------------------------------------------------------------ +// Project active +// Active Thing (activething.com) git.activething.com/go +// +// File name int.go +// Created by DEV +// Modified 07/03/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package results + +type ( + + Int interface { + Result + Value() int // GResult implementation + } + + + IntSuccess int + + IntError struct{ error } +) + +func TupleIntSuccess(result int) (int, error) { + return result, nil } + +func TupleIntError(err error) ([]byte, error) { + return nil, err } + + +// IntSuccess -> Result, G.Result Implementation + +func MakeIntSuccess(success int) IntSuccess { + return IntSuccess(success) } + +func (_ IntSuccess) Ok() bool { + return true } + +func (_ IntSuccess) Fail() error { + return nil } + +func (s IntSuccess) Success() any { + return s } + +func (s IntSuccess) Value() int { + return int(s) } + + + +// IntError -> Result, G.Result Implementation + +func MakeIntError(cause error) IntError { + return IntError{cause} } + +func (e IntError) Ok() bool { + return false } + +func (e IntError) Fail() error { + return e.error } + +func (_ IntError) Success() any { + return nil } + +func (_ IntError) Value() int { + return 0 } diff --git a/core/rsls/result.go b/core/rsls/result.go new file mode 100644 index 0000000..1361a76 --- /dev/null +++ b/core/rsls/result.go @@ -0,0 +1,44 @@ +// ------------------------------------------------------------------------ +// Project active +// Active Thing (activething.com) git.activething.com/go +// +// File name result.go +// Created by DEV +// Modified 08/03/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package results + +type ( + + Result interface { + // Ok ; con un valor de true indica que el resultado + // se ha producido sin errores + Ok () bool + + // Success Value; contiene el valor del resultado en caso + // de que no se haya producido un error, en ese caso + // devolvera nil. + Success() any + + // Fail Error; contiene el error del resultado + Fail() error + + + } + +) diff --git a/core/rsls/string.go b/core/rsls/string.go new file mode 100644 index 0000000..c6b9993 --- /dev/null +++ b/core/rsls/string.go @@ -0,0 +1,80 @@ +// ------------------------------------------------------------------------ +// Project active +// Active Thing (activething.com) git.activething.com/go +// +// File name string.go +// Created by DEV +// Modified 07/03/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package results + +type ( + + String interface { + Result + Value() string // GResult implementation + } + + StringSuccess string + + StringError struct{ error } +) + + +func TupleStringSuccess(result string) (string, error) { + return result, nil } + +func TupleStringError(err error) (string, error) { + return "", err } + + + +// StringSuccess -> Result, G.Result Implementation + +func (_ StringSuccess) Ok() bool { + return true } + +func (s StringSuccess) Success() any { + return s } + +func (_ StringSuccess) Fail() error { + return nil } + +func (s StringSuccess) Value() string { + return string(s) } + + + +// StringError -> Result, G.Result Implementation + +func MakeStringError(cause error) IntError { + return IntError{cause} } + +func (e StringError) Ok() bool { + return false } + +func (_ StringError) Success() any { + return nil } + +func (e StringError) Fail() error { + return e.error } + +func (_ StringError) Value() string { + return "" } + + diff --git a/core/syns/abool.go b/core/syns/abool.go new file mode 100644 index 0000000..9d8f2e7 --- /dev/null +++ b/core/syns/abool.go @@ -0,0 +1,109 @@ +// +// Feb21 +// +// GO Active Thing +// Framework +// +// http://activething.com/dev/goat +// +// Dev : Juan V.Navarro +// Email: juanvnl@activething.com +// Date : 16/02/2021 +// +// Copyright 2021 the GOAT Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package syns + +import ( + "sync/atomic" +) + +type ( + + // ABool + // Type: Struct + // Desc: Atomic Bool, estructura para realizar operaciones atomicas + // sobre un valor de tipo Bool + // + ABool struct { + + // value: valor sobre el que se realizaran las operaciones + // atomicas. + // + value uint32 + } +) + +// NewABool +// Desc: Función constructor para ABool +// +// Prms: val, valor inicial +// Rets: Puntero al nuevo objeto creado. +// +func NewABool(val bool) *ABool { return &ABool{value: boolAsUint32(val)} } + +// ABool.Get +// Desc: +// Rets: +// +func (b *ABool) Get() bool { return atomic.LoadUint32(&b.value) == 1 } + +// ABool.Set +// Desc: +// Prms: +// +func (b *ABool) Set(val bool) { atomic.StoreUint32(&b.value, boolAsUint32(val)) } + +// ABool.Swap +// Desc: +// Prms: +// +func (b *ABool) Swap(new bool) bool { return atomic.SwapUint32(&b.value, boolAsUint32(new)) == 1 } + +// ABool.CAS +// Desc: +// Prms: +// Rets: +// +func (b *ABool) CAS(old, new bool) bool { + return atomic.CompareAndSwapUint32(&b.value, boolAsUint32(old), boolAsUint32(new)) +} + +// boolAsUint32 +// Desc: Convierte un valor de tipo bool a uint32 +// Prms: val, valor a convertir +// Rets: uint32, El valor segun sea true = 1 o +// false = * +// +func boolAsUint32(val bool) uint32 { + if val { + return 1 + } + return 0 +} + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syns/aduration.go b/core/syns/aduration.go new file mode 100644 index 0000000..ffb8b07 --- /dev/null +++ b/core/syns/aduration.go @@ -0,0 +1,117 @@ +// +// Feb21 +// +// GO Active Thing +// Framework +// +// http://activething.com/dev/goat +// +// Dev : Juan V.Navarro +// Email: juanvnl@activething.com +// Date : 16/02/2021 +// +// Copyright 2021 the GOAT Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package syns + +import ( + "sync/atomic" + "time" +) + +type ( + + // ADuration + // Type: Struct + // + // Desc: + // + // + ADuration struct { + value int64 + } +) + +// NewADuration +// Desc: Función constructor para ADuration +// +// Prms: val, valor inicial +// Rets: Puntero al nuevo objeto creado. +// +func NewADuration(val time.Duration) *ADuration { return &ADuration{value: int64(val)} } + +// ADuration.Get +// Desc: +// Prms: +// Rets: +// +func (i *ADuration) Get() time.Duration { return time.Duration(atomic.LoadInt64(&i.value)) } + +// ADuration.Set +// Desc: +// Prms: +// Rets: +// +func (i *ADuration) Set(val time.Duration) { atomic.StoreInt64(&i.value, int64(val)) } + +// ADuration.Swap +// Desc: +// Prms: +// Rets: +// +func (i *ADuration) Swap(new time.Duration) time.Duration { + return time.Duration(atomic.SwapInt64(&i.value, int64(new))) +} + +// ADuration.Add +// Desc: +// Prms: +// Rets: +// +func (i *ADuration) Add(dlt time.Duration) time.Duration { + return time.Duration(atomic.AddInt64(&i.value, int64(dlt))) +} + +// ADuration.Sub +// Desc: +// Prms: +// Rets: +// +func (i *ADuration) Sub(dlt time.Duration) time.Duration { + return time.Duration(atomic.AddInt64(&i.value, int64(-dlt))) +} + +// ADuration.CAS +// Desc: +// Prms: +// Rets: +// +func (i *ADuration) CAS(old, new time.Duration) bool { + return atomic.CompareAndSwapInt64(&i.value, int64(old), int64(new)) +} + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syns/aerror.go b/core/syns/aerror.go new file mode 100644 index 0000000..ac791e7 --- /dev/null +++ b/core/syns/aerror.go @@ -0,0 +1,90 @@ +// +// Feb21 +// +// GO Active Thing +// Framework +// +// http://activething.com/dev/goat +// +// Dev : Juan V.Navarro +// Email: juanvnl@activething.com +// Date : 16/02/2021 +// +// Copyright 2021 the GOAT Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package syns + +import ( + "sync/atomic" +) + +type ( + + // AError + // Type: Struct + // Desc: + // + // + AError struct { + value atomic.Value + } +) + +// NewAError +// Desc: Función constructor para AError +// +// Prms: val, valor inicial +// Rets: Puntero al nuevo objeto creado. +// +func NewAError(err error) *AError { + ae := &AError{} + if err != nil { + ae.value.Store(err) + } + return ae +} + +// AError.Set +// Desc: +// Prms: +// Rets: +// +func (a *AError) Set(err error) { a.value.Store(err) } + +// AError.Get +// Desc: +// Prms: +// Rets: +// +func (a *AError) Get() error { + if vl := a.value.Load(); vl != nil { + return vl.(error) + } + return nil +} + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syns/aint32.go b/core/syns/aint32.go new file mode 100644 index 0000000..c62562b --- /dev/null +++ b/core/syns/aint32.go @@ -0,0 +1,121 @@ +// +// Feb21 +// +// GO Active Thing +// Framework +// +// http://activething.com/dev/goat +// +// Dev : Juan V.Navarro +// Email: juanvnl@activething.com +// Date : 16/02/2021 +// +// Copyright 2021 the GOAT Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package syns + +import ( + "sync/atomic" +) + +type ( + + // AInt32 + // Type: Struct + // Desc: + // + // + AInt32 struct { + value int32 + } +) + +// NewAInt32 +// Desc: Función constructor para AInt32 +// +// Prms: val, valor inicial +// Rets: Puntero al nuevo objeto creado. +// +func NewAInt32(val int32) *AInt32 { return &AInt32{value: val} } + +// AInt32.Get +// Desc: +// Prms: +// Rets: +// +func (i *AInt32) Get() int32 { return atomic.LoadInt32(&i.value) } + +// AInt32.Set +// Desc: +// Prms: +// Rets: +// +func (i *AInt32) Set(val int32) { atomic.StoreInt32(&i.value, val) } + +// AInt32.Swap +// Desc: +// Prms: +// Rets: +// +func (i *AInt32) Swap(new int32) int32 { return atomic.SwapInt32(&i.value, new) } + +// AInt32.Add +// Desc: +// Prms: +// Rets: +// +func (i *AInt32) Add(dlt int32) int32 { return atomic.AddInt32(&i.value, dlt) } + +// AInt32.Sub +// Desc: +// Prms: +// Rets: +// +func (i *AInt32) Sub(dlt int32) int32 { return atomic.AddInt32(&i.value, -dlt) } + +// AInt32.Inc +// Desc: +// Prms: +// Rets: +// +func (i *AInt32) Inc() int32 { return i.Add(1) } + +// AInt32.Dec +// Desc: +// Prms: +// Rets: +// +func (i *AInt32) Dec() int32 { return i.Add(-1) } + +// AInt32.CAS +// Desc: +// Prms: +// Rets: +// +func (i *AInt32) CAS(old, new int32) bool { return atomic.CompareAndSwapInt32(&i.value, old, new) } + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syns/aint64.go b/core/syns/aint64.go new file mode 100644 index 0000000..baf9130 --- /dev/null +++ b/core/syns/aint64.go @@ -0,0 +1,121 @@ +// +// Feb21 +// +// GO Active Thing +// Framework +// +// http://activething.com/dev/goat +// +// Dev : Juan V.Navarro +// Email: juanvnl@activething.com +// Date : 16/02/2021 +// +// Copyright 2021 the GOAT Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package syns + +import ( + "sync/atomic" +) + +type ( + + // AInt64 + // Type: Struct + // Desc: + // + // + AInt64 struct { + value int64 + } +) + +// NewAInt64 +// Desc: Función constructor para AInt64 +// +// Prms: val, valor inicial +// Rets: Puntero al nuevo objeto creado. +// +func NewAInt64(val int64) *AInt64 { return &AInt64{value: val} } + +// AInt64.Get +// Desc: +// Prms: +// Rets: +// +func (i *AInt64) Get() int64 { return atomic.LoadInt64(&i.value) } + +// AInt64.Set +// Desc: +// Prms: +// Rets: +// +func (i *AInt64) Set(val int64) { atomic.StoreInt64(&i.value, val) } + +// AInt64.Swap +// Desc: +// Prms: +// Rets: +// +func (i *AInt64) Swap(new int64) int64 { return atomic.SwapInt64(&i.value, new) } + +// AInt64.Add +// Desc: +// Prms: +// Rets: +// +func (i *AInt64) Add(dlt int64) int64 { return atomic.AddInt64(&i.value, dlt) } + +// AInt64.Sub +// Desc: +// Prms: +// Rets: +// +func (i *AInt64) Sub(dlt int64) int64 { return atomic.AddInt64(&i.value, -dlt) } + +// AInt64.Inc +// Desc: +// Prms: +// Rets: +// +func (i *AInt64) Inc() int64 { return i.Add(1) } + +// AInt64.Dec +// Desc: +// Prms: +// Rets: +// +func (i *AInt64) Dec() int64 { return i.Add(-1) } + +// AInt64.CAS +// Desc: +// Prms: +// Rets: +// +func (i *AInt64) CAS(old, new int64) bool { return atomic.CompareAndSwapInt64(&i.value, old, new) } + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syns/ananos.go b/core/syns/ananos.go new file mode 100644 index 0000000..2b3edb1 --- /dev/null +++ b/core/syns/ananos.go @@ -0,0 +1,155 @@ +// +// Feb21 +// +// GO Active Thing +// Framework +// +// http://activething.com/dev/goat +// +// Dev : Juan V.Navarro +// Email: juanvnl@activething.com +// Date : 16/02/2021 +// +// Copyright 2021 the GOAT Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package syns + +import ( + "sync/atomic" + "time" +) + +type ( + + // ANanos + // Type: Struct + // Desc: + // + // + ANanos struct { + value int64 + } +) + +// NewANanos +// Desc: Función constructor para ANanos +// +// Prms: val, valor inicial +// Rets: Puntero al nuevo objeto creado. +// +func NewANanos(val time.Duration) *ANanos { return &ANanos{value: int64(val)} } + +// ANanos.Get +// Desc: +// Prms: +// Rets: +// +func (i *ANanos) Get() time.Duration { return time.Duration(atomic.LoadInt64(&i.value)) } + +// ANanos.Set +// Desc: +// Prms: +// Rets: +// +func (i *ANanos) Set(val time.Duration) { atomic.StoreInt64(&i.value, int64(val)) } + +// ANanos.Swap +// Desc: +// Prms: +// Rets: +// +func (i *ANanos) Swap(new time.Duration) time.Duration { + return time.Duration(atomic.SwapInt64(&i.value, int64(new))) +} + +// ANanos.Add +// Desc: +// Prms: +// Rets: +// +func (i *ANanos) Add(dlt time.Duration) time.Duration { + return time.Duration(atomic.AddInt64(&i.value, int64(dlt))) +} + +// ANanos.Sub +// Desc: +// Prms: +// Rets: +// +func (i *ANanos) Sub(dlt time.Duration) time.Duration { + return time.Duration(atomic.AddInt64(&i.value, int64(-dlt))) +} + +// ANanos.CAS +// Desc: +// Prms: +// Rets: +// +func (i *ANanos) CAS(old, new time.Duration) bool { + return atomic.CompareAndSwapInt64(&i.value, int64(old), int64(new)) +} + +// ANanos.GetTime +// Desc: +// Prms: +// Rets: +// +func (i *ANanos) GetTime() time.Time { return time.Unix(0, atomic.LoadInt64(&i.value)) } + +// ANanos.SetTime +// Desc: +// Prms: +// Rets: +// +func (i *ANanos) SetTime(val time.Time) { atomic.StoreInt64(&i.value, val.UnixNano()) } + +// ANanos.GetNanos +// Desc: +// Prms: +// Rets: +// +func (i *ANanos) GetNanos() int64 { return atomic.LoadInt64(&i.value) } + +// ANanos.SetNanos +// Desc: +// Prms: +// Rets: +// +func (i *ANanos) SetNanos(val int64) { atomic.StoreInt64(&i.value, val) } + +// ANanos.SetNow +// Desc: +// Prms: +// Rets: +// +func (i *ANanos) SetNow() time.Time { + nw := time.Now() + i.SetTime(nw) + return nw +} + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syns/auint32.go b/core/syns/auint32.go new file mode 100644 index 0000000..272c4d0 --- /dev/null +++ b/core/syns/auint32.go @@ -0,0 +1,121 @@ +// +// Feb21 +// +// GO Active Thing +// Framework +// +// http://activething.com/dev/goat +// +// Dev : Juan V.Navarro +// Email: juanvnl@activething.com +// Date : 16/02/2021 +// +// Copyright 2021 the GOAT Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package syns + +import ( + "sync/atomic" +) + +type ( + + // AUInt32 + // Type: Struct + // Desc: + // + // + AUInt32 struct { + value uint32 + } +) + +// NewAUInt32 +// Desc: Función constructor para AUInt32 +// +// Prms: val, valor inicial +// Rets: Puntero al nuevo objeto creado. +// +func NewAUInt32(val uint32) *AUInt32 { return &AUInt32{value: val} } + +// AUInt32.Get +// Desc: +// Prms: +// Rets: +// +func (u *AUInt32) Get() uint32 { return atomic.LoadUint32(&u.value) } + +// AUInt32.Set +// Desc: +// Prms: +// Rets: +// +func (u *AUInt32) Set(val uint32) { atomic.StoreUint32(&u.value, val) } + +// AUInt32.Swap +// Desc: +// Prms: +// Rets: +// +func (u *AUInt32) Swap(new uint32) uint32 { return atomic.SwapUint32(&u.value, new) } + +// AUInt32.Add +// Desc: +// Prms: +// Rets: +// +func (u *AUInt32) Add(dlt uint32) uint32 { return atomic.AddUint32(&u.value, dlt) } + +// AUInt32.Sub +// Desc: +// Prms: +// Rets: +// +func (u *AUInt32) Sub(dlt uint32) uint32 { return atomic.AddUint32(&u.value, ^uint32(dlt-1)) } + +// AUInt32.Inc +// Desc: +// Prms: +// Rets: +// +func (u *AUInt32) Inc() uint32 { return u.Add(1) } + +// AUInt32.Dec +// Desc: +// Prms: +// Rets: +// +func (u *AUInt32) Dec() uint32 { return u.Add(^uint32(0)) } + +// AUInt32.CAS +// Desc: +// Prms: +// Rets: +// +func (u *AUInt32) CAS(old, new uint32) bool { return atomic.CompareAndSwapUint32(&u.value, old, new) } + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syns/auint64.go b/core/syns/auint64.go new file mode 100644 index 0000000..84a58af --- /dev/null +++ b/core/syns/auint64.go @@ -0,0 +1,121 @@ +// +// Feb21 +// +// GO Active Thing +// Framework +// +// http://activething.com/dev/goat +// +// Dev : Juan V.Navarro +// Email: juanvnl@activething.com +// Date : 16/02/2021 +// +// Copyright 2021 the GOAT Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package syns + +import ( + "sync/atomic" +) + +type ( + + // AUInt64 + // Type: Struct + // Desc: + // + // + AUInt64 struct { + value uint64 + } +) + +// NewAUInt64 +// Desc: Función constructor para AUInt64 +// +// Prms: val, valor inicial +// Rets: Puntero al nuevo objeto creado. +// +func NewAUInt64(val uint64) *AUInt64 { return &AUInt64{value: val} } + +// AUInt64.Get +// Desc: +// Prms: +// Rets: +// +func (u *AUInt64) Get() uint64 { return atomic.LoadUint64(&u.value) } + +// AUInt64.Set +// Desc: +// Prms: +// Rets: +// +func (u *AUInt64) Set(val uint64) { atomic.StoreUint64(&u.value, val) } + +// AUInt64.Swap +// Desc: +// Prms: +// Rets: +// +func (u *AUInt64) Swap(new uint64) uint64 { return atomic.SwapUint64(&u.value, new) } + +// AUInt64.Add +// Desc: +// Prms: +// Rets: +// +func (u *AUInt64) Add(dlt uint64) uint64 { return atomic.AddUint64(&u.value, dlt) } + +// AUInt64.Sub +// Desc: +// Prms: +// Rets: +// +func (u *AUInt64) Sub(dlt uint64) uint64 { return atomic.AddUint64(&u.value, ^uint64(dlt-1)) } + +// AUInt64.Inc +// Desc: +// Prms: +// Rets: +// +func (u *AUInt64) Inc() uint64 { return u.Add(1) } + +// AUInt64.Dec +// Desc: +// Prms: +// Rets: +// +func (u *AUInt64) Dec() uint64 { return u.Add(^uint64(0)) } + +// AUInt64.CAS +// Desc: +// Prms: +// Rets: +// +func (u *AUInt64) CAS(old, new uint64) bool { return atomic.CompareAndSwapUint64(&u.value, old, new) } + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syns/b32_aint.go b/core/syns/b32_aint.go new file mode 100644 index 0000000..4a17a84 --- /dev/null +++ b/core/syns/b32_aint.go @@ -0,0 +1,64 @@ +// +// Feb21 +// +// GO Active Thing +// Framework +// +// http://activething.com/dev/goat +// +// Dev : Juan V.Navarro +// Email: juanvnl@activething.com +// Date : 16/02/2021 +// +// Copyright 2021 the GOAT Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +build 386 arm mips mipsle + +package syns + +import ( + "sync/atomic" +) + +type AInt struct{ value int32 } + +func NewAInt(v int) *AInt { return &AInt{value: int32(v)} } + +func (u *AInt) Get() int { return int(atomic.LoadInt32(&u.value)) } +func (u *AInt) Set(v int) { atomic.StoreInt32(&u.value, int32(v)) } +func (u *AInt) Swap(new int) int { return int(atomic.SwapInt32(&u.value, int32(new))) } + +func (u *AInt) Add(dlt int) int { return int(atomic.AddInt32(&u.value, int32(dlt))) } +func (u *AInt) Sub(dlt int) int { return int(atomic.AddInt32(&u.value, -dlt)) } +func (u *AInt) Inc() int { return u.Add(1) } +func (u *AInt) Dec() int { return u.Add(-1) } + +func (u *AInt) CAS(old, new int) bool { + return atomic.CompareAndSwapInt32(&u.value, int32(old), int32(new)) +} + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syns/b32_uint.go b/core/syns/b32_uint.go new file mode 100644 index 0000000..f0fb63c --- /dev/null +++ b/core/syns/b32_uint.go @@ -0,0 +1,64 @@ +// +// Feb21 +// +// GO Active Thing +// Framework +// +// http://activething.com/dev/goat +// +// Dev : Juan V.Navarro +// Email: juanvnl@activething.com +// Date : 16/02/2021 +// +// Copyright 2021 the GOAT Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +build 386 arm mips mipsle + +package syns + +import ( + "sync/atomic" +) + +type AUInt struct{ value uint32 } + +func NewAUint(v uint) *AUInt { return &AUInt{value: uint32(v)} } + +func (u *AUInt) Get() uint { return uint(atomic.LoadUint32(&u.value)) } +func (u *AUInt) Set(v uint) { atomic.StoreUint32(&u.value, uint32(v)) } +func (u *AUInt) Swap(new uint) uint { return uint(atomic.SwapUint32(&u.value, uint32(new))) } + +func (u *AUInt) Add(dlt uint) uint { return uint(atomic.AddUint32(&u.value, uint32(dlt))) } +func (u *AUInt) Sub(dlt uint) uint { return uint(atomic.AddUint32(&u.value, ^uint32(uint32(dlt)-1))) } +func (u *AUInt) Inc() uint { return u.Add(1) } +func (u *AUInt) Dec() uint { return u.Add(uint(^uint32(0))) } + +func (u *AUInt) CAS(old, new uint) bool { + return atomic.CompareAndSwapUint32(&u.value, uint32(old), uint32(new)) +} + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syns/b64_int.go b/core/syns/b64_int.go new file mode 100644 index 0000000..2e7b29d --- /dev/null +++ b/core/syns/b64_int.go @@ -0,0 +1,124 @@ +// +// Feb21 +// +// GO Active Thing +// Framework +// +// http://activething.com/dev/goat +// +// Dev : Juan V.Navarro +// Email: juanvnl@activething.com +// Date : 16/02/2021 +// +// Copyright 2021 the GOAT Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +build amd64 arm64 ppc64 ppc64le mips64 mips64le s390x + +package syns + +import ( + "sync/atomic" +) + +type ( + + // AInt + // Type: Struct + // Desc: + // + AInt struct { + value int64 + } +) + +// NewAInt +// Desc: Función constructor para AInt +// +// Prms: val, valor inicial +// Rets: Puntero al nuevo objeto creado. +// +func NewAInt(val int) *AInt { return &AInt{value: int64(val)} } + +// AInt.Get +// Desc: +// Prms: +// Rets: +// +func (u *AInt) Get() int { return int(atomic.LoadInt64(&u.value)) } + +// AInt.Set +// Desc: +// Prms: +// Rets: +// +func (u *AInt) Set(v int) { atomic.StoreInt64(&u.value, int64(v)) } + +// AInt.Swap +// Desc: +// Prms: +// Rets: +// +func (u *AInt) Swap(new int) int { return int(atomic.SwapInt64(&u.value, int64(new))) } + +// AInt.Add +// Desc: +// Prms: +// Rets: +// +func (u *AInt) Add(dlt int) int { return int(atomic.AddInt64(&u.value, int64(dlt))) } + +// AInt.Sub +// Desc: +// Prms: +// Rets: +// +func (u *AInt) Sub(dlt int) int { return int(atomic.AddInt64(&u.value, int64(-dlt))) } + +// AInt.Inc +// Desc: +// Prms: +// Rets: +// +func (u *AInt) Inc() int { return u.Add(1) } + +// AInt.Dec +// Desc: +// Prms: +// Rets: +// +func (u *AInt) Dec() int { return u.Add(-1) } + +// AInt.CAS +// Desc: +// Prms: +// Rets: +// +func (u *AInt) CAS(old, new int) bool { + return atomic.CompareAndSwapInt64(&u.value, int64(old), int64(new)) +} + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syns/b64_uint.go b/core/syns/b64_uint.go new file mode 100644 index 0000000..3955cf0 --- /dev/null +++ b/core/syns/b64_uint.go @@ -0,0 +1,124 @@ +// +// Feb21 +// +// GO Active Thing +// Framework +// +// http://activething.com/dev/goat +// +// Dev : Juan V.Navarro +// Email: juanvnl@activething.com +// Date : 16/02/2021 +// +// Copyright 2021 the GOAT Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +build amd64 arm64 ppc64 ppc64le mips64 mips64le s390x + +package syns + +import ( + "sync/atomic" +) + +type ( + + // AUInt + // Type: Struct + // Desc: + // + AUInt struct { + value uint64 + } +) + +// NewAInt +// Desc: Función constructor para AUInt +// +// Prms: val, valor inicial +// Rets: Puntero al nuevo objeto creado. +// +func NewAUint(val int64) *AUInt { return &AUInt{value: uint64(val)} } + +// AUInt.Get +// Desc: +// Prms: +// Rets: +// +func (u *AUInt) Get() uint { return uint(atomic.LoadUint64(&u.value)) } + +// AUInt.Set +// Desc: +// Prms: +// Rets: +// +func (u *AUInt) Set(val uint) { atomic.StoreUint64(&u.value, uint64(val)) } + +// AUInt.Swap +// Desc: +// Prms: +// Rets: +// +func (u *AUInt) Swap(new uint) uint { return uint(atomic.SwapUint64(&u.value, uint64(new))) } + +// AUInt.Add +// Desc: +// Prms: +// Rets: +// +func (u *AUInt) Add(dlt uint) uint { return uint(atomic.AddUint64(&u.value, uint64(dlt))) } + +// AUInt.Sub +// Desc: +// Prms: +// Rets: +// +func (u *AUInt) Sub(dlt uint) uint { return uint(atomic.AddUint64(&u.value, ^uint64(dlt-1))) } + +// AUInt.Inc +// Desc: +// Prms: +// Rets: +// +func (u *AUInt) Inc() uint { return u.Add(1) } + +// AUInt.Dec +// Desc: +// Prms: +// Rets: +// +func (u *AUInt) Dec() uint { return uint(^uint64(0)) } + +// AUInt.CAS +// Desc: +// Prms: +// Rets: +// +func (u *AUInt) CAS(old, new uint) bool { + return atomic.CompareAndSwapUint64(&u.value, uint64(old), uint64(new)) +} + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syns/ctasks/active.go b/core/syns/ctasks/active.go new file mode 100644 index 0000000..77cd493 --- /dev/null +++ b/core/syns/ctasks/active.go @@ -0,0 +1,63 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name gogo.go +// Created by DEV +// Modified 20/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package ctasks + +import "errs" + +const ( + + CompletionFromChild int = iota * -1 + CompletionFromSelf + CompletionFromParent + CompletionFromContext + CompletionFromTimer + CompletionFromRequest + +) + + +var ( + + G = struct { + + ErrInvalidCompletion errs.ErrCode + ErrInvalidState errs.ErrCode + ErrCancelByParent errs.ErrCode + ErrCancelByRequest errs.ErrCode + ErrCancelByContext errs.ErrCode + ErrCancelByTimer errs.ErrCode + + }{ + ErrInvalidCompletion: errs.ErrCode("invalid-completion"), + ErrInvalidState : errs.ErrCode("invalid-state"), + ErrCancelByParent : errs.ErrCode("cancel-by-parent"), + ErrCancelByRequest : errs.ErrCode("cancel-by-request"), + ErrCancelByContext : errs.ErrCode("cancel-by-context"), + ErrCancelByTimer : errs.ErrCode("cancel-by-timer"), + + + } +) + + diff --git a/core/syns/ctasks/completer.go b/core/syns/ctasks/completer.go new file mode 100644 index 0000000..a4f6320 --- /dev/null +++ b/core/syns/ctasks/completer.go @@ -0,0 +1,42 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name completer.go +// Created by DEV +// Modified 20/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package ctasks + + +type ( + + Completer interface { + + Complete (context Context, cid int) + } + + + CompleteFnc func (context Context, cid int) + +) + + + +func (f CompleteFnc) Complete (context Context, cid int) { + f(context,cid) } diff --git a/core/syns/ctasks/completion.go b/core/syns/ctasks/completion.go new file mode 100644 index 0000000..e28418a --- /dev/null +++ b/core/syns/ctasks/completion.go @@ -0,0 +1,373 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name completion.go +// Created by DEV +// Modified 20/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package ctasks + +import ( + "context" + "opts" + "sync" + "sync/atomic" + "syncs/works" + "time" + cronus "timers" +) + +type ( + + Completion struct { + /*embedded*/context.Context + mux sync.RWMutex + wgr sync.WaitGroup + + parent Context + expiration *cronus.Expiration + + mode Mode + state uint32 + pending uint32 + + cid int + result Result + + dispatchFn dispatchFnc + cancelFn func() + + completers []Completer + } + + CompletionFnc func (c *Completion) error + + dispatchFnc func (*Completion, Completer, int) error + + +) + + +func NewCompletion (options ...CompletionFnc) (*Completion,error) { + + c := &Completion { + mode : ModeAll, + cid : CompletionFromSelf, + dispatchFn: dispatcher, + } + for _,o := range options { + if er := o(c); er != nil { + return nil,er + } + } + if c.expiration == nil { + c.expiration = cronus.NewExpiration(0,nil) + } + return c,nil +} + + +func (c *Completion) Mode () Mode { + return c.mode } + +func (c *Completion) State () State { + return State(atomic.LoadUint32(&c.state)) } + +func (c *Completion) Pending() int { + return int(atomic.LoadUint32(&c.pending)) } + +func (c *Completion) IsCompleted () bool { + return c.State() > StateStarted +} + +func (c *Completion) Chrono () cronus.Chronometer { + return c.expiration.Chono() } + +func (c *Completion) Result () Result { + c.wgr.Wait() + return c.result +} + +func (c *Completion) Wait () { + c.wgr.Wait() } + + +func (c *Completion) AddCompleter (cms ... Completer) error { + c.mux.Lock() + if c.State() != StateCreated { + c.mux.Unlock() + return G.ErrInvalidState + } + for _,cm := range cms { + c.completers = append(c.completers, cm) + } + c.mux.Unlock() + return nil +} + + +func (c *Completion) Cancel () { + c.notify(CompletionFromRequest, StateCanceled,nil,G.ErrCancelByRequest) } + + +func (c *Completion) Start (ctx context.Context) error { + return c.complete(ctx,nil,CompletionFromSelf) } + + +func (c *Completion) Complete (cmp Context, cid int) { + _ = c.complete(nil,cmp,cid) } + + + +func (c *Completion) complete (ctx context.Context, cctx Context, cid int) error { + c.mux.Lock() + + if c.State() != StateCreated { + c.mux.Unlock() + return G.ErrInvalidState + } + + // Nos sirve para determinar de donde va a depender la expiracion + // en tiempo de la completion en caso de que exista, o bien de la + // completion padre o bien del contexto. + // + var ex cronus.Expirer + + if cctx != nil { + c.parent = cctx + c.Context= cctx + c.cid = cid + if c.parent.IsCompleted() { + c.mux.Unlock() + c.notify(CompletionFromParent, StateCanceled,nil,G.ErrCancelByParent) + return G.ErrCancelByParent + } + ex = c.parent + } else { + if ctx == nil { + c.Context = context.Background() + } else { + c.Context = ctx + if ctx.Err() != nil { + c.mux.Unlock() + c.notify(CompletionFromContext, StateCanceled,nil,G.ErrCancelByContext) + return G.ErrCancelByContext.WrapWithCause(ctx.Err()) + } + + ch := make(chan struct{}) + c.cancelFn = func(){ close(ch)} + go func(cc *Completion, ch chan struct{}){ + select { + case <- ch: + case <- cc.Context.Done() : + er := G.ErrCancelByContext.WrapWithCause(cc.Context.Err()) + cc.notify(CompletionFromContext, StateCanceled,nil,er) + } + }(c,ch) + } + ex = ctx + } + + if er := c.expiration.Start(ex); er != nil { + c.mux.Unlock() + c.notify(CompletionFromSelf, StateFaulted,nil,er) + return er + } + + atomic.StoreUint32(&c.state,uint32(StateStarted)) + c.wgr.Add(1) + + go func (c *Completion) { + ln := len(c.completers) + if ln == 0 { + c.mux.Unlock() + c.notify(CompletionFromSelf, StateCompleted, nil, nil) + return + } + + atomic.StoreUint32(&c.pending,uint32(ln)) + cs := c.completers + c.mux.Unlock() + + for ix, cm := range cs { + if c.IsCompleted() { + return + } + if er := c.dispatchFn(c,cm,ix); er != nil { + c.notify(CompletionFromSelf, StateFaulted,nil,er) + return + } + } + }(c) + + return nil +} + + + +func (c *Completion) Notify (frm int, val interface{}, err error) { + c.notify(frm, StateCompleted,val,err) } + + + +func (c *Completion) notify (frm int, ste State, val interface{}, err error) { + c.mux.Lock() + os := c.State() + if os > StateStarted { + c.mux.Unlock() + return + } + + if frm >= CompletionFromChild { + cn := atomic.AddUint32(&c.pending,-1) + + switch { + case c.mode.IsAnyOrResult() && val != nil: + atomic.StoreUint32(&c.state,uint32(StateCompleted)) + c.result = NewResultValue(frm, val) + + case c.mode.IsAnyOrError() && err != nil: + atomic.StoreUint32(&c.state,uint32(StateFaulted)) + c.result = NewResultError(frm, err) + + case c.mode == ModeTask: + c.result = NewResult(frm, val, err) + + default: + if c.mode == ModeAll { + if c.result == nil { + c.result = NewResultList(c.cid, NewResult(frm, val, err)) + } else { + c.result.(*ResultList).Add(NewResult(frm, val, err)) + } + } + if cn == 0 { + atomic.StoreUint32(&c.state,uint32(StateCompleted)) + } else { + c.mux.Unlock() + return + } + } + + } else { + atomic.StoreUint32(&c.state,uint32(ste)) + c.result = NewResult(frm,val,err) + } + + _ = c.expiration.Stop() + if c.cancelFn != nil { + c.cancelFn() + } + c.wgr.Done() + c.mux.Unlock() + + + // Solo notificamos a las completions hijas y al padre en caso de que se haya iniciado + if os == StateStarted { + for _, ch := range c.completers { + // Notificamos solo a los completer que a su vez implementan + // Context + if cm, is := ch.(Context); is { + if !cm.IsCompleted() { + cm.Notify(CompletionFromParent, nil, G.ErrCancelByParent) + } + } + } + // Notificamos al padre en caso de que tenga y la completion no venga de el + if frm != CompletionFromParent && c.parent != nil { + c.parent.Notify(c.cid,c.result.Value(),c.result.Error()) + } + } +} + + + + + + + +func dispatcher (completion *Completion, completer Completer, cid int) error { + go completer.Complete(completion,cid) + return nil +} + + + + + + +// WithMode +// Desc: Función para el constructor de Completion, +// establece el mode de como se llegara a la completion +// +func WithMode (mode Mode) opts.GOptionErrFnc[Completion] { + return func(c *Completion) error { + c.mode = mode + return nil + } +} + + +// WithTimeout +// Desc: Función para el constructor de Completion +// Establece el tiempo máximo de la completion +// +func WithTimeout (tmo time.Duration) opts.GOptionErrFnc[Completion] { + return func(c *Completion) error { + c.expiration = cronus.NewExpiration(tmo,func(){ + c.notify(CompletionFromTimer, StateCanceled,nil,G.ErrCancelByTimer) + }) + return nil + } +} + + +// WithCompleters +// Desc: Función para el constructor de Completion, +// añade los objeto a completar en la completion +// +func WithCompleters (completers ... Completer) opts.GOptionErrFnc[Completion] { + return func(c *Completion) error { + if c.State() != StateCreated { + return G.ErrInvalidState + } + for _, cm := range completers { + c.completers = append(c.completers, cm) + } + return nil + } +} + + +// WithWorkPool +// Desc: Función para el constructor de Completion, +// utiliza un pool de trabajo para completar +// las tareas. +// +func WithWorkPool (pool *works.Pool) opts.GOptionErrFnc[Completion] { + return func(c *Completion) error { + c.dispatchFn = dispatchFnc(func (cm *Completion, cr Completer, ci int) error { + return pool.DoWork(c,func(){ + cr.Complete(cm,ci) + }) + }) + return nil + } +} + diff --git a/core/syns/ctasks/context.go b/core/syns/ctasks/context.go new file mode 100644 index 0000000..17d139d --- /dev/null +++ b/core/syns/ctasks/context.go @@ -0,0 +1,39 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name completion_context.go +// Created by DEV +// Modified 20/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package ctasks + +import "context" + +type ( + + Context interface { + context.Context + + IsCompleted () bool + + Notify (cid int, val interface {}, err error) + } +) + + diff --git a/core/syns/ctasks/mode.go b/core/syns/ctasks/mode.go new file mode 100644 index 0000000..fe27eb5 --- /dev/null +++ b/core/syns/ctasks/mode.go @@ -0,0 +1,92 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name completion_mode.go +// Created by DEV +// Modified 20/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package ctasks + + + +const( + + ModeAll Mode = iota + + // ModeAny Las tareas se ejecutaran haste que se + //produzca el primer resultado o el primer error + ModeAny + + //ModeResult Las tareas se ejecutaran hasta que + //se obtenga el primer resultado. + ModeResult + + //ModeError Las tareas se completaran en el momento de + //que se produzca un error. + ModeError + + //CompletionModeTask Modo para las completions de una sola task + ModeTask + +) + + +type ( + + Mode uint8 + +) + + +func (m Mode) IsAnyOrResult () bool { + return m == ModeResult || m == ModeAny +} + + +func (m Mode) IsAnyOrError () bool { + return m == ModeError || m == ModeAny +} + + + +func (m Mode) String () string { + switch m { + case ModeAll: return "all" + case ModeAny: return "any" + case ModeResult: return "result" + case ModeError: return "error" + case ModeTask: return "task" + default: + return "??" + } +} + + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syns/ctasks/result.go b/core/syns/ctasks/result.go new file mode 100644 index 0000000..fb41237 --- /dev/null +++ b/core/syns/ctasks/result.go @@ -0,0 +1,51 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name completion_result.go +// Created by DEV +// Modified 20/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package ctasks + + + +type ( + + Result interface { + + CID () int + + Value() any + + Error() error + + Kind () ResultKind + } +) + + +func NewResult(cid int, val any, err error) Result { + if err != nil { + return *NewResultError(cid,err) + } + if val != nil { + return *NewResultValue(cid,val) + } + return ResultVoid(cid) +} \ No newline at end of file diff --git a/core/syns/ctasks/result_error.go b/core/syns/ctasks/result_error.go new file mode 100644 index 0000000..3e977d1 --- /dev/null +++ b/core/syns/ctasks/result_error.go @@ -0,0 +1,74 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name completion_result_error.go +// Created by DEV +// Modified 20/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package ctasks + + + + +type ( + + + ResultError struct { + cid int + err error + } + +) + +func NewResultError(cid int, err error) *ResultError { + return &ResultError{ + cid : cid, + err : err, + } +} + +func (r ResultError) CID () int { + return r.cid } + +func (_ ResultError) Kind () ResultKind { + return ResultKindError +} + +func (_ ResultError) Value () any { + return nil } + +func (r ResultError) Error () error { + return r.err } + + + + + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syns/ctasks/result_kind.go b/core/syns/ctasks/result_kind.go new file mode 100644 index 0000000..1378801 --- /dev/null +++ b/core/syns/ctasks/result_kind.go @@ -0,0 +1,87 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name completion_result_kind.go +// Created by DEV +// Modified 20/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package ctasks + + + + +const( + + ResultKindVoid ResultKind = iota + ResultKindError + ResultKindValue + ResultKindList + +) + + +type ( + + ResultKind uint8 + +) + +func (k ResultKind) IsVoid () bool { + return k == ResultKindVoid +} + +func (k ResultKind) IsError() bool { + return k == ResultKindError +} + + +func (k ResultKind) IsValue() bool { + return k == ResultKindValue +} + + +func (k ResultKind) IsList () bool { + return k == ResultKindList +} + + +func (k ResultKind) String () string { + switch k { + case ResultKindVoid: return "void" + case ResultKindValue: return "value" + case ResultKindError: return "error" + case ResultKindList: return "list" + default: + return "??" + } +} + + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syns/ctasks/result_list.go b/core/syns/ctasks/result_list.go new file mode 100644 index 0000000..bbf36cc --- /dev/null +++ b/core/syns/ctasks/result_list.go @@ -0,0 +1,88 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name completion_result_list.go +// Created by DEV +// Modified 20/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package ctasks + + + + +type ( + + + ResultList struct { + cid int + results []Result + } + +) + +func NewResultList(cid int, results ...Result) *ResultList { + ls := make([]Result,len(results)) + copy(ls, results) + return &ResultList{ + cid: cid, + results: ls, + } +} + + +func (r *ResultList) Add (rsl Result) { + if rsl != nil { + r.results = append(r.results, rsl) + } +} + + +func (r ResultList) CID () int { + return r.cid } + + +func (_ ResultList) Kind () ResultKind { + return ResultKindList +} + + +func (_ ResultList) Error () error { + return nil } + + +func (r ResultList) Value () any { + return r.results } + + + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ + + + diff --git a/core/syns/ctasks/result_value.go b/core/syns/ctasks/result_value.go new file mode 100644 index 0000000..f764fb5 --- /dev/null +++ b/core/syns/ctasks/result_value.go @@ -0,0 +1,74 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name completion_result_value.go +// Created by DEV +// Modified 20/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package ctasks + + + + + +type ( + + + ResultValue struct { + cid int + value any + } + +) + +func NewResultValue(cid int, value any) *ResultValue { + return &ResultValue{ + cid : cid, + value: value, + } +} + +func (r ResultValue) CID () int { + return r.cid } + +func (_ ResultValue) Kind () ResultKind { + return ResultKindValue +} + +func (_ ResultValue) Error () error { + return nil } + +func (r ResultValue) Value () any { + return r.value } + + + + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syns/ctasks/result_void.go b/core/syns/ctasks/result_void.go new file mode 100644 index 0000000..69d4459 --- /dev/null +++ b/core/syns/ctasks/result_void.go @@ -0,0 +1,70 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name completion_result_void.go +// Created by DEV +// Modified 20/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package ctasks + + + + + +type ( + + + ResultVoid int + + +) + + +func (r ResultVoid) CID () int { + return int(r) +} + +func (_ ResultVoid) Kind () ResultKind { + return ResultKindVoid +} + +func (_ ResultVoid) Value () any { + return nil } + +func (_ ResultVoid) Error () error { + return nil } + + + + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ + + + diff --git a/core/syns/ctasks/state.go b/core/syns/ctasks/state.go new file mode 100644 index 0000000..d5d6e06 --- /dev/null +++ b/core/syns/ctasks/state.go @@ -0,0 +1,58 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name completion_state.go +// Created by DEV +// Modified 20/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package ctasks + + + +const ( + + StateCreated State = iota + StateStarted + StateCompleted + StateCanceled + StateFaulted + +) + + +type ( + + State uint32 + +) + + +func (s State) String () string { + switch s { + case StateCreated: return "created" + case StateStarted: return "started" + case StateCompleted: return "completed" + case StateCanceled: return "canceled" + case StateFaulted: return "faulted" + default: return "??" + } +} + + + diff --git a/core/syns/go.mod b/core/syns/go.mod new file mode 100644 index 0000000..1dfb1ab --- /dev/null +++ b/core/syns/go.mod @@ -0,0 +1,4 @@ +module syns + + +go 1.20 \ No newline at end of file diff --git a/core/syns/locker_read.go b/core/syns/locker_read.go new file mode 100644 index 0000000..319206f --- /dev/null +++ b/core/syns/locker_read.go @@ -0,0 +1,50 @@ +// +// Feb21 +// +// GO Active Thing +// Framework +// +// http://activething.com/dev/goat +// +// Dev : Juan V.Navarro +// Email: juanvnl@activething.com +// Date : 16/02/2021 +// +// Copyright 2021 the GOAT Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package syns + +type ( + + + LockerRead interface { + RLock() + RUnlock() + } +) + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syns/locker_rw.go b/core/syns/locker_rw.go new file mode 100644 index 0000000..bd8a876 --- /dev/null +++ b/core/syns/locker_rw.go @@ -0,0 +1,49 @@ +// +// Feb21 +// +// GO Active Thing +// Framework +// +// http://activething.com/dev/goat +// +// Dev : Juan V.Navarro +// Email: juanvnl@activething.com +// Date : 16/02/2021 +// +// Copyright 2021 the GOAT Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +package syns + +type ( + + + LockerRW interface { + LockerRead + LockerWrite + } +) + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syns/locker_write.go b/core/syns/locker_write.go new file mode 100644 index 0000000..71f605c --- /dev/null +++ b/core/syns/locker_write.go @@ -0,0 +1,50 @@ +// +// Feb21 +// +// GO Active Thing +// Framework +// +// http://activething.com/dev/goat +// +// Dev : Juan V.Navarro +// Email: juanvnl@activething.com +// Date : 16/02/2021 +// +// Copyright 2021 the GOAT Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package syns + +type ( + + + LockerWrite interface { + Lock() + Unlock() + } +) + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syns/nop_locker.go b/core/syns/nop_locker.go new file mode 100644 index 0000000..80da083 --- /dev/null +++ b/core/syns/nop_locker.go @@ -0,0 +1,45 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name nop_locker.go +// Created by DEV +// Modified 20/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package syns + + +type ( + + NopLocker struct{} +) + + +func (_ NopLocker) Lock() {} + + +func (_ NopLocker) Unlock() {} + + +func (_ NopLocker) RLock() {} + + +func (_ NopLocker) RUnlock() {} + + + diff --git a/core/syns/pools/g_pool.go b/core/syns/pools/g_pool.go new file mode 100644 index 0000000..8140377 --- /dev/null +++ b/core/syns/pools/g_pool.go @@ -0,0 +1,134 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name pool.go +// Created by DEV +// Modified 17/01/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package pools + +import ( + "opts" + "sync" + "sync/atomic" +) + +type ( + + GPool[T any] struct { + PoolStatsInfo + + inner sync.Pool + + cap int32 + len int32 + + createFn func() *T + } +) + +func NewGPool[T any](ops ...opts.GOptionFnc[GPool[T]]) *GPool[T] { + return opts.GApply(&GPool[T]{}, ops...) } + + +func (p *GPool[T]) Len() int32 { + return atomic.LoadInt32(&p.len) } + + +func (p *GPool[T]) Cap() int32 { + return atomic.LoadInt32(&p.cap) } + + +func (p *GPool[T]) Get() *T { + o := p.inner.Get() + if o != nil { + p.AddAcquired() + if p.Len() > 0 { + atomic.AddInt32(&p.len, -1) + } + return o.(*T) + } + if o = p.createFn(); o != nil { + p.AddCreated() + } + return o.(*T) +} + + +func (p *GPool[T]) Put(obj *T) { + if obj == nil { + return + } + c := p.Cap() + p.AddReleased() + if c == -1 || c >= p.Len() { + atomic.AddInt32(&p.len, 1) + p.inner.Put(obj) + } +} + + +func (p *GPool[T]) Empty() { + for p.Len() > 0 { + _ = p.Get() + } +} + + + + +func WithNew[T any](nfn func() *T) opts.GOptionFnc[GPool[T]] { + return func(p *GPool[T]) { + p.createFn = nfn + } +} + + +func WithCap[T any](cap int32) opts.GOptionFnc[GPool[T]] { + return func(p *GPool[T]) { + atomic.StoreInt32(&p.cap, cap) + } +} + + +func WithLen[T any](len int32) opts.GOptionFnc[GPool[T]] { + return func(p *GPool[T]) { + if p.createFn == nil { + return + } + c := p.Cap() + if c != -1 && len > c { + len = c + } + for i := int32(0); i < len; i++ { + p.Put(p.createFn()) + } + } +} + + +func WithSet[T any](els ...*T) opts.GOptionFnc[GPool[T]] { + return func(p *GPool[T]) { + for _, e := range els { + if e != nil { + p.Put(e) + } + } + } +} diff --git a/core/syns/pools/pool_call_sizes.go b/core/syns/pools/pool_call_sizes.go new file mode 100644 index 0000000..5586edf --- /dev/null +++ b/core/syns/pools/pool_call_sizes.go @@ -0,0 +1,44 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name call_sizes.go +// Created by DEV +// Modified 17/01/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package pools + +type ( + PoolCallSize struct { + Size uint64 + Calls uint64 + } + + PoolCallSizes []PoolCallSize +) + +func (c PoolCallSizes) Len() int { + return len(c) } + + +func (c PoolCallSizes) Less(i, j int) bool { + return c[i].Calls > c[j].Calls } + + +func (c PoolCallSizes) Swap(i, j int) { + c[i], c[j] = c[j], c[i] } diff --git a/core/syns/pools/pool_stats.go b/core/syns/pools/pool_stats.go new file mode 100644 index 0000000..92c5cdb --- /dev/null +++ b/core/syns/pools/pool_stats.go @@ -0,0 +1,39 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name pool_stats.go +// Created by DEV +// Modified 20/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package pools + + + + +type ( + + PoolStats interface { + + Created () uint64 + Acquired() uint64 + Released() uint64 + } +) + + diff --git a/core/syns/pools/pool_stats_info.go b/core/syns/pools/pool_stats_info.go new file mode 100644 index 0000000..444a836 --- /dev/null +++ b/core/syns/pools/pool_stats_info.go @@ -0,0 +1,64 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name pool_stats.go +// Created by DEV +// Modified 17/01/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package pools + +import "sync/atomic" + +type ( + + PoolStatsInfo struct { + created uint64 + acquired uint64 + released uint64 + } +) + +func NewPoolStatsInfo () *PoolStatsInfo { + return &PoolStatsInfo{} } + + +func (p *PoolStatsInfo) Created() uint64 { + return atomic.LoadUint64(&p.created) } + + +func (p *PoolStatsInfo) Acquired() uint64 { + return atomic.LoadUint64(&p.acquired) } + + +func (p *PoolStatsInfo) Released() uint64 { + return atomic.LoadUint64(&p.released) } + + +func (p *PoolStatsInfo) AddCreated() { + atomic.AddUint64(&p.created, 1) } + + +func (p *PoolStatsInfo) AddReleased() { + atomic.AddUint64(&p.released, 1) } + + +func (p *PoolStatsInfo) AddAcquired() { + atomic.AddUint64(&p.acquired, 1) } + + diff --git a/core/syns/queue/g_queue.go b/core/syns/queue/g_queue.go new file mode 100644 index 0000000..94cb4e6 --- /dev/null +++ b/core/syns/queue/g_queue.go @@ -0,0 +1,87 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name g_queue.go +// Created by DEV +// Modified 24/04/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package queue + +import ( + "sync" + "syncs" +) + +type ( + + GQueue [T any]struct { + locker syncs.LockerRW + elems []T + } + +) + + +func NewGQueue [T any](safe bool) *GQueue[T] { + var lc syncs.LockerRW + if safe { + lc = &sync.RWMutex{} + } else { + lc = syncs.NopLocker{} + } + return &GQueue[T]{ locker : lc } +} + + +func (q *GQueue[T]) Len () (l int) { + q.locker.RLock() + l = len(q.elems) + q.locker.RUnlock() + return +} + + +func (q *GQueue[T]) Push(ele T) { + q.locker.Lock() + q.elems = append(q.elems,ele) + q.locker.Unlock() +} + + +func (q *GQueue[T]) Pop() (e T) { + q.locker.Lock() + if q.Len() > 0 { + e = q.elems[0] + q.elems = q.elems[1:] + } + q.locker.Unlock() + return +} + + +func (q *GQueue[T]) Clear (onClearFnc func(ele T)) { + q.locker.Lock() + if onClearFnc != nil { + for _,e := range q.elems { + onClearFnc(e) + } + } + q.elems = q.elems[:0] + q.locker.Unlock() +} diff --git a/core/syns/signaler.go b/core/syns/signaler.go new file mode 100644 index 0000000..ef1da05 --- /dev/null +++ b/core/syns/signaler.go @@ -0,0 +1,27 @@ +package syns + + + +type ( + + // Signaler + // Channel type + // + // + Signaler chan struct{} +) + +// MakeSignaler +// Function constructor -> Signaler +// +// +func MakeSignaler(buf int) Signaler { return make(Signaler,1) } + + +func (c Signaler) Send (){ c <- struct{}{}} + + +func (c Signaler) Wait () <- chan struct{} { return c } + + +func (c Signaler) Close(){ close(c) } \ No newline at end of file diff --git a/core/syns/works/active.go b/core/syns/works/active.go new file mode 100644 index 0000000..1d6d3e5 --- /dev/null +++ b/core/syns/works/active.go @@ -0,0 +1,56 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name active.go +// Created by DEV +// Modified 23/04/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package works + +import ( + "errs" + "time" +) + +const ( + + minWorkers = 10 + maxWorkers = 1000 + + minIdle = time.Millisecond * 100 + maxIdle = time.Second * 10 + +) + +var ( + + G = struct { + + ErrPoolStarted errs.ErrCode + ErrPoolStopped errs.ErrCode + ErrPoolAcquire errs.ErrCode + + }{ + ErrPoolStarted : errs.ErrCode("pool-started"), + ErrPoolStopped : errs.ErrCode("pool-stopped"), + ErrPoolAcquire : errs.ErrCode("pool-acquire"), + } +) + + diff --git a/core/syns/works/pool.go b/core/syns/works/pool.go new file mode 100644 index 0000000..2ff0429 --- /dev/null +++ b/core/syns/works/pool.go @@ -0,0 +1,282 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name worker_pool.go +// Created by DEV +// Modified 20/02/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package works + +import ( + "context" + "runtime" + "sync" + "sync/atomic" + "syncs/pools" + "time" +) + + +type ( + + Pool struct { + stats *pools.PoolStatsInfo + pool sync.Pool + mux sync.Mutex + + cap int32 + max int32 + count int32 + state uint32 + + maxIdle int64 + + workers []*worker + doneCh chan struct{} + } + + + PoolFnc func(wp *Pool) +) + + +func NewPool(options ...PoolFnc) *Pool { + c := int32(1) + if runtime.GOMAXPROCS(0) == 1 { + c = 0 + } + wp := &Pool{ + stats : pools.NewPoolStatsInfo(), + maxIdle: int64(maxIdle), + cap : c, + max : maxWorkers, + state : uint32(PoolStateCreated), + } + for _,o := range options { + o(wp) + } + wp.pool.New = wp.newWorker + return wp +} + + +func (p *Pool) newWorker () any { + p.stats.AddCreated() + return &worker{ + jobCh: make(chan func(), atomic.LoadInt32(&p.cap)) }} + + +func (p *Pool) Stats () pools.PoolStats { + return p.stats } + + +func (p *Pool) State () PoolState { + return PoolState(atomic.LoadUint32(&p.state)) } + +func (p *Pool) Count () int32 { + return atomic.LoadInt32(&p.count) } + + +func (p *Pool) MaxWorkers () int32 { + return atomic.LoadInt32(&p.max) } + +func (p *Pool) SetMaxWorkers (max int32) { + if max <= 0 { + max = maxWorkers + } + atomic.StoreInt32(&p.max,max) +} + + +func (p *Pool) WorkerCap () int32 { + return atomic.LoadInt32(&p.cap) } + +func (p *Pool) SetWorkerCap (cap int32) { + if cap <= 0 { + cap = 0 + } + atomic.StoreInt32(&p.cap,cap) +} + + +func (p *Pool) MaxWorkerIdle () time.Duration { + return time.Duration(atomic.LoadInt64(&p.maxIdle)) } + +func (p *Pool) SetMaxWorkerIdle (idle time.Duration) { + if idle < minIdle { + idle = minIdle + } + atomic.StoreInt64(&p.maxIdle,int64(idle)) +} + + + + + +func (p *Pool) Done () <- chan struct{} { + return p.doneCh } + + + +func (p *Pool) Start () error { + p.mux.Lock() + + st := p.State() + if st == PoolStateRunning { + p.mux.Unlock() + return G.ErrPoolStarted + } + if st == PoolStateStopped { + atomic.StoreInt32(&p.count,0) + } + + p.doneCh = make(chan struct{}) + p.mux.Unlock() + + go func(p *Pool) { + atomic.StoreUint32(&p.state,uint32(PoolStateRunning)) + var ls []*worker + for { + p.clearWorkers(&ls) + select { + case <- p.doneCh: + return + default: + time.Sleep(time.Duration(atomic.LoadInt64(&p.maxIdle))) + } + } + }(p) + + return nil +} + + +func (p *Pool) Stop () error { + p.mux.Lock() + if p.State() != PoolStateRunning { + p.mux.Unlock() + return G.ErrPoolStopped + } + atomic.StoreUint32(&p.state,uint32(PoolStateStopped)) + + close(p.doneCh) + p.doneCh = nil + ws := p.workers + + for ix,wk := range ws { + wk.jobCh <- nil + ws[ix]=nil + } + + p.workers = ws[:0] + + p.mux.Unlock() + return nil +} + + +func (p *Pool) DoWork(ctx context.Context, job func()) error { + p.mux.Lock() + if p.State() != PoolStateRunning { + p.mux.Unlock() + return G.ErrPoolStopped + } + + wk := (*worker)(nil) + ws := p.workers + ln := len(ws) - 1 + + if ln >= 0 { + wk = ws[ln] + ws[ln] = nil + p.workers = ws[:ln] + p.mux.Unlock() + } else { + p.mux.Unlock() + + if atomic.LoadInt32(&p.count) >= atomic.LoadInt32(&p.max) { + return G.ErrPoolAcquire + } + atomic.AddInt32(&p.count,1) + wk = p.pool.Get().(*worker) + + go func(p *Pool, w *worker, x context.Context) { + + for job := range w.jobCh { + if job == nil { + break + } + job() + job = nil + + p.mux.Lock() + done := false + if p.State() != PoolStateStopped { + w.lastTime = time.Now() + p.workers = append(p.workers, w) + done = true + p.stats.AddReleased() + } + p.mux.Unlock() + if !done { + break + } + } + atomic.AddInt32(&p.count,-1) + p.pool.Put(w) + + }(p,wk,ctx) + + } + + p.stats.AddAcquired() + wk.jobCh <- job + return nil +} + + + + +func (p *Pool) clearWorkers (cls *[]*worker) { + p.mux.Lock() + tm := time.Now() + mi := time.Duration(atomic.LoadInt64(&p.maxIdle)) + ws := p.workers + ln := len(ws) + ix := 0 + + for ix mi { + ix++ + } + *cls = append((*cls)[:0],ws[:ix]...) + if ix > 0 { + nt := copy(ws,ws[ix:]) + for ix:= nt; ix= 'A' && v <= 'Z' + vIsLow := v >= 'a' && v <= 'z' + if capNext { + if vIsLow { + v += 'A' + v -= 'a' + } + } else if i == 0 { + if vIsCap { + v += 'a' + v -= 'A' + } + } else if prevIsCap && vIsCap && !hasAcronym { + v += 'a' + v -= 'A' + } + prevIsCap = vIsCap + + if vIsCap || vIsLow { + n.WriteByte(v) + capNext = false + } else if vIsNum := v >= '0' && v <= '9'; vIsNum { + n.WriteByte(v) + capNext = true + } else { + capNext = v == '_' || v == ' ' || v == '-' || v == '.' + } + } + return n.String() +} + +// ToCamel converts a string to CamelCase +func ToCamel(s string) string { + return toCamelInitCase(s, true) +} + +// ToLowerCamel converts a string to lowerCamelCase +func ToLowerCamel(s string) string { + return toCamelInitCase(s, false) +} \ No newline at end of file diff --git a/core/typs/astrings/err_astrings.go b/core/typs/astrings/err_astrings.go new file mode 100644 index 0000000..cec6e0e --- /dev/null +++ b/core/typs/astrings/err_astrings.go @@ -0,0 +1,51 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name err_astrings.go +// Created by DEV +// Modified 26/04/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package astrings + + +import "errs/erdata" + +type ( + + // ErrAStrings no puede heredar directamente de Errs.Code + // ya que es utilizada por fjson y ftext lo que crea + // un ciclo de importaciones + // + ErrAStrings string +) + + +func (e ErrAStrings) Error() string { + return string(e) } + + +func (e ErrAStrings) Code () string { + return string(e) } + + + +func (e ErrAStrings) Collect (c erdata.Collector) { + c.AddFieldString(erdata.FieldNameCode,string(e)) } + + diff --git a/core/typs/astrings/snake.go b/core/typs/astrings/snake.go new file mode 100644 index 0000000..f1b7d75 --- /dev/null +++ b/core/typs/astrings/snake.go @@ -0,0 +1,117 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name snake.go +// Created by DEV +// Modified 31/03/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ +// https://github.com/iancoleman/strcase/blob/v0.3.0/snake.go + +package astrings + +import "strings" + + + +// ToSnake converts a string to snake_case +func ToSnake(s string) string { + return ToDelimited(s, '_') +} + + +func ToSnakeWithIgnore(s string, ignore string) string { + return ToUDelimited(s, '_', ignore, false) +} + +// ToUSnake converts a string to SCREAMING_SNAKE_CASE +func ToUSnake(s string) string { + return ToUDelimited(s, '_', "", true) +} + +// ToKebab converts a string to kebab-case +func ToKebab(s string) string { + return ToDelimited(s, '-') +} + +// ToUKebab converts a string to SCREAMING-KEBAB-CASE +func ToUKebab(s string) string { + return ToUDelimited(s, '-', "", true) +} + + + +// ToDelimited converts a string to delimited.snake.case +// (in this case `delimiter = '.'`) +func ToDelimited(s string, delimiter uint8) string { + return ToUDelimited(s, delimiter, "", false) +} + +// ToUDelimited converts a string to SCREAMING.DELIMITED.SNAKE.CASE +// (in this case `delimiter = '.'; upper = true`) +// or delimited.snake.case +// (in this case `delimiter = '.'; screaming = false`) +func ToUDelimited(s string, delimiter uint8, ignore string, upper bool) string { + s = strings.TrimSpace(s) + n := strings.Builder{} + n.Grow(len(s) + 2) // nominal 2 bytes of extra space for inserted delimiters + for i, v := range []byte(s) { + vIsCap := v >= 'A' && v <= 'Z' + vIsLow := v >= 'a' && v <= 'z' + if vIsLow && upper { + v += 'A' + v -= 'a' + } else if vIsCap && !upper { + v += 'a' + v -= 'A' + } + + // treat acronyms as words, eg for JSONData -> JSON is a whole word + if i+1 < len(s) { + next := s[i+1] + vIsNum := v >= '0' && v <= '9' + nextIsCap := next >= 'A' && next <= 'Z' + nextIsLow := next >= 'a' && next <= 'z' + nextIsNum := next >= '0' && next <= '9' + // add underscore if next letter case type is changed + if (vIsCap && (nextIsLow || nextIsNum)) || (vIsLow && (nextIsCap || nextIsNum)) || (vIsNum && (nextIsCap || nextIsLow)) { + prevIgnore := ignore != "" && i > 0 && strings.ContainsAny(string(s[i-1]), ignore) + if !prevIgnore { + if vIsCap && nextIsLow { + if prevIsCap := i > 0 && s[i-1] >= 'A' && s[i-1] <= 'Z'; prevIsCap { + n.WriteByte(delimiter) + } + } + n.WriteByte(v) + if vIsLow || vIsNum || nextIsNum { + n.WriteByte(delimiter) + } + continue + } + } + } + + if (v == ' ' || v == '_' || v == '-' || v == '.') && !strings.ContainsAny(string(v), ignore) { + // replace space/underscore/hyphen/dot with delimiter + n.WriteByte(delimiter) + } else { + n.WriteByte(v) + } + } + + return n.String() +} \ No newline at end of file diff --git a/core/typs/astrings/string.go b/core/typs/astrings/string.go new file mode 100644 index 0000000..e1e6384 --- /dev/null +++ b/core/typs/astrings/string.go @@ -0,0 +1,59 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name string.go +// Created by DEV +// Modified 29/03/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package astrings + +import ( + "strings" +) + + + + +func Split(source string, size int) []string { + var ls []string + for i := 0; i < len(source); i += size { + // Calcula el tamaño máximo para el fragmento actual + re := len(source) - i + fs := min(size, re) + ln := source[i : i+fs] + ls = append(ls, ln) + } + return ls +} + +func Pad(source string, size int, chr byte, truncate bool) string { + cn := size - len(source) + if cn == 0 { + return source + } + if cn < 0 { + if truncate { + return source[:size] + } + return source + } + return source + strings.Repeat(string(chr),cn) +} + + diff --git a/core/typs/astrings/transformer.go b/core/typs/astrings/transformer.go new file mode 100644 index 0000000..1da45fe --- /dev/null +++ b/core/typs/astrings/transformer.go @@ -0,0 +1,42 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name string_adapter.go +// Created by DEV +// Modified 31/03/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package astrings + + + +type ( + + + Transformer interface { + Transform (value string) string + } + + + TransformFnc func (value string) string + +) + + +func (f TransformFnc) Transform (value string) string { + return f(value) } \ No newline at end of file diff --git a/core/typs/astrings/transformers.go b/core/typs/astrings/transformers.go new file mode 100644 index 0000000..0c98b20 --- /dev/null +++ b/core/typs/astrings/transformers.go @@ -0,0 +1,58 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name transformers.go +// Created by DEV +// Modified 18/04/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package astrings + +import "errs/erfield" + +type ( + + + Transformers []Transformer +) + + +func MakeTransformers (names ...string) Transformers { + var l Transformers + for _,name := range names { + if t := GetTransformer(name); t != nil { + l = append(l, t) + continue + } + panic(erfield.NewFieldString(G.ErrTransformerNotFound,"transformer",name)) + } + return l +} + +func (a Transformers) Transform (value string) string { + if len(a) == 0 { + return value + } + s := value + for _,f := range a { + s = f.Transform(s) + } + return s +} + + diff --git a/core/typs/go.mod b/core/typs/go.mod new file mode 100644 index 0000000..942c488 --- /dev/null +++ b/core/typs/go.mod @@ -0,0 +1,3 @@ +module typs + +go 1.22 diff --git a/core/typs/numbers.go b/core/typs/numbers.go new file mode 100644 index 0000000..10a8048 --- /dev/null +++ b/core/typs/numbers.go @@ -0,0 +1,51 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name generics.go +// Created by DEV +// Modified 17/01/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package typs + +type ( + + Unsigned interface { + uint | uint8 | uint16 | uint32 | uint64 + } + + UnsignedAll interface { + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 + } + + Signed interface { + int | int8 | int16 | int32 | int64 + } + + SignedAll interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 + } + + Integer interface{ Signed | Unsigned } + + Float interface{ float32 | float64 } + + Complex interface{ complex64 | complex128 } + + Number interface{ Integer | Float | Complex } +) diff --git a/core/typs/slices/strings.go b/core/typs/slices/strings.go new file mode 100644 index 0000000..5c849cc --- /dev/null +++ b/core/typs/slices/strings.go @@ -0,0 +1,58 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name string.go +// Created by DEV +// Modified 16/01/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package slices + + + +type Strings []string + + + + +func MakeStrings(size, capacity int) Strings { + return make(Strings, size, capacity) +} + +func (s Strings) Reset() Strings { + if s != nil { + return s[:0] + } + return s +} + +func (s Strings) Has(value string) bool { + if len(s) == 0 { + return false + } + for _, k := range s { + if k == value { + return true + } + } + return false +} + +func (s Strings) Append(value string) Strings { + return append(s, value) +} diff --git a/core/vals/active.go b/core/vals/active.go new file mode 100644 index 0000000..442a274 --- /dev/null +++ b/core/vals/active.go @@ -0,0 +1,24 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name active.go +// Created by DEV +// Modified 19/03/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package vals diff --git a/core/vals/g_name_valuer.go b/core/vals/g_name_valuer.go new file mode 100644 index 0000000..838ac06 --- /dev/null +++ b/core/vals/g_name_valuer.go @@ -0,0 +1,33 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name name_valuer_g.go +// Created by DEV +// Modified 19/03/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package vals + +type ( + + GNameValuer[T any] interface { + Namer + GValuer[T] + } + +) diff --git a/core/vals/g_valuer.go b/core/vals/g_valuer.go new file mode 100644 index 0000000..0c43168 --- /dev/null +++ b/core/vals/g_valuer.go @@ -0,0 +1,40 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name gvaluer.go +// Created by DEV +// Modified 19/03/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package vals + +type ( + + + GValuer[T any] interface { + Value() T + } + + + GValuerFnc[T any] func() T + + +) + +func (f GValuerFnc[T]) Value() T { + return f() } diff --git a/core/vals/go.mod b/core/vals/go.mod new file mode 100644 index 0000000..b795869 --- /dev/null +++ b/core/vals/go.mod @@ -0,0 +1,3 @@ +module vals + +go 1.22 diff --git a/core/vals/key_value_getter.go b/core/vals/key_value_getter.go new file mode 100644 index 0000000..1565135 --- /dev/null +++ b/core/vals/key_value_getter.go @@ -0,0 +1,50 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name value_provider.go +// Created by DEV +// Modified 19/03/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package vals + +type ( + + KeyValueGetter interface { + + GetKeyValue(key any) (any, bool) + + } + + + + GetKeyValueFnc func(key any) (any, bool) + + +) + + + +func (f GetKeyValueFnc) GetKeyValue(key any) (any, bool) { + return f(key) } + + + + +func nopGetKeyValue (_ any) (any,bool) { + return nil,false } \ No newline at end of file diff --git a/core/vals/key_value_setter.go b/core/vals/key_value_setter.go new file mode 100644 index 0000000..9ce4a7e --- /dev/null +++ b/core/vals/key_value_setter.go @@ -0,0 +1,42 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name key_value_setter.go +// Created by DEV +// Modified 19/03/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package vals + +type ( + + + KeyValueSetter interface { + + SetKeyValue(key, value any) error + + } + + + SetKeyValueFnc func(key, value any) error + +) + + +func (f SetKeyValueFnc) Key(key, value any) error { + return f(key,value) } \ No newline at end of file diff --git a/core/vals/name_valuer.go b/core/vals/name_valuer.go new file mode 100644 index 0000000..6643ddf --- /dev/null +++ b/core/vals/name_valuer.go @@ -0,0 +1,35 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name name_valuer.go +// Created by DEV +// Modified 19/03/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package vals + +type ( + + + NameValuer interface { + + Name () string // Namer + Value() any // Valuer + } + +) diff --git a/core/vals/namer.go b/core/vals/namer.go new file mode 100644 index 0000000..cc07edd --- /dev/null +++ b/core/vals/namer.go @@ -0,0 +1,38 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name namer.go +// Created by DEV +// Modified 19/03/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package vals + +type ( + + + Namer interface { + Name() string + } + + NameFnc func() string +) + + +func (f NameFnc) Name() string { + return f() } diff --git a/core/vals/scope.go b/core/vals/scope.go new file mode 100644 index 0000000..e0742e0 --- /dev/null +++ b/core/vals/scope.go @@ -0,0 +1,98 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name scope.go +// Created by DEV +// Modified 19/03/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package vals + +import "sync" + +type ( + + Scope struct { + atts ScopeAtt + parent KeyValueGetter + values sync.Map + } + + + ScopeFnc func(*Scope) + +) + + +func NewScope(options ...ScopeFnc) *Scope { + return applyScopeOptions(&Scope{ parent: GetKeyValueFnc(nopGetKeyValue)}, options...) } + + +func (s *Scope) NewChildScope(options ...ScopeFnc) *Scope { + return applyScopeOptions(&Scope{parent: s },options ...) } + + + +func (s *Scope) Atts () ScopeAtt { + return s.atts } + + + +func (s *Scope) GetKeyValue(key any) (any, bool) { + if key == nil { + return nil, false + } + v, h := s.values.Load(key) + if !h { + v, h = s.parent.GetKeyValue(key) + } + if h { + return AsValue(v), true + } + return nil, false +} + + +func (s *Scope) SetKeyValue(key any, value any) error { + if key == nil { + //todo error + } + if s.atts.IsReadOnly() { + //todo error + } + s.values.Store(key, AsValuer(value)) + return nil +} + + +func (s *Scope) DelKeyValue (key any) { + s.values.Delete(key) } + + + + +func (s *Scope) Range (f func(key, value any) bool) { + s.values.Range(f) } + + +func (s *Scope) Reset () { + s.values.Range(func(k,v any) bool { + s.values.Delete(k) + return true + }) +} \ No newline at end of file diff --git a/core/vals/scope_att.go b/core/vals/scope_att.go new file mode 100644 index 0000000..9900238 --- /dev/null +++ b/core/vals/scope_att.go @@ -0,0 +1,36 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name scope_att.go +// Created by DEV +// Modified 19/03/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package vals + +const ( + ScopeAttReadOnly ScopeAtt = 1 << iota +) + +type ( + ScopeAtt uint8 +) + +func (a ScopeAtt) IsReadOnly() bool { + return a&ScopeAttReadOnly != 0 +} diff --git a/core/vals/scope_ops.go b/core/vals/scope_ops.go new file mode 100644 index 0000000..f88f627 --- /dev/null +++ b/core/vals/scope_ops.go @@ -0,0 +1,33 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name scope_ops.go +// Created by DEV +// Modified 19/03/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package vals + + + +func applyScopeOptions(scope *Scope, options ...ScopeFnc) *Scope { + for _, o := range options { + o(scope) + } + return scope +} diff --git a/core/vals/valuer.go b/core/vals/valuer.go new file mode 100644 index 0000000..7b9c00e --- /dev/null +++ b/core/vals/valuer.go @@ -0,0 +1,71 @@ +// ------------------------------------------------------------------------ +// Project active2 +// Active Thing (activething.com) git.activething.com/go +// +// File name value_provider.go +// Created by DEV +// Modified 19/03/2024 +// +// Copyright 2024 activething.com +// ------------------------------------------------------------------------ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +package vals + +type ( + + Valuer interface { + Value() any + } + + ValueFnc func() any +) + + +func (f ValueFnc) Value() any { + return f() +} + + + +func AsValuer(value any) Valuer { + if value == nil { + return ValueFnc(nopValue) + } + switch v := value.(type) { + case Valuer: + return v + case func() any: + return ValueFnc(v) + default: + return ValueFnc(func() any { return value }) + } +} + +func AsValue(value any) any { + if value == nil { + return nil + } + if vl, is := value.(Valuer); is { + return vl.Value() + } + if vl, is := value.(func() any); is { + return vl() + } + return value +} + +func nopValue() any { + return nil +} diff --git a/go.work b/go.work index 19e9da1..f410ea2 100644 --- a/go.work +++ b/go.work @@ -1,14 +1,17 @@ go 1.22 use ( - ./A ./A/test - ./core/errs + ./base/apcks + ./core/bits ./core/blds ./core/btes + ./core/errs ./core/flds ./core/mems + ./core/opts + ./core/syns + ./core/typs - -) \ No newline at end of file +)