small app works, example core dumps on Marshal()
This commit is contained in:
parent
3f2909aa0d
commit
9349ab95fc
2
Makefile
2
Makefile
|
@ -3,7 +3,7 @@ BUILDTIME = $(shell date +%Y.%m.%d_%H%M)
|
||||||
|
|
||||||
simple: build
|
simple: build
|
||||||
# make -C example clean simpleMutexGlobal goimports vet
|
# make -C example clean simpleMutexGlobal goimports vet
|
||||||
make -C example clean simpleMutexProtoc goimports vet
|
# make -C example clean simpleMutexProtoc goimports vet
|
||||||
|
|
||||||
full: install clean auto goimports vet build test install
|
full: install clean auto goimports vet build test install
|
||||||
@echo everything worked and the example ran
|
@echo everything worked and the example ran
|
||||||
|
|
15
addMutex.go
15
addMutex.go
|
@ -14,7 +14,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (pf *File) syncLock(w io.Writer) {
|
func (pf *File) syncLock(w io.Writer) {
|
||||||
var LOCK string = pf.Bases.Lockname
|
var LOCK string = pf.Base.Lockname // if the Marshall code changes, this will have to change
|
||||||
|
|
||||||
fmt.Fprintln(w, "// a simple global lock")
|
fmt.Fprintln(w, "// a simple global lock")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
|
@ -95,19 +95,20 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
// ONLY PASS THIS IF YOU DO NOT WANT TO USE MARSHAL()
|
// ONLY PASS THIS IF YOU DO NOT WANT TO USE MARSHAL()
|
||||||
|
|
||||||
if argv.Marshal {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = pf.Base
|
msg = pf.Base
|
||||||
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
|
||||||
|
if argv.Marshal {
|
||||||
|
// msg.Lockname = "fruitMu.Lock"
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +116,10 @@ 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
|
||||||
|
if argv.Marshal {
|
||||||
|
// msg.Lockname = "fruitMu.Lock"
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
VERSION = $(shell git describe --tags)
|
VERSION = $(shell git describe --tags)
|
||||||
BUILDTIME = $(shell date +%Y.%m.%d_%H%M)
|
BUILDTIME = $(shell date +%Y.%m.%d_%H%M)
|
||||||
|
|
||||||
test: goimports build
|
all: clean simpleMutexProtoc goimports build
|
||||||
./example
|
./example
|
||||||
|
|
||||||
modproto: clean withMutex goimports vet build
|
modproto: clean withMutex goimports vet build
|
||||||
|
@ -46,4 +46,4 @@ goimports:
|
||||||
clean:
|
clean:
|
||||||
-rm -f go.*
|
-rm -f go.*
|
||||||
-rm -f *.pb.go
|
-rm -f *.pb.go
|
||||||
-rm -f testfiles
|
-rm -f example basket.pb
|
||||||
|
|
|
@ -19,20 +19,18 @@ var sortmap map[string]string
|
||||||
var marshalKeys []string
|
var marshalKeys []string
|
||||||
var uniqueKeys []string
|
var uniqueKeys []string
|
||||||
|
|
||||||
var pb *Fruits
|
var counter int = rand.Intn(100)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
pb = NewFruits()
|
var pb *Fruits
|
||||||
|
// pb = NewFruits()
|
||||||
|
pb = new(Fruits)
|
||||||
// attempt to load basket.pb
|
// attempt to load basket.pb
|
||||||
if err := pb.loadBasket(); err != nil {
|
if err := pb.loadBasket(); err != nil {
|
||||||
log.Info("load basket failed. running this for the first time?")
|
log.Info("load basket failed. running this for the first time?")
|
||||||
fruit := &Fruit{
|
a := pb.getNewFruit()
|
||||||
Brand: "mom",
|
pb.Fruits = append(pb.Fruits, a)
|
||||||
City: "New NewYork",
|
pb.printTable()
|
||||||
UPC: "2000",
|
|
||||||
}
|
|
||||||
testAppend(fruit)
|
|
||||||
appendByUPC()
|
|
||||||
}
|
}
|
||||||
if err := pb.saveBasket(); err != nil {
|
if err := pb.saveBasket(); err != nil {
|
||||||
badExit(err)
|
badExit(err)
|
||||||
|
@ -40,7 +38,6 @@ func main() {
|
||||||
if pb == nil {
|
if pb == nil {
|
||||||
badExit(fmt.Errorf("pb == nil This should not have happened"))
|
badExit(fmt.Errorf("pb == nil This should not have happened"))
|
||||||
}
|
}
|
||||||
pb.printTable()
|
|
||||||
pb.addThings()
|
pb.addThings()
|
||||||
pb.printTable()
|
pb.printTable()
|
||||||
pb.saveBasket()
|
pb.saveBasket()
|
||||||
|
@ -52,6 +49,17 @@ func badExit(err error) {
|
||||||
os.Exit(-1)
|
os.Exit(-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pb *Fruits) getNewFruit() *Fruit {
|
||||||
|
counter += rand.Intn(100)
|
||||||
|
upc := fmt.Sprintf("%d", counter)
|
||||||
|
fut := &Fruit{
|
||||||
|
Brand: "mom",
|
||||||
|
City: "New NewYork",
|
||||||
|
UPC: upc,
|
||||||
|
}
|
||||||
|
return fut
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
x := new(Fruit)
|
x := new(Fruit)
|
||||||
x = &Fruit{
|
x = &Fruit{
|
||||||
|
@ -130,36 +138,6 @@ func (pb *Fruits) addThings() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAppend(fruit *Fruit) {
|
|
||||||
if pb.AppendUnique(fruit) {
|
|
||||||
log.Info("AppendUnique() test1 ok", fruit.Brand, fruit.City)
|
|
||||||
} else {
|
|
||||||
badExit(fmt.Errorf("AppendUnique test1 failed %s %s %d\n", fruit.Brand, fruit.City, pb.Len()))
|
|
||||||
}
|
|
||||||
if pb.AppendUnique(fruit) {
|
|
||||||
badExit(fmt.Errorf("AppendUnique() test2 worked but should not have %s %s", fruit.Brand, fruit.City))
|
|
||||||
} else {
|
|
||||||
log.Info("AppendUnique() test2 failed ok", fruit.Brand, fruit.City)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendByUPC() {
|
|
||||||
fruit := new(Fruit)
|
|
||||||
fruit.UPC = "blah331"
|
|
||||||
fruit.City = "fry"
|
|
||||||
fruit.City = "paris"
|
|
||||||
if pb.AppendUniqueByUPC(fruit) {
|
|
||||||
log.Info("AppendUnique() test1 ok", fruit.Brand, fruit.City)
|
|
||||||
} else {
|
|
||||||
badExit(fmt.Errorf("AppendUniqueByUPC test1 failed %s %s %d\n", fruit.Brand, fruit.City, pb.Len()))
|
|
||||||
}
|
|
||||||
if pb.AppendUniqueByUPC(fruit) {
|
|
||||||
badExit(fmt.Errorf("AppendUniqueByUPC() test2 worked but should not have %s %s", fruit.Brand, fruit.City))
|
|
||||||
} else {
|
|
||||||
log.Info("AppendUnique() test2 failed ok", fruit.Brand, fruit.City)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pb *Fruits) saveBasket() error {
|
func (pb *Fruits) saveBasket() error {
|
||||||
data, err := pb.Marshal()
|
data, err := pb.Marshal()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
VERSION = $(shell git describe --tags)
|
||||||
|
BUILDTIME = $(shell date +%Y.%m.%d_%H%M)
|
||||||
|
|
||||||
|
all: clean simpleMutexProtoc goimports build
|
||||||
|
./small
|
||||||
|
|
||||||
|
modproto: clean withMutex goimports vet build
|
||||||
|
./small
|
||||||
|
|
||||||
|
rawproto: clean withoutMutex goimports vet build
|
||||||
|
./small
|
||||||
|
|
||||||
|
vet:
|
||||||
|
@GO111MODULE=off go vet
|
||||||
|
|
||||||
|
build:
|
||||||
|
GO111MODULE=off go build -v
|
||||||
|
|
||||||
|
simpleMutexProtoc:
|
||||||
|
../autogenpb --proto fruit.proto --package main
|
||||||
|
|
||||||
|
# why does this fail to compile? I'm not sure. maybe someone smart can figure it out
|
||||||
|
# basically, it just trys to return the deleted record but says something
|
||||||
|
# about the RWmutex lock being copied and GO fails to compile
|
||||||
|
# I'm don't grok what is going on. This autogenerated code should
|
||||||
|
# provide as simple as one could hope for automated way to try to debug it though!
|
||||||
|
simpleMutexProtocWithDeleteCopy:
|
||||||
|
../autogenpb --proto fruit.proto --package main --delete
|
||||||
|
|
||||||
|
simpleMutexGlobal:
|
||||||
|
../autogenpb --proto fruit.proto --package main --mutex=false
|
||||||
|
|
||||||
|
withMutex:
|
||||||
|
../autogenpb --proto fruit.proto --package main
|
||||||
|
../autogenpb --proto file.proto --package main
|
||||||
|
../autogenpb --proto patchset.proto --package main
|
||||||
|
|
||||||
|
withoutMutex:
|
||||||
|
../autogenpb --proto fruit.proto --package main --mutex=false
|
||||||
|
../autogenpb --proto file.proto --package main --mutex=false
|
||||||
|
../autogenpb --proto patchset.proto --package main --mutex=false
|
||||||
|
|
||||||
|
goimports:
|
||||||
|
goimports -w *.go
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-rm -f go.*
|
||||||
|
-rm -f *.pb.go
|
||||||
|
-rm -f small basket.pb
|
|
@ -0,0 +1,9 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
func NewFruits() *Fruits {
|
||||||
|
x := new(Fruits)
|
||||||
|
x.Uuid = "test"
|
||||||
|
x.Version = "v0.0.2"
|
||||||
|
// x.Fruits =
|
||||||
|
return x
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package fruit;
|
||||||
|
|
||||||
|
import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp
|
||||||
|
|
||||||
|
// "Fruit" must exist. you can put anything in it
|
||||||
|
message Fruit {
|
||||||
|
string brand = 1;
|
||||||
|
string UPC = 2;
|
||||||
|
string city = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Fruits" MUST EXIST and start exactly this way
|
||||||
|
// It must be "Fruit" + 's' and must match the name of this file: "fruit.proto"
|
||||||
|
message Fruits { // `autogenpb:marshal`
|
||||||
|
string uuid = 1; // `autogenpb:uuid:be926ad9-f07f-484c-adf2-d96eeabf3079`
|
||||||
|
string version = 2; // `autogenpb:version:v0.0.1`
|
||||||
|
repeated Fruit Fruits = 3; // THIS MUST BE "Fruit" and then "Fruit" + "s"
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
//go:build go1.20
|
||||||
|
// +build go1.20
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"go.wit.com/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// sent via -ldflags
|
||||||
|
var VERSION string
|
||||||
|
var BUILDTIME string
|
||||||
|
|
||||||
|
var sortmap map[string]string
|
||||||
|
var marshalKeys []string
|
||||||
|
var uniqueKeys []string
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var pb *Fruits
|
||||||
|
pb = new(Fruits)
|
||||||
|
// attempt to load basket.pb
|
||||||
|
fruit := &Fruit{
|
||||||
|
Brand: "mom",
|
||||||
|
City: "New NewYork",
|
||||||
|
UPC: "2000",
|
||||||
|
}
|
||||||
|
pb.Fruits = append(pb.Fruits, fruit)
|
||||||
|
|
||||||
|
a := &Fruit{
|
||||||
|
Brand: "fry",
|
||||||
|
City: "the moon",
|
||||||
|
UPC: "2001",
|
||||||
|
}
|
||||||
|
pb.Fruits = append(pb.Fruits, a)
|
||||||
|
|
||||||
|
pb.saveBasket()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pb *Fruits) saveBasket() error {
|
||||||
|
data, err := pb.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
w, err := os.OpenFile("basket.pb", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
w.Write(data)
|
||||||
|
w.Close()
|
||||||
|
log.Info("saved basket.pb ok")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func badExit(err error) {
|
||||||
|
log.Info("autogenpb error:", err)
|
||||||
|
os.Exit(-1)
|
||||||
|
}
|
10
sort.go
10
sort.go
|
@ -21,14 +21,12 @@ func (pb *Files) makeNewSortfile(pf *File) error {
|
||||||
header(wSort, pf)
|
header(wSort, pf)
|
||||||
header(wFind, pf)
|
header(wFind, pf)
|
||||||
|
|
||||||
if !argv.Mutex {
|
|
||||||
pf.syncLock(wSort)
|
pf.syncLock(wSort)
|
||||||
}
|
|
||||||
|
|
||||||
if argv.Mutex {
|
// if argv.Mutex {
|
||||||
// use the mutex lock from the modified protoc.pb.go file
|
// // use the mutex lock from the modified protoc.pb.go file
|
||||||
pf.Bases.Lockname = "all.Lock"
|
// pf.Bases.Lockname = "all.Lock"
|
||||||
}
|
// }
|
||||||
|
|
||||||
pf.Base.iterTop(wSort)
|
pf.Base.iterTop(wSort)
|
||||||
pf.Base.iterNext(wSort)
|
pf.Base.iterNext(wSort)
|
||||||
|
|
18
sortFunc.go
18
sortFunc.go
|
@ -57,18 +57,18 @@ func (pf *File) selectAllFunc(w io.Writer) {
|
||||||
var BASE string = pf.Base.Name
|
var BASE string = pf.Base.Name
|
||||||
var LOCK string = pf.Bases.Lockname
|
var LOCK string = pf.Bases.Lockname
|
||||||
|
|
||||||
fmt.Fprintln(w, "func (all *"+BASES+") All() *"+BASE+"Iterator {")
|
fmt.Fprintln(w, "func (x *"+BASES+") All() *"+BASE+"Iterator {")
|
||||||
fmt.Fprintln(w, " "+BASE+"Pointers := all.selectAll"+BASE+"()")
|
fmt.Fprintln(w, " "+BASE+"Pointers := x.selectAll"+BASE+"()")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
fmt.Fprintln(w, " iterator := New"+BASE+"Iterator("+BASE+"Pointers)")
|
fmt.Fprintln(w, " iterator := New"+BASE+"Iterator("+BASE+"Pointers)")
|
||||||
fmt.Fprintln(w, " return iterator")
|
fmt.Fprintln(w, " return iterator")
|
||||||
fmt.Fprintln(w, "}")
|
fmt.Fprintln(w, "}")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
fmt.Fprintln(w, "func (all *"+BASES+") Len() int {")
|
fmt.Fprintln(w, "func (x *"+BASES+") Len() int {")
|
||||||
fmt.Fprintln(w, " "+LOCK+".RLock()")
|
fmt.Fprintln(w, " "+LOCK+".RLock()")
|
||||||
fmt.Fprintln(w, " defer "+LOCK+".RUnlock()")
|
fmt.Fprintln(w, " defer "+LOCK+".RUnlock()")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
fmt.Fprintln(w, " return len(all."+BASES+")")
|
fmt.Fprintln(w, " return len(x."+BASES+")")
|
||||||
fmt.Fprintln(w, "}")
|
fmt.Fprintln(w, "}")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
}
|
}
|
||||||
|
@ -78,8 +78,8 @@ func (pf *File) sortByFunc(w io.Writer) {
|
||||||
var BASE string = pf.Base.Name
|
var BASE string = pf.Base.Name
|
||||||
|
|
||||||
for _, SORT := range pf.Base.Sort {
|
for _, SORT := range pf.Base.Sort {
|
||||||
fmt.Fprintln(w, "func (all *"+BASES+") SortBy"+SORT+"() *"+BASE+"Iterator {")
|
fmt.Fprintln(w, "func (x *"+BASES+") SortBy"+SORT+"() *"+BASE+"Iterator {")
|
||||||
fmt.Fprintln(w, " things := all.selectAll"+BASE+"()")
|
fmt.Fprintln(w, " things := x.selectAll"+BASE+"()")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
fmt.Fprintln(w, " sort.Sort("+BASE+""+SORT+"(things))")
|
fmt.Fprintln(w, " sort.Sort("+BASE+""+SORT+"(things))")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
|
@ -103,14 +103,14 @@ func (pf *File) iterSelect(w io.Writer) {
|
||||||
var LOCK string = pf.Bases.Lockname
|
var LOCK string = pf.Bases.Lockname
|
||||||
|
|
||||||
fmt.Fprintln(w, "// safely returns a slice of pointers to the "+BASE+" protobufs")
|
fmt.Fprintln(w, "// safely returns a slice of pointers to the "+BASE+" protobufs")
|
||||||
fmt.Fprintln(w, "func (all *"+BASES+") selectAll"+BASE+"() []*"+BASE+" {")
|
fmt.Fprintln(w, "func (x *"+BASES+") selectAll"+BASE+"() []*"+BASE+" {")
|
||||||
fmt.Fprintln(w, " "+LOCK+".RLock()")
|
fmt.Fprintln(w, " "+LOCK+".RLock()")
|
||||||
fmt.Fprintln(w, " defer "+LOCK+".RUnlock()")
|
fmt.Fprintln(w, " defer "+LOCK+".RUnlock()")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
fmt.Fprintln(w, " // Create a new slice to hold pointers to each "+BASE+"")
|
fmt.Fprintln(w, " // Create a new slice to hold pointers to each "+BASE+"")
|
||||||
fmt.Fprintln(w, " var tmp []*"+BASE+"")
|
fmt.Fprintln(w, " var tmp []*"+BASE+"")
|
||||||
fmt.Fprintln(w, " tmp = make([]*"+BASE+", len(all."+BASES+"))")
|
fmt.Fprintln(w, " tmp = make([]*"+BASE+", len(x."+BASES+"))")
|
||||||
fmt.Fprintln(w, " for i, p := range all."+BASES+" {")
|
fmt.Fprintln(w, " for i, p := range x."+BASES+" {")
|
||||||
fmt.Fprintln(w, " tmp[i] = p // Copy pointers for safe iteration")
|
fmt.Fprintln(w, " tmp[i] = p // Copy pointers for safe iteration")
|
||||||
fmt.Fprintln(w, " }")
|
fmt.Fprintln(w, " }")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
|
|
10
sortNew.go
10
sortNew.go
|
@ -8,11 +8,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (msg *MsgName) getLockname(s string) string {
|
func (msg *MsgName) getLockname(s string) string {
|
||||||
if argv.Mutex {
|
// if argv.Mutex {
|
||||||
// use the mutex lock from the modified protoc.pb.go file
|
// // use the mutex lock from the modified protoc.pb.go file
|
||||||
return s + ".Lock"
|
// return s + ".Lock"
|
||||||
// return s // causes Marshal() to panic? always use the variable name 'Lock'?
|
// // return s // causes Marshal() to panic? always use the variable name 'Lock'?
|
||||||
}
|
// }
|
||||||
// a single global lock by struct name
|
// a single global lock by struct name
|
||||||
return msg.Lockname
|
return msg.Lockname
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue