<repo_name>bomzlab/study_go<file_sep>/src/model/comms/Interfaces.go
package comms

import ()

type GetMap interface {
	Get(s string) string
}
<file_sep>/src/main/Test6.go
package main

import (
	"fmt"
	m "parsetest"
)

func main6() {

	v := m.ToInt("3")
	fmt.Println("toInt :: ", v)

	s := m.ToString(33)
	fmt.Println("toString :: ", s)
}
<file_sep>/src/main/TestIntMap.go
package main

import (
	"fmt"
	mp "model/maps"
)

func maina() {
	fmt.Println("intMap test")

	m := mp.NewIntMap()
	m.Add(3, "good")

	key := 3
	fmt.Println("key ", key, " , value = ", m.Get(key))

}
<file_sep>/src/main/Test16.go
package main

import (
	"fmt"
	bmap "model/maps"
)

func main16() {
	//	m := bmap.NewSyncMap()
	//	fmt.Println("count %d", m.Count())
	//
	//	m.Set("king", "kong")
	//	fmt.Println("count %d", m.Count())

	m := bmap.NewBomzStyleMapInstance()
	printMap(m)

	m.Add("good", "bye")
	printMap(m)

	fmt.Println("get :: ", m.Get("good"))
	fmt.Println("get :: ", m.Get("good1"))
}

func printMap(m bmap.BomzMap) {
	fmt.Println(m, " , count : ", m.Count())
}
<file_sep>/src/model/maps/BomzSyncMap.go
package maps

import ()

const (
	set = iota
	get
	remove
	count
)

type syncMap struct {
	m map[string]interface{}
	c chan command
}

type command struct {
	key    string
	value  interface{}
	action int
	result chan<- interface{}
}

func NewSyncMap() syncMap {
	m := syncMap{
		m: make(map[string]interface{}),
		c: make(chan command),
	}

	go m.run()
	return m
}

func (m syncMap) run() {
	for cmd := range m.c {
		switch cmd.action {
		case set:
			m.m[cmd.key] = cmd.value
		case get:
			v, ok := m.m[cmd.key]
			cmd.result <- [2]interface{}{v, ok}
		case remove:
			delete(m.m, cmd.key)
		case count:
			cmd.result <- len(m.m)
		}
	}
}

func (m syncMap) Set(k string, v interface{}) {
	m.c <- command{action: set, key: k, value: v}
}

func (m syncMap) Get(k string) (interface{}, bool) {
	callback := make(chan interface{})
	m.c <- command{action: get, key: k, result: callback}
	result := (<-callback).([2]interface{})
	return result[0], result[1].(bool)
}

func (m syncMap) Remove(k string) {
	m.c <- command{action: remove, key: k}
}

func (m syncMap) Count() int {
	callback := make(chan interface{})
	m.c <- command{action: count, result: callback}
	return (<-callback).(int)
}
<file_sep>/src/model/sets/Sets.go
package sets

import ()

type BomzSet interface {
	Add(interface{})
	Contains(interface{}) bool
	Count() int
	Values() []interface{}
	Remove(interface{})
}
<file_sep>/src/model/sets/BomzNonSyncSet.go
package sets

import ()

type bomzNonSyncSet struct {
	m map[interface{}]bool
}

func NewNonSyncSet() bomzNonSyncSet {
	set := bomzNonSyncSet{
		m: make(map[interface{}]bool),
	}

	return set
}

func (set bomzNonSyncSet) Add(v interface{}) {
	set.m[v] = true
}

func (set bomzNonSyncSet) Contains(v interface{}) bool {
	r := set.m[v]
	return r
}

func (set bomzNonSyncSet) Count() int {
	return len(set.m)
}

func (set bomzNonSyncSet) Values() []interface{} {
	var result []interface{}

	for k, _ := range set.m {
		result = append(result, k)
	}

	return result
}

func (set bomzNonSyncSet) Remove(v interface{}) {
	delete(set.m, v)
}
<file_sep>/src/main/Test18Sub.go
package main

import (
	"bufio"
	"fmt"
	"net"
	"time"
)

func handleClient(client net.Conn) {

	defer func() {
		client.Close()
		fmt.Println("client call close")
	}()

	reader := bufio.NewReader(client)

	var data []byte = make([]byte, 300)

	for {
		//		size, err := client.Read(data)
		size, err := reader.Read(data)
		fmt.Println("client read size :: ", size, " <<>> ", len(data))

		if err != nil {
			fmt.Println("client close. ", err)
			break
		}

		if size < 0 {
			fmt.Println("client read size error : ", size)
			break
		}

		if size == 0 {
			time.Sleep(500 * time.Millisecond)
			continue
		}

		fmt.Println("read size :: ", size, " , data :: ", string(data[:size]))
	}
}
<file_sep>/src/main/Test14.go
package main

import (
	"fmt"
	"runtime"
	"sync"
	"sync/atomic"
)

const MAX_LOOP = 1000

type counter struct {
	i    int64
	lock sync.Mutex
	once sync.Once
}

func (c *counter) increment() {

	// 1번만 실행하는 락
	c.once.Do(func() {
		fmt.Println("once call")
	})

	atomic.AddInt64(&c.i, 1) // 해당 처리가 될때는 시간당 cpu 분할 처리를 하지 않는다

	//	sync.Mutex 를 이용한 방법
	//	c.lock.Lock()
	//	c.i += 1
	//	c.lock.Unlock()
}

func (c *counter) display() {
	fmt.Println("display :: ", c.i)
}

func main14() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	fmt.Println("my cpu :: ", runtime.NumCPU())

	c := counter{i: 0}

	// 비효율적인 방법
	//	ch := make(chan struct{})
	//
	//	for i := 0; i < MAX_LOOP; i++ {
	//		go func() {
	//			c.increment()
	//			ch <- struct{}{}
	//		}()
	//	}
	//
	//	for i := 0; i < MAX_LOOP; i++ {
	//		<-ch
	//	}

	// 효율적인 방법
	wg := sync.WaitGroup{}

	for i := 0; i < MAX_LOOP; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()

			c.increment()
		}()
	}

	wg.Wait()

	c.display()

}
<file_sep>/src/main/Test18.go
package main

import (
	"fmt"
	"net"
	"time"
)

var listener net.Listener

func main18() {

	for {
		if !openServer(":8080") {
			continue
		}

		fmt.Println("waiting client ...")
		client, err := listener.Accept()

		if err != nil {
			closeServer()
			continue
		}

		fmt.Println("client :: ", client)

		go handleClient(client)
	}

}

func closeServer() {
	listener.Close()
}

func openServer(port string) bool {
	if listener != nil {
		return true
	}

	ln, err := net.Listen("tcp", port)

	if err != nil {
		fmt.Println("server open error :: ", err)
		time.Sleep(3 * time.Second)
		return false
	}

	listener = ln
	fmt.Printf("server open success. port %s\n", port)

	return true
}
<file_sep>/src/model/user/Simple.go
package user

import (
	"errors"
)

type user struct {
	id    string
	name  string
	age   int
	addr1 string
	addr2 string
}

func New(id, name string, age int, addr1, addr2 string) (*user, error) {
	if len(id) == 0 {
		return nil, errors.New("id is nil")
	}

	if len(name) == 0 {
		return nil, errors.New("name is nil")
	}

	if age <= 0 {
		return nil, errors.New("age is nil")
	}

	if len(addr1) == 0 {
		return nil, errors.New("addr1 is nil")
	}

	if len(addr2) == 0 {
		return nil, errors.New("addr2 is nil")
	}

	user := user{id, name, age, addr1, addr2}

	return &user, nil
}

func (u *user) Id() string {
	return u.id
}

func (u *user) Name() string {
	return u.name
}

func (u *user) Age() int {
	return u.age
}

func (u *user) Addr1() string {
	return u.addr1
}

func (u *user) Addr2() string {
	return u.addr2
}

func (u *user) SetName(n string) {
	u.name = n
}

func (u *user) SetAge(a int) {
	u.age = a
}
<file_sep>/src/main/Test7.go
package main

import (
	"fmt"
	"time"
)

func init() {
	fmt.Println("init call")
}

func main7() {
	fmt.Println("main call")

	go longTime()
	go shortTime()

	time.Sleep(5 * time.Second)

	fmt.Println("main end>>", time.Second)
}

func longTime() {
	fmt.Println("long start : ", time.Now())

	time.Sleep(3 * time.Second)

	fmt.Println("long end : ", time.Now())
}

func shortTime() {
	fmt.Println("short start : ", time.Now())

	time.Sleep(1 * time.Second)

	fmt.Println("short end : ", time.Now())
}
<file_sep>/src/main/Test5.go
package main

import (
	"fmt"
	"strings"
)

func main5() {

	v := func(x, y int) int {
		return x + y
	}

	v(3, 4)

	//	v := func(x, y int) int {
	//		return x + y
	//	}(3, 4)
	fmt.Println("1>", v)

	a := sumFileName(".zip")
	fmt.Println("2>", a("good"))

	fmt.Println("3>", sum1(3, sum2))

	hangulCheck("Hi, 안녕, Good")
}

func sumFileName(prefix string) func(string) string {
	return func(fileName string) string {
		if strings.HasSuffix(fileName, prefix) {
			return fileName
		}
		return fileName + prefix
	}
}

func sum1(y int, f func(int, int) int) int {
	return f(y, 3)
}

func sum2(x, y int) int {
	return x + y
}

func hangulCheck(s string) {
	i := strings.Index(s, "안")
	fmt.Println("index = ", i, " , 본문 = ", s)
}
<file_sep>/src/model/maps/BomzMap.go
package maps

import ()

type bomzMap map[string]string

func New() bomzMap {
	return make(map[string]string)
}

func (m bomzMap) Get(v string) string {
	return m[v]
}
<file_sep>/src/main/TestSet.go
package main

import (
	"fmt"
	set "model/sets"
)

func main() {
	fmt.Printf("% start\n", "bomzSet")

	var mySet set.BomzSet

	mySet = getSet(true)

	fmt.Println(">>", mySet)

	mySet.Add(3)
	mySet.Add(8)

	for i := 0; i < 10; i++ {
		fmt.Println(i, " = ", mySet.Contains(i))
	}

	fmt.Println("===================", mySet.Count())

	mySet.Remove(8)

	for i := 0; i < 10; i++ {
		fmt.Println(i, " = ", mySet.Contains(i))
	}

	fmt.Println("===================", mySet.Count())

	v := mySet.Values()

	for i, r := range v {
		fmt.Println(">>>>", i, "=", r)
	}
}

func getSet(sync bool) set.BomzSet {
	if sync {
		return set.NewSyncSet()
	} else {
		return set.NewNonSyncSet()
	}
}
<file_sep>/src/main/Test8.go
package main

import (
	"fmt"
	"time"
)

func main8() {
	fmt.Println("main call")

	done := make(chan bool)

	go longTime2(done)
	go shortTime2(done)

	fmt.Println("end :: ", <-done)
	fmt.Println("end :: ", <-done)

	fmt.Println("main end>>")
}

func longTime2(done chan bool) {
	fmt.Println("long start : ", time.Now())

	time.Sleep(3 * time.Second)

	fmt.Println("long end : ", time.Now())

	done <- true
}

func shortTime2(done chan bool) {
	fmt.Println("short start : ", time.Now())

	time.Sleep(1 * time.Second)

	fmt.Println("short end : ", time.Now())

	done <- false
}
<file_sep>/src/model/sets/BomzSyncSet.go
package sets

import (
	"sync"
)

type bomzSyncSet struct {
	m  bomzNonSyncSet
	mu sync.Mutex
}

func NewSyncSet() bomzSyncSet {
	return bomzSyncSet{
		m: NewNonSyncSet(),
	}
}

func (m bomzSyncSet) Add(v interface{}) {
	defer m.mu.Unlock()
	m.mu.Lock()
	m.m.Add(v)
}

func (m bomzSyncSet) Contains(v interface{}) bool {
	defer m.mu.Unlock()
	m.mu.Lock()
	return m.m.Contains(v)
}

func (m bomzSyncSet) Count() int {
	defer m.mu.Unlock()
	m.mu.Lock()
	return m.m.Count()
}

func (m bomzSyncSet) Values() []interface{} {
	defer m.mu.Unlock()
	m.mu.Lock()
	return m.m.Values()
}

func (m bomzSyncSet) Remove(v interface{}) {
	defer m.mu.Unlock()
	m.mu.Lock()
	m.m.Remove(v)
}
<file_sep>/README.md
# go_study
go lang study
<file_sep>/src/main/Test9.go
package main

import (
	"fmt"
	user "model/user"
)

func main9() {
	info, err := user.New("bomz", "min", 15, "south", "korea")
	fmt.Println("make user :: ", info, " <> ", err)

	if err != nil {
		return
	}

	info.SetAge(30)

	fmt.Println("update age user :: ", info)
}
<file_sep>/src/main/Test4.go
package main

import (
	"fmt"
	"strconv"
)

func main4() {
	a, b := 3, 5

	fmt.Println("sum : ", sum(a, b))
	fmt.Println("mult : ", mult(a, b))

	x, y := test1(a, b)
	fmt.Println("test1 : ", x, " / ", y)

	toInt1("3a")
	fmt.Println("toInt2 : ", toInt2("4"))

	fmt.Println(point1(&a), " , main = ", a)

	defer1(a, b)
}

func sum(x, y int) int {
	return x + y
}

func mult(x, y int) int {
	return x * y
}

func test1(x, y int) (int, int) {
	return sum(x, y), mult(x, y)
}

func toInt1(v string) {
	if i, err := strconv.Atoi(v); err == nil {
		fmt.Println("value = ", i)
	} else {
		fmt.Println("value ", v, " is error. ", err)
	}
}

func toInt2(v string) (re int) {
	re, _ = strconv.Atoi(v)
	fmt.Println("toInt2 method : ", re)
	return
}

func point1(x *int) string {
	*x += 3
	return "Point1 method = " + strconv.Itoa(*x)
}

func defer1(x, y int) {
	fmt.Println("defer1-1 : ", x, " , ", y)
	v := x + y

	defer fmt.Println("defer1-2 : ", x, " , ", y, " = ", v)

	v = 40
	fmt.Println("defer1-3 : ", x, " , ", y, " = ", v)
}
<file_sep>/src/model/maps/BomzStyleMap.go
package maps

import ()

type mapInfo struct {
	m   map[interface{}]interface{}
	cmd chan mapCommand
}

func (m mapInfo) Add(k, v interface{}) {
	m.cmd <- mapCommand{key: k, value: v, action: set}
}

func (m mapInfo) Get(k interface{}) interface{} {
	callback := make(chan interface{})
	m.cmd <- mapCommand{key: k, action: get, result: callback}
	return (<-callback).(interface{})
}

func (m mapInfo) Remove(k interface{}) interface{} {
	return nil
}

func (m mapInfo) Count() int {
	callback := make(chan interface{})
	m.cmd <- mapCommand{action: count, result: callback}
	return (<-callback).(int)
}

func NewBomzStyleMapInstance() mapInfo {
	m := mapInfo{
		m:   make(map[interface{}]interface{}),
		cmd: make(chan mapCommand),
	}
	go run(m)
	return m
}

func run(info mapInfo) {
	for i := range info.cmd {
		switch i.action {
		case set:
			info.m[i.key] = i.value
		case get:
			v, ok := info.m[i.key]
			if ok {
				i.result <- v
			} else {
				i.result <- -1
			}

		case count:
			i.result <- len(info.m)
		}
	}
}
<file_sep>/src/parsetest/StringParse.go
package parsetest

import (
	"strconv"
)

func toString(i int) string {
	return strconv.Itoa(i)
}
<file_sep>/src/model/maps/MapStyle.go
package maps

import ()

type BomzMap interface {
	Add(k, v interface{})
	Get(k interface{}) interface{}
	Remove(k interface{}) interface{}
	Count() int
}

type mapCommand struct {
	key    interface{}
	value  interface{}
	action int
	result chan<- interface{}
}
<file_sep>/src/model/maps/IntMap.go
package maps

import ()

type intMap struct {
	m map[int]interface{}
}

func NewIntMap() intMap {
	m := intMap{
		m: make(map[int]interface{}),
	}

	return m
}

func (m intMap) Add(key int, value interface{}) bool {
	if value == nil {
		return false
	}

	m.m[key] = value

	return true
}

func (m intMap) Get(key int) interface{} {
	return m.m[key]
}
<file_sep>/src/main/Test10.go
package main

import (
	"fmt"
	bomzComms "model/comms"
	bomzMap "model/maps"
)

func main10() {
	m := bomzMap.New()

	fmt.Println("map : ", m)

	m["king"] = "kong"
	m["hot"] = "dog"

	fmt.Println("map : ", m)

	process(m)
}

func process(g bomzComms.GetMap) {
	fmt.Println("process >> ", g.Get("hot"))
}
<file_sep>/src/main/Test15.go
package main

import (
	"fmt"
	"runtime"
	"time"
)

func main15() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	quit := make(chan struct{})
	done := process15(quit)
	timeout := time.After(2 * time.Second)

	select {
	case d := <-done:
		fmt.Println("done >> ", d)
	case <-timeout:
		fmt.Println("timeout")
		quit <- struct{}{}
	}
}

func process15(quit chan struct{}) chan string {
	done := make(chan string)

	go func() {

		go func() {
			time.Sleep(10 * time.Second)
			done <- "Complate"
		}()

		<-quit
		fmt.Println("닫아라")
	}()

	return done
}
<file_sep>/src/main/Test17.go
package main

import (
	"fmt"
	"sync"
	"time"
)

var list = []int{}

var lock = sync.Mutex{}

func main17() {

	wg := sync.WaitGroup{}

	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(i int) {
			defer wg.Done()
			running(i)
		}(i)
	}

	wg.Wait()

	for i, v := range list {
		fmt.Println(i, " ranking is ", v)
	}

}

func running(i int) {
	for x := 1; x <= 2; x++ {
		time.Sleep(1 * time.Second)
		fmt.Println(i, " >> ", x, " running ...")
	}

	lock.Lock()
	list = append(list, i)
	lock.Unlock()
}
<file_sep>/src/main/Test19.go
package main

import (
	"fmt"
	"net"
	"strconv"
	"time"
)

var socket net.Conn

func main19() {
	index := 0

	for {
		if !connect("127.0.0.1", 8080) {
			continue
		}

		write(&index)

		time.Sleep(3 * time.Second)
	}

}

func write(i *int) {
	msg := "good" + strconv.Itoa(*i)

	if _, err := socket.Write([]byte(msg)); err != nil {
		fmt.Println("전송 실패로 연결 종료")
		disconnect()
	} else {
		*i++
	}

}

func disconnect() {
	if socket != nil {
		socket.Close()
		socket = nil
	}
}

func connect(ip string, port int) bool {
	if socket != nil {
		return true
	}

	conn, err := net.Dial("tcp", ip+":"+strconv.Itoa(port))

	if err != nil {
		fmt.Println("client connect fail : ", ip, ":", port)
		time.Sleep(1 * time.Second)
		return false
	}

	socket = conn
	return true
}
<file_sep>/src/main/Test12.go
package main

import (
	"fmt"
)

func main12() {

	ch := make(chan int)
	quit := make(chan int)

	go func() {
		for i := 0; i < 10; i++ {
			fmt.Println("ch::", <-ch)
		}

		quit <- 0
	}()

	check(ch, quit)
}

func check(ch, quit chan int) {
	x := 1

	for {
		select {
		case ch <- x:
			x++
		case <-quit:
			fmt.Println("quit :: ")
			return
		default:
			fmt.Println("default call")
		}
	}
}
<file_sep>/src/main/Test20.go
package main

