add nomutex support to disable it per message struct
This commit is contained in:
parent
721bbd8f92
commit
10f75f87a6
4
Makefile
4
Makefile
|
@ -47,6 +47,10 @@ build: goimports
|
||||||
bak:
|
bak:
|
||||||
mv -f autogenpb autogenpb.last
|
mv -f autogenpb autogenpb.last
|
||||||
|
|
||||||
|
redo-protobuf:
|
||||||
|
rm -f *.pb.go
|
||||||
|
autogenpb --proto file.proto --package main
|
||||||
|
|
||||||
install: test
|
install: test
|
||||||
GO111MODULE=off go install \
|
GO111MODULE=off go install \
|
||||||
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
|
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
|
||||||
|
|
|
@ -15,24 +15,24 @@ package main;
|
||||||
|
|
||||||
import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp
|
import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp
|
||||||
|
|
||||||
message Apple { // `autogenpb:marshal`
|
message Apple {
|
||||||
string name = 1; // `autogenpb:unique` // generates SortByxxx() and AppendUnique() functions
|
string name = 1; // `autogenpb:unique` // generates SortByxxx() and AppendUnique() functions
|
||||||
string genus = 2; // `autogenpb:unique` // generates same thing here but SortByGenus()
|
string genus = 2; // `autogenpb:unique` // generates same thing here but SortByGenus()
|
||||||
google.protobuf.Timestamp ctime = 3; // when the apple was born
|
google.protobuf.Timestamp ctime = 3; // when the apple was born
|
||||||
}
|
}
|
||||||
|
|
||||||
message Pear {
|
message Pear { // `autogenpb:nomutex`
|
||||||
string name = 1; // `autogenpb:sort`
|
string name = 1; // `autogenpb:sort`
|
||||||
string favorite = 2; // `autogenpb:sort` `autogenpb:unique`
|
string favorite = 2; // `autogenpb:sort` `autogenpb:unique`
|
||||||
}
|
}
|
||||||
|
|
||||||
message Banana {
|
message Banana { // `autogenpb:nomutex`
|
||||||
repeated string name = 1; // `autogenpb:sort`
|
repeated string name = 1; // `autogenpb:sort`
|
||||||
string favorite = 2; // `autogenpb:sort` `autogenpb:unique`
|
string favorite = 2; // `autogenpb:sort` `autogenpb:unique`
|
||||||
string country = 3; // `autogenpb:sort`
|
string country = 3; // `autogenpb:sort`
|
||||||
}
|
}
|
||||||
|
|
||||||
message Basket {
|
message Basket { // `autogenpb:nomutex`
|
||||||
repeated string name = 1; // `autogenpb:sort` `autogenpb:unique`
|
repeated string name = 1; // `autogenpb:sort` `autogenpb:unique`
|
||||||
string favorite = 2; // `autogenpb:sort` `autogenpb:unique`
|
string favorite = 2; // `autogenpb:sort` `autogenpb:unique`
|
||||||
int64 price = 3; // `autogenpb:sort`
|
int64 price = 3; // `autogenpb:sort`
|
||||||
|
@ -42,7 +42,7 @@ message Basket {
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Fruit" must exist. you can put anything in it
|
// "Fruit" must exist. you can put anything in it
|
||||||
message Fruit { // `autogenpb:marshal`
|
message Fruit {
|
||||||
string brand = 1; // `autogenpb:unique` `autogenpb:sort`
|
string brand = 1; // `autogenpb:unique` `autogenpb:sort`
|
||||||
repeated Apple apples = 2;
|
repeated Apple apples = 2;
|
||||||
repeated Pear pears = 3;
|
repeated Pear pears = 3;
|
||||||
|
|
|
@ -45,6 +45,7 @@ message MsgName {
|
||||||
repeated MsgVar vars = 9; // store all the vars in the message
|
repeated MsgVar vars = 9; // store all the vars in the message
|
||||||
bool needIter = 10; // true if the sort iterator has not been generated yet
|
bool needIter = 10; // true if the sort iterator has not been generated yet
|
||||||
bool needAll = 11; // true if the sort iterator has not been generated yet
|
bool needAll = 11; // true if the sort iterator has not been generated yet
|
||||||
|
bool noMutex = 12; // only use the global mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
message Sort {
|
message Sort {
|
||||||
|
|
17
generate.go
17
generate.go
|
@ -60,7 +60,13 @@ func (pb *Files) makeNewSortfile(pf *File) error {
|
||||||
APPLE := s.VarType
|
APPLE := s.VarType
|
||||||
APPLES := s.VarName
|
APPLES := s.VarName
|
||||||
LOCK := s.Lockname
|
LOCK := s.Lockname
|
||||||
funcdef := newIterAll(wSort, FRUIT, APPLE, APPLES, LOCK)
|
|
||||||
|
msg := pf.findMsg(s.VarType)
|
||||||
|
if msg == nil {
|
||||||
|
return fmt.Errorf("failed to find struct %s", s.VarType)
|
||||||
|
}
|
||||||
|
|
||||||
|
funcdef := msg.newIterAll(wSort, FRUIT, APPLE, APPLES, LOCK)
|
||||||
log.Printf("JUNK: %-2d %20s %20s %20s %20s %s\n", i, FRUIT, APPLE, "", LOCK, funcdef)
|
log.Printf("JUNK: %-2d %20s %20s %20s %20s %s\n", i, FRUIT, APPLE, "", LOCK, funcdef)
|
||||||
}
|
}
|
||||||
log.Printf("\n")
|
log.Printf("\n")
|
||||||
|
@ -73,7 +79,12 @@ func (pb *Files) makeNewSortfile(pf *File) error {
|
||||||
VARNAME := s.VarName
|
VARNAME := s.VarName
|
||||||
LOCK := s.Lockname
|
LOCK := s.Lockname
|
||||||
|
|
||||||
funcdef := addSelectAll(wSort, PARENT, CHILD, VARNAME, LOCK)
|
msg := pf.findMsg(s.VarType)
|
||||||
|
if msg == nil {
|
||||||
|
return fmt.Errorf("failed to find struct %s", s.VarType)
|
||||||
|
}
|
||||||
|
|
||||||
|
funcdef := msg.addSelectAll(wSort, PARENT, CHILD, VARNAME, LOCK)
|
||||||
log.Printf("SORT: %-2d %20s %20s %20s %20s %s\n", i, PARENT, CHILD, VARNAME, LOCK, funcdef)
|
log.Printf("SORT: %-2d %20s %20s %20s %20s %s\n", i, PARENT, CHILD, VARNAME, LOCK, funcdef)
|
||||||
}
|
}
|
||||||
log.Printf("END SELECT\n")
|
log.Printf("END SELECT\n")
|
||||||
|
@ -121,7 +132,7 @@ func (pb *Files) makeNewSortfile(pf *File) error {
|
||||||
}
|
}
|
||||||
sortname := s.VarType + v.VarName
|
sortname := s.VarType + v.VarName
|
||||||
selectName := "selectAll" + VARNAME
|
selectName := "selectAll" + VARNAME
|
||||||
funcdef := newSortBy(wSort, PARENT, s.VarType, sortname, sortby, selectName)
|
funcdef := newSortBy(wSort, PARENT, s.VarType, sortname, sortby, selectName, v.VarName)
|
||||||
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "", "", funcdef)
|
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "", "", funcdef)
|
||||||
} else {
|
} else {
|
||||||
funcname := "func (x *" + FUNCTYPE + ") SortBy" + v.VarName + "(" + v.VarType + ") *[]iter" + s.VarType + " # can not do this yet"
|
funcname := "func (x *" + FUNCTYPE + ") SortBy" + v.VarName + "(" + v.VarType + ") *[]iter" + s.VarType + " # can not do this yet"
|
||||||
|
|
|
@ -7,17 +7,6 @@ import (
|
||||||
|
|
||||||
// generates Find() and some other stuff
|
// generates Find() and some other stuff
|
||||||
|
|
||||||
func (msg *MsgName) getLockname(s string) string {
|
|
||||||
// leave this function stubbed in for development of autogenpb
|
|
||||||
// if argv.Mutex {
|
|
||||||
// // use the mutex lock from the modified protoc.pb.go file
|
|
||||||
// return s + ".Lock"
|
|
||||||
// // return s // causes Marshal() to panic? always use the variable name 'Lock'?
|
|
||||||
// }
|
|
||||||
// a single global lock by struct name
|
|
||||||
return msg.Lockname
|
|
||||||
}
|
|
||||||
|
|
||||||
func (msg *MsgName) generateFindBy(w io.Writer, FUNCNAME, STRUCT, VARNAME, VARTYPE, COLOR string) string {
|
func (msg *MsgName) generateFindBy(w io.Writer, FUNCNAME, STRUCT, VARNAME, VARTYPE, COLOR string) string {
|
||||||
LOCK := msg.getLockname("x")
|
LOCK := msg.getLockname("x")
|
||||||
funcdef := "func (x *" + STRUCT + ") " + FUNCNAME + "(s string) *" + VARTYPE
|
funcdef := "func (x *" + STRUCT + ") " + FUNCNAME + "(s string) *" + VARTYPE
|
||||||
|
|
|
@ -13,8 +13,19 @@ import (
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (msg *MsgName) getLockname(s string) string {
|
||||||
|
// leave this function stubbed in for development of autogenpb
|
||||||
|
// if argv.Mutex {
|
||||||
|
// // use the mutex lock from the modified protoc.pb.go file
|
||||||
|
// return s + ".Lock"
|
||||||
|
// // return s // causes Marshal() to panic? always use the variable name 'Lock'?
|
||||||
|
// }
|
||||||
|
// a single global lock by struct name
|
||||||
|
return msg.Lockname
|
||||||
|
}
|
||||||
|
|
||||||
func (pf *File) syncLock(w io.Writer) {
|
func (pf *File) syncLock(w io.Writer) {
|
||||||
var LOCK string = pf.Base.Lockname // if the Marshall code changes, this will have to change
|
var LOCK string = pf.Filebase + "Mu" // this should be lowercase. do not export the Mutex
|
||||||
|
|
||||||
fmt.Fprintln(w, "// a simple global lock")
|
fmt.Fprintln(w, "// a simple global lock")
|
||||||
fmt.Fprintln(w, "var "+LOCK+" sync.RWMutex")
|
fmt.Fprintln(w, "var "+LOCK+" sync.RWMutex")
|
||||||
|
@ -110,7 +121,6 @@ func (pf *File) structMatch(line string) bool {
|
||||||
start = "type " + msg.Name + " struct {"
|
start = "type " + msg.Name + " struct {"
|
||||||
if strings.HasPrefix(line, start) {
|
if strings.HasPrefix(line, start) {
|
||||||
msg.MutexFound = true
|
msg.MutexFound = true
|
||||||
msg.Lockname = "x.Lock"
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +130,7 @@ func (pf *File) structMatch(line string) bool {
|
||||||
start = "type " + msg.Name + " struct {"
|
start = "type " + msg.Name + " struct {"
|
||||||
if strings.HasPrefix(line, start) {
|
if strings.HasPrefix(line, start) {
|
||||||
msg.MutexFound = true
|
msg.MutexFound = true
|
||||||
// msg.Lockname = "x.Lock"
|
msg.Lockname = "x.Lock"
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +138,11 @@ func (pf *File) structMatch(line string) bool {
|
||||||
start = "type " + msg.Name + " struct {"
|
start = "type " + msg.Name + " struct {"
|
||||||
if strings.HasPrefix(line, start) {
|
if strings.HasPrefix(line, start) {
|
||||||
msg.MutexFound = true
|
msg.MutexFound = true
|
||||||
// msg.Lockname = "x.Lock"
|
if msg.NoMutex {
|
||||||
|
msg.Lockname = pf.Filebase + "Mu" // this should be lowercase. do not export the Mutex
|
||||||
|
} else {
|
||||||
|
msg.Lockname = "x.Lock"
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,9 @@ import (
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newIterAll(w io.Writer, FRUIT, APPLE, APPLES, LOCK string) string {
|
func (msg *MsgName) newIterAll(w io.Writer, FRUIT, APPLE, APPLES, LOCK string) string {
|
||||||
|
LOCK = msg.getLockname("x")
|
||||||
|
|
||||||
funcdef := "func (x *" + FRUIT + ") all" + APPLES + "() []*" + APPLE + " {"
|
funcdef := "func (x *" + FRUIT + ") all" + APPLES + "() []*" + APPLE + " {"
|
||||||
|
|
||||||
fmt.Fprintln(w, "// safely returns a slice of pointers to the FRUIT protobufs")
|
fmt.Fprintln(w, "// safely returns a slice of pointers to the FRUIT protobufs")
|
||||||
|
@ -35,7 +37,9 @@ func newIter(w io.Writer, msg *MsgName) string {
|
||||||
msg.NeedIter = false
|
msg.NeedIter = false
|
||||||
APPLE := msg.Name
|
APPLE := msg.Name
|
||||||
|
|
||||||
funcdef := "func New" + APPLE + "Iterator(things []*" + APPLE + ") *" + APPLE + "Iterator"
|
// should this be 'new' or 'New' ? Does it matter? I think it's totally internal here
|
||||||
|
// in this file where it is "new or "New". I changed it to lower case 2025.01.12
|
||||||
|
funcdef := "func new" + APPLE + "Iterator(things []*" + APPLE + ") *" + APPLE + "Iterator"
|
||||||
|
|
||||||
fmt.Fprintln(w, "// DEFINE THE", APPLE, "ITERATOR.")
|
fmt.Fprintln(w, "// DEFINE THE", APPLE, "ITERATOR.")
|
||||||
fmt.Fprintln(w, "// itializes a new iterator.")
|
fmt.Fprintln(w, "// itializes a new iterator.")
|
||||||
|
@ -76,6 +80,8 @@ func newIter(w io.Writer, msg *MsgName) string {
|
||||||
// TODO; figure out what types this actually works on
|
// TODO; figure out what types this actually works on
|
||||||
// TODO; add timestamppb compare
|
// TODO; add timestamppb compare
|
||||||
func newSortType(w io.Writer, STRUCT, VARNAME string) string {
|
func newSortType(w io.Writer, STRUCT, VARNAME string) string {
|
||||||
|
|
||||||
|
// Can these be lower case? Should they be lower case? maybe sort.Sort() requires upper case?
|
||||||
fmt.Fprintln(w, "// sort struct by", VARNAME)
|
fmt.Fprintln(w, "// sort struct by", VARNAME)
|
||||||
fmt.Fprintln(w, "type "+STRUCT+VARNAME+" []*"+STRUCT+"")
|
fmt.Fprintln(w, "type "+STRUCT+VARNAME+" []*"+STRUCT+"")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
|
@ -87,16 +93,21 @@ func newSortType(w io.Writer, STRUCT, VARNAME string) string {
|
||||||
return "type " + STRUCT + VARNAME + " []*" + STRUCT + " // { return a[i]." + VARNAME + " < a[j]." + VARNAME + " }"
|
return "type " + STRUCT + VARNAME + " []*" + STRUCT + " // { return a[i]." + VARNAME + " < a[j]." + VARNAME + " }"
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSortBy(w io.Writer, STRUCT, ITER, SORTNAME, SORTBY, SELECT string) string {
|
func newSortBy(w io.Writer, STRUCT, ITER, SORTNAME, SORTBY, SELECT, VARNAME string) string {
|
||||||
funcdef := "func (x *" + STRUCT + ") " + SORTBY + "() *" + ITER + "Iterator"
|
funcdef := "func (x *" + STRUCT + ") " + SORTBY + "() *" + ITER + "Iterator"
|
||||||
|
|
||||||
fmt.Fprintln(w, funcdef, "{")
|
fmt.Fprintln(w, funcdef, "{")
|
||||||
|
fmt.Fprintln(w, " // copy the pointers as fast as possible.")
|
||||||
fmt.Fprintln(w, " things := x."+SELECT+"()")
|
fmt.Fprintln(w, " things := x."+SELECT+"()")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
|
fmt.Fprintln(w, "// todo: try slices.SortFunc() instead to see what happens")
|
||||||
fmt.Fprintln(w, " sort.Sort("+SORTNAME+"(things))")
|
fmt.Fprintln(w, " sort.Sort("+SORTNAME+"(things))")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "// slices.SortFunc(things, func(a, b *"+STRUCT+") bool {")
|
||||||
fmt.Fprintln(w, " iterator := New"+ITER+"Iterator(things)")
|
fmt.Fprintln(w, "// return a."+VARNAME+" < b."+VARNAME+" // Sort by ??. let the compiler work it out??")
|
||||||
fmt.Fprintln(w, " return iterator")
|
fmt.Fprintln(w, "// })")
|
||||||
|
// should this be 'new' or 'New' ? Does it matter? I think it's totally internal here
|
||||||
|
// in this file where it is "new or "New". I changed it to lower case 2025.01.12
|
||||||
|
fmt.Fprintln(w, " return new"+ITER+"Iterator(things)")
|
||||||
fmt.Fprintln(w, "}")
|
fmt.Fprintln(w, "}")
|
||||||
|
|
||||||
return funcdef
|
return funcdef
|
||||||
|
@ -108,7 +119,9 @@ func addAllFunc(w io.Writer, FRUIT, APPLE, APPLES string) string {
|
||||||
fmt.Fprintln(w, funcdef)
|
fmt.Fprintln(w, funcdef)
|
||||||
fmt.Fprintln(w, " "+APPLE+"Pointers := x.selectAll"+APPLES+"()")
|
fmt.Fprintln(w, " "+APPLE+"Pointers := x.selectAll"+APPLES+"()")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
fmt.Fprintln(w, " iterator := New"+APPLE+"Iterator("+APPLE+"Pointers)")
|
// should this be 'new' or 'New' ? Does it matter? I think it's totally internal here. I think there are only 3 places
|
||||||
|
// in this file where it is "new or "New". I changed it to lower case 2025.01.12
|
||||||
|
fmt.Fprintln(w, " iterator := new"+APPLE+"Iterator("+APPLE+"Pointers)")
|
||||||
fmt.Fprintln(w, " return iterator")
|
fmt.Fprintln(w, " return iterator")
|
||||||
fmt.Fprintln(w, "}")
|
fmt.Fprintln(w, "}")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
|
@ -130,7 +143,9 @@ func addLenFunc(w io.Writer, FRUIT, APPLES, LOCK string) string {
|
||||||
return funcdef
|
return funcdef
|
||||||
}
|
}
|
||||||
|
|
||||||
func addSelectAll(w io.Writer, FRUIT, APPLE, APPLES, LOCK string) string {
|
func (msg *MsgName) addSelectAll(w io.Writer, FRUIT, APPLE, APPLES, LOCK string) string {
|
||||||
|
LOCK = msg.getLockname("x")
|
||||||
|
|
||||||
funcdef := "func (x *" + FRUIT + ") selectAll" + APPLES + "() []*" + APPLE
|
funcdef := "func (x *" + FRUIT + ") selectAll" + APPLES + "() []*" + APPLE
|
||||||
fmt.Fprintln(w, "// safely returns a slice of pointers to the "+APPLE+" protobufs")
|
fmt.Fprintln(w, "// safely returns a slice of pointers to the "+APPLE+" protobufs")
|
||||||
fmt.Fprintln(w, funcdef, "{")
|
fmt.Fprintln(w, funcdef, "{")
|
||||||
|
|
2
main.go
2
main.go
|
@ -26,7 +26,7 @@ import (
|
||||||
var VERSION string
|
var VERSION string
|
||||||
var BUILDTIME string
|
var BUILDTIME string
|
||||||
|
|
||||||
var fsort *os.File // the sort.pb.go output file
|
// var fsort *os.File // the sort.pb.go output file
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
pp := arg.MustParse(&argv)
|
pp := arg.MustParse(&argv)
|
||||||
|
|
|
@ -265,6 +265,10 @@ func (pf *File) parseForMessage(line string) *MsgName {
|
||||||
msg.DoMutex = true
|
msg.DoMutex = true
|
||||||
log.Info("Added Mutex=true:", msg.Name)
|
log.Info("Added Mutex=true:", msg.Name)
|
||||||
}
|
}
|
||||||
|
if strings.Contains(line, "`autogenpb:nomutex`") {
|
||||||
|
msg.NoMutex = true
|
||||||
|
log.Info("Added Mutex=true:", msg.Name)
|
||||||
|
}
|
||||||
if strings.Contains(line, "`autogenpb:marshal`") {
|
if strings.Contains(line, "`autogenpb:marshal`") {
|
||||||
msg.DoMarshal = true
|
msg.DoMarshal = true
|
||||||
log.Info("Added Marshal=true:", msg.Name)
|
log.Info("Added Marshal=true:", msg.Name)
|
||||||
|
|
Loading…
Reference in New Issue