import (
	"bytes"
	"fmt"
	"golang.org/x/text/encoding/korean"
	"golang.org/x/text/transform"
	"io/ioutil"
	"os"
)

func main20() {
	path := "d:/"

	fi, err := ioutil.ReadDir(path)
	execute(&path, &fi, &err)
}

func execute(path *string, f *[]os.FileInfo, err *error) {
	if *err != nil {
		return
	}

	for _, file := range *f {

		if file.IsDir() {
			p := *path + file.Name() + "/"
			fi, e := ioutil.ReadDir(p)
			execute(&p, &fi, &e)

		} else {
			print(path, &file)
		}
	}
}

func print(path *string, f *os.FileInfo) {
	var bufs bytes.Buffer
	wr := transform.NewWriter(&bufs, korean.EUCKR.NewEncoder())
	wr.Write([]byte(*path + (*f).Name()))
	wr.Close()

	fmt.Println(bufs.String())
}
<file_sep>/src/main/Test2.go
package main

import (
	"fmt"
)

const MAX = 30

func main2() {

	sum := 0

	for i := 0; i < 10; i++ {
		sum += i
	}

	fmt.Println("sum=", sum)

	sum = 8

	switch {
	case sum >= 0 && sum <= 10:
		fmt.Println("0~10 : ", sum)
		fallthrough // 다음 case 실행
	case sum > 10 && sum <= 20:
		fmt.Println("11~20 : ", sum)
	case sum > 20 && sum <= 40:
		fmt.Println("21~40 : ", sum)
	case sum > 40 && sum <= 50:
		fmt.Println("41~50 : ", sum)
	}

	array := []int{3, 4, 5, 6}
	for i := 0; i < len(array); i++ {
		fmt.Println("array ", i, " = ", array[i])
	}

	fmt.Println("==================")

	for index, value := range array {
		fmt.Println(">>>", index, "=", value)
	}

}
<file_sep>/src/parsetest/IntParse.go
package parsetest

import (
	"strconv"
)

func ToInt(s string) int {
	v, _ := strconv.Atoi(s)
	return v
}

func ToString(i int) string {
	return toString(i)
}
<file_sep>/src/main/Test3.go
package main

import (
	"fmt"
)

var tmpX int

const tmpY int = 20

func main3() {
	fmt.Println("Test3")

	type Box struct {
		width  int
		height int
	}

	box := Box{30, 20}
	fmt.Println("Box W=", box.width, " H=", box.height, " >>", box)

	fmt.Println("before X=", tmpX, " , Y=", tmpY)
	tmpX = 40
	//	tmpY = 20	// const error! java final
	fmt.Println("after X=", tmpX, " , Y=", tmpY)

	//	const (
	//		one   = 0
	//		two   = 1
	//		three = 2
	//		four  = 3
	//	)

	//	const (
	//		one = iota
	//		two
	//		three
	//		four
	//	)

	//	const (
	//		one = iota + 2
	//		two
	//		three
	//		four
	//	)

	type Number int
	const (
		//		_          = iota
		one Number = 5 + iota
		two
		three
		four
	)

	fmt.Println(one, " / ", two, " / ", three, " / ", four)
}
<file_sep>/src/main/Test11.go
package main

import (
	"fmt"
	"sync"
	"time"
)

func main11() {
	// error example

	ch := make(chan int)

	fmt.Println("start : ", ch)

	type lock struct {
		m sync.Mutex
	}

	lo := lock{}

	go func(lo *lock) {
		for i := 0; i < 10; i++ {
			lo.m.Lock()
			ch <- i
			lo.m.Unlock()
			time.Sleep(1 * time.Second)
		}
	}(&lo)

	for i := range ch {
		time.Sleep(5 * time.Second)

		lo.m.Lock()
		fmt.Println(">>>", <-ch, " <> ", i)
		lo.m.Unlock()

	}

	fmt.Println("end")

	close(ch)
}
