Commit 28a6cc60c98e9c7f1e88ab4b376fb993c39b1d82
1 parent
e2880d3fb1
Exists in
master
Integrated logger and improved QuickSort
Showing
8 changed files
with
313 additions
and
332 deletions
Show diff stats
gologger/http_logs.go
... | ... | @@ -1,66 +0,0 @@ |
1 | -package gologger | |
2 | - | |
3 | -import ( | |
4 | - "bytes" | |
5 | - "fmt" | |
6 | - "net/http" | |
7 | - "net/http/httputil" | |
8 | - "os" | |
9 | - "strings" | |
10 | - "time" | |
11 | -) | |
12 | - | |
13 | -const splitLine = "==============================================================" | |
14 | - | |
15 | -// LogHTTPRequest ... | |
16 | -func (l *Logger) LogHTTPRequest(req *http.Request, userID string) string { | |
17 | - if userID == "" { | |
18 | - userID = "-" | |
19 | - } | |
20 | - | |
21 | - var b strings.Builder | |
22 | - | |
23 | - b.WriteString("Request:\n") | |
24 | - // CLF-like header | |
25 | - fmt.Fprintf(&b, "%s %s %s\n", req.RemoteAddr, userID, time.Now().Format(dateTimeFormat)) | |
26 | - | |
27 | - body, err := httputil.DumpRequest(req, true) | |
28 | - if err != nil { | |
29 | - fmt.Fprintf(os.Stderr, "%v\n", err) | |
30 | - } | |
31 | - | |
32 | - const sepStr = "\r\n\r\n" | |
33 | - sepIndex := bytes.Index(body, []byte(sepStr)) | |
34 | - if sepIndex == -1 { | |
35 | - b.WriteString(string(body) + "\n\n") | |
36 | - } else { | |
37 | - sepIndex += len(sepStr) | |
38 | - payload, _ := printJSON(body[sepIndex:]) | |
39 | - b.WriteString(string(body[:sepIndex]) + string(payload) + "\n\n") | |
40 | - } | |
41 | - | |
42 | - return b.String() | |
43 | -} | |
44 | - | |
45 | -// LogHTTPResponse ... | |
46 | -func (l *Logger) LogHTTPResponse(data []byte, status int, startTime time.Time) string { | |
47 | - duration := time.Now().Sub(startTime) | |
48 | - jsonData, _ := printJSON(data) | |
49 | - return fmt.Sprintf("Response:\n%d %v %dB\n%s\n%s\n\n", status, duration, len(data), jsonData, splitLine) | |
50 | -} | |
51 | - | |
52 | -// CombineHTTPLogs ... | |
53 | -func (l *Logger) CombineHTTPLogs(in string, out string) { | |
54 | - if l.outputFile == nil { | |
55 | - return | |
56 | - } | |
57 | - | |
58 | - l.mu.Lock() | |
59 | - defer l.mu.Unlock() | |
60 | - | |
61 | - msg := in + out | |
62 | - if l.shouldSplit(len(msg)) { | |
63 | - l.split() | |
64 | - } | |
65 | - l.outputFile.WriteString(msg) | |
66 | -} |
gologger/main.go
... | ... | @@ -1,162 +0,0 @@ |
1 | -package gologger | |
2 | - | |
3 | -import ( | |
4 | - "bytes" | |
5 | - "encoding/json" | |
6 | - "fmt" | |
7 | - "os" | |
8 | - "path/filepath" | |
9 | - "strings" | |
10 | - "sync" | |
11 | - "time" | |
12 | -) | |
13 | - | |
14 | -const dateTimeFormat = "2006-01-02 15:04:05" | |
15 | - | |
16 | -// Block ... | |
17 | -const ( | |
18 | - MaxLogSize5MB int64 = 5 * 1024 * 1024 | |
19 | - MaxLogSize1MB int64 = 1 * 1024 * 1024 | |
20 | - MaxLogSize500KB int64 = 500 * 1024 | |
21 | - MaxLogSize100KB int64 = 100 * 1024 | |
22 | - MaxLogSize512B int64 = 512 | |
23 | -) | |
24 | - | |
25 | -// Logger ... | |
26 | -type Logger struct { | |
27 | - mu *sync.Mutex | |
28 | - outputFile *os.File | |
29 | - | |
30 | - outputFileName string | |
31 | - fullName string | |
32 | - maxFileSize int64 | |
33 | - | |
34 | - splitCount int | |
35 | - | |
36 | - directory string | |
37 | -} | |
38 | - | |
39 | -// New ... | |
40 | -func New(name, dir string, maxFileSize int64) (logger *Logger, err error) { | |
41 | - logger = &Logger{} | |
42 | - | |
43 | - logger.outputFileName = name | |
44 | - logger.mu = &sync.Mutex{} | |
45 | - logger.maxFileSize = maxFileSize | |
46 | - logger.directory = dir | |
47 | - | |
48 | - err = os.Mkdir(dir, os.ModePerm) | |
49 | - if err != nil { | |
50 | - if !os.IsExist(err) { | |
51 | - return nil, err | |
52 | - } | |
53 | - } | |
54 | - | |
55 | - date := strings.Replace(time.Now().Format(dateTimeFormat), ":", ".", -1) | |
56 | - logger.outputFileName += " " + date | |
57 | - logger.fullName = logger.outputFileName + ".txt" | |
58 | - path := filepath.Join(dir, logger.fullName) | |
59 | - if logger.outputFile, err = os.Create(path); err != nil { | |
60 | - return nil, err | |
61 | - } | |
62 | - | |
63 | - return logger, nil | |
64 | -} | |
65 | - | |
66 | -// Log ... | |
67 | -func (l *Logger) Log(format string, v ...interface{}) { | |
68 | - if l.outputFile == nil { | |
69 | - return | |
70 | - } | |
71 | - | |
72 | - l.mu.Lock() | |
73 | - defer l.mu.Unlock() | |
74 | - | |
75 | - msg := fmt.Sprintf(format, v...) | |
76 | - s := time.Now().Format(dateTimeFormat) + ": " + msg + "\n" | |
77 | - if l.shouldSplit(len(s)) { | |
78 | - l.split() | |
79 | - } | |
80 | - l.outputFile.WriteString(s) | |
81 | -} | |
82 | - | |
83 | -// Print ... | |
84 | -func (l *Logger) Print(format string, v ...interface{}) { | |
85 | - msg := fmt.Sprintf(format, v...) | |
86 | - fmt.Printf("%s: %s\n", time.Now().Format(dateTimeFormat), msg) | |
87 | -} | |
88 | - | |
89 | -// Trace ... | |
90 | -func (l *Logger) Trace(format string, v ...interface{}) string { | |
91 | - if l.outputFile == nil { | |
92 | - return "" | |
93 | - } | |
94 | - | |
95 | - l.mu.Lock() | |
96 | - defer l.mu.Unlock() | |
97 | - | |
98 | - s := getTrace(format, v...) + "\n" | |
99 | - | |
100 | - if l.shouldSplit(len(s)) { | |
101 | - l.split() | |
102 | - } | |
103 | - l.outputFile.WriteString(s) | |
104 | - | |
105 | - return s | |
106 | -} | |
107 | - | |
108 | -// PrintTrace ... | |
109 | -func (l *Logger) PrintTrace(format string, v ...interface{}) { | |
110 | - s := getTrace(format, v...) | |
111 | - fmt.Printf("%s\n", s) | |
112 | -} | |
113 | - | |
114 | -// PrintAndTrace ... | |
115 | -func (l *Logger) PrintAndTrace(format string, v ...interface{}) { | |
116 | - t := l.Trace(format, v...) | |
117 | - fmt.Println(t) | |
118 | -} | |
119 | - | |
120 | -// Close ... | |
121 | -func (l *Logger) Close() error { | |
122 | - if l.outputFile == nil { | |
123 | - return nil | |
124 | - } | |
125 | - | |
126 | - return l.outputFile.Close() | |
127 | -} | |
128 | - | |
129 | -func (l *Logger) split() error { | |
130 | - if l.outputFile == nil { | |
131 | - return nil | |
132 | - } | |
133 | - | |
134 | - // close old file | |
135 | - err := l.outputFile.Close() | |
136 | - if err != nil { | |
137 | - return err | |
138 | - } | |
139 | - | |
140 | - // open new file | |
141 | - l.splitCount++ | |
142 | - path := filepath.Join(l.directory, l.outputFileName+fmt.Sprintf("(%d)", l.splitCount)+".txt") | |
143 | - l.outputFile, err = os.Create(path) | |
144 | - | |
145 | - return err | |
146 | -} | |
147 | - | |
148 | -func (l *Logger) shouldSplit(nextEntrySize int) bool { | |
149 | - stats, _ := l.outputFile.Stat() | |
150 | - return int64(nextEntrySize) >= (l.maxFileSize - stats.Size()) | |
151 | -} | |
152 | - | |
153 | -func printJSON(in []byte) (out []byte, err error) { | |
154 | - var buf bytes.Buffer | |
155 | - err = json.Indent(&buf, in, "", " ") | |
156 | - return buf.Bytes(), err | |
157 | -} | |
158 | - | |
159 | -// GetOutDir ... | |
160 | -func (l *Logger) GetOutDir() string { | |
161 | - return l.directory | |
162 | -} |
gologger/tracing.go
... | ... | @@ -1,65 +0,0 @@ |
1 | -package gologger | |
2 | - | |
3 | -import ( | |
4 | - "fmt" | |
5 | - "math" | |
6 | - "runtime" | |
7 | - "strings" | |
8 | - "time" | |
9 | -) | |
10 | - | |
11 | -// getCallStack | |
12 | -func getCallStack() (stack []string) { | |
13 | - const ( | |
14 | - maxStackDepth = 10000 | |
15 | - skipRuntime = 2 // skip runtime and startup | |
16 | - skipCallers = 2 | |
17 | - thisPackage = "gologger" | |
18 | - ) | |
19 | - | |
20 | - callers := make([]uintptr, maxStackDepth) // min 1 | |
21 | - | |
22 | - stackDepth := runtime.Callers(skipCallers, callers) | |
23 | - frames := runtime.CallersFrames(callers) | |
24 | - | |
25 | - for i := 0; i < skipRuntime; i++ { | |
26 | - frames.Next() | |
27 | - } | |
28 | - | |
29 | - for i := 0; i < stackDepth-skipRuntime-skipCallers; i++ { | |
30 | - frame, next := frames.Next() | |
31 | - if !strings.Contains(frame.File, thisPackage) { | |
32 | - stack = append(stack, fmt.Sprintf("[%s %d]", frame.File, frame.Line)) | |
33 | - } | |
34 | - if !next { | |
35 | - break | |
36 | - } | |
37 | - } | |
38 | - | |
39 | - reverseStack(stack) | |
40 | - | |
41 | - return stack | |
42 | -} | |
43 | - | |
44 | -// in place | |
45 | -func reverseStack(stack []string) { | |
46 | - middle := int(math.Floor(float64(len(stack)) / 2.0)) | |
47 | - | |
48 | - lastIndex := len(stack) - 1 | |
49 | - for i := 0; i < middle; i++ { | |
50 | - stack[i], stack[lastIndex] = stack[lastIndex], stack[i] | |
51 | - lastIndex-- | |
52 | - } | |
53 | -} | |
54 | - | |
55 | -func getTrace(format string, v ...interface{}) (t string) { | |
56 | - stack := getCallStack() | |
57 | - | |
58 | - t = time.Now().Format(dateTimeFormat) + ":\n" | |
59 | - for _, s := range stack { | |
60 | - t += s + "\n" | |
61 | - } | |
62 | - t += fmt.Sprintf(format, v...) + "\n" | |
63 | - | |
64 | - return t | |
65 | -} |
logger/http_logs.go
... | ... | @@ -0,0 +1,66 @@ |
1 | +package logger | |
2 | + | |
3 | +import ( | |
4 | + "bytes" | |
5 | + "fmt" | |
6 | + "net/http" | |
7 | + "net/http/httputil" | |
8 | + "os" | |
9 | + "strings" | |
10 | + "time" | |
11 | +) | |
12 | + | |
13 | +const splitLine = "==============================================================" | |
14 | + | |
15 | +// LogHTTPRequest ... | |
16 | +func (l *Logger) LogHTTPRequest(req *http.Request, userID string) string { | |
17 | + if userID == "" { | |
18 | + userID = "-" | |
19 | + } | |
20 | + | |
21 | + var b strings.Builder | |
22 | + | |
23 | + b.WriteString("Request:\n") | |
24 | + // CLF-like header | |
25 | + fmt.Fprintf(&b, "%s %s %s\n", req.RemoteAddr, userID, time.Now().Format(dateTimeFormat)) | |
26 | + | |
27 | + body, err := httputil.DumpRequest(req, true) | |
28 | + if err != nil { | |
29 | + fmt.Fprintf(os.Stderr, "%v\n", err) | |
30 | + } | |
31 | + | |
32 | + const sepStr = "\r\n\r\n" | |
33 | + sepIndex := bytes.Index(body, []byte(sepStr)) | |
34 | + if sepIndex == -1 { | |
35 | + b.WriteString(string(body) + "\n\n") | |
36 | + } else { | |
37 | + sepIndex += len(sepStr) | |
38 | + payload, _ := printJSON(body[sepIndex:]) | |
39 | + b.WriteString(string(body[:sepIndex]) + string(payload) + "\n\n") | |
40 | + } | |
41 | + | |
42 | + return b.String() | |
43 | +} | |
44 | + | |
45 | +// LogHTTPResponse ... | |
46 | +func (l *Logger) LogHTTPResponse(data []byte, status int, startTime time.Time) string { | |
47 | + duration := time.Now().Sub(startTime) | |
48 | + jsonData, _ := printJSON(data) | |
49 | + return fmt.Sprintf("Response:\n%d %v %dB\n%s\n%s\n\n", status, duration, len(data), jsonData, splitLine) | |
50 | +} | |
51 | + | |
52 | +// CombineHTTPLogs ... | |
53 | +func (l *Logger) CombineHTTPLogs(in string, out string) { | |
54 | + if l.outputFile == nil { | |
55 | + return | |
56 | + } | |
57 | + | |
58 | + l.mu.Lock() | |
59 | + defer l.mu.Unlock() | |
60 | + | |
61 | + msg := in + out | |
62 | + if l.shouldSplit(len(msg)) { | |
63 | + l.split() | |
64 | + } | |
65 | + l.outputFile.WriteString(msg) | |
66 | +} | ... | ... |
logger/main.go
... | ... | @@ -0,0 +1,162 @@ |
1 | +package logger | |
2 | + | |
3 | +import ( | |
4 | + "bytes" | |
5 | + "encoding/json" | |
6 | + "fmt" | |
7 | + "os" | |
8 | + "path/filepath" | |
9 | + "strings" | |
10 | + "sync" | |
11 | + "time" | |
12 | +) | |
13 | + | |
14 | +const dateTimeFormat = "2006-01-02 15:04:05" | |
15 | + | |
16 | +// Block ... | |
17 | +const ( | |
18 | + MaxLogSize5MB int64 = 5 * 1024 * 1024 | |
19 | + MaxLogSize1MB int64 = 1 * 1024 * 1024 | |
20 | + MaxLogSize500KB int64 = 500 * 1024 | |
21 | + MaxLogSize100KB int64 = 100 * 1024 | |
22 | + MaxLogSize512B int64 = 512 | |
23 | +) | |
24 | + | |
25 | +// Logger ... | |
26 | +type Logger struct { | |
27 | + mu *sync.Mutex | |
28 | + outputFile *os.File | |
29 | + | |
30 | + outputFileName string | |
31 | + fullName string | |
32 | + maxFileSize int64 | |
33 | + | |
34 | + splitCount int | |
35 | + | |
36 | + directory string | |
37 | +} | |
38 | + | |
39 | +// New ... | |
40 | +func New(name, dir string, maxFileSize int64) (logger *Logger, err error) { | |
41 | + logger = &Logger{} | |
42 | + | |
43 | + logger.outputFileName = name | |
44 | + logger.mu = &sync.Mutex{} | |
45 | + logger.maxFileSize = maxFileSize | |
46 | + logger.directory = dir | |
47 | + | |
48 | + err = os.Mkdir(dir, os.ModePerm) | |
49 | + if err != nil { | |
50 | + if !os.IsExist(err) { | |
51 | + return nil, err | |
52 | + } | |
53 | + } | |
54 | + | |
55 | + date := strings.Replace(time.Now().Format(dateTimeFormat), ":", ".", -1) | |
56 | + logger.outputFileName += " " + date | |
57 | + logger.fullName = logger.outputFileName + ".txt" | |
58 | + path := filepath.Join(dir, logger.fullName) | |
59 | + if logger.outputFile, err = os.Create(path); err != nil { | |
60 | + return nil, err | |
61 | + } | |
62 | + | |
63 | + return logger, nil | |
64 | +} | |
65 | + | |
66 | +// Log ... | |
67 | +func (l *Logger) Log(format string, v ...interface{}) { | |
68 | + if l.outputFile == nil { | |
69 | + return | |
70 | + } | |
71 | + | |
72 | + l.mu.Lock() | |
73 | + defer l.mu.Unlock() | |
74 | + | |
75 | + msg := fmt.Sprintf(format, v...) | |
76 | + s := time.Now().Format(dateTimeFormat) + ": " + msg + "\n" | |
77 | + if l.shouldSplit(len(s)) { | |
78 | + l.split() | |
79 | + } | |
80 | + l.outputFile.WriteString(s) | |
81 | +} | |
82 | + | |
83 | +// Print ... | |
84 | +func (l *Logger) Print(format string, v ...interface{}) { | |
85 | + msg := fmt.Sprintf(format, v...) | |
86 | + fmt.Printf("%s: %s\n", time.Now().Format(dateTimeFormat), msg) | |
87 | +} | |
88 | + | |
89 | +// Trace ... | |
90 | +func (l *Logger) Trace(format string, v ...interface{}) string { | |
91 | + if l.outputFile == nil { | |
92 | + return "" | |
93 | + } | |
94 | + | |
95 | + l.mu.Lock() | |
96 | + defer l.mu.Unlock() | |
97 | + | |
98 | + s := getTrace(format, v...) + "\n" | |
99 | + | |
100 | + if l.shouldSplit(len(s)) { | |
101 | + l.split() | |
102 | + } | |
103 | + l.outputFile.WriteString(s) | |
104 | + | |
105 | + return s | |
106 | +} | |
107 | + | |
108 | +// PrintTrace ... | |
109 | +func (l *Logger) PrintTrace(format string, v ...interface{}) { | |
110 | + s := getTrace(format, v...) | |
111 | + fmt.Printf("%s\n", s) | |
112 | +} | |
113 | + | |
114 | +// PrintAndTrace ... | |
115 | +func (l *Logger) PrintAndTrace(format string, v ...interface{}) { | |
116 | + t := l.Trace(format, v...) | |
117 | + fmt.Println(t) | |
118 | +} | |
119 | + | |
120 | +// Close ... | |
121 | +func (l *Logger) Close() error { | |
122 | + if l.outputFile == nil { | |
123 | + return nil | |
124 | + } | |
125 | + | |
126 | + return l.outputFile.Close() | |
127 | +} | |
128 | + | |
129 | +// GetOutDir ... | |
130 | +func (l *Logger) GetOutDir() string { | |
131 | + return l.directory | |
132 | +} | |
133 | + | |
134 | +func (l *Logger) split() error { | |
135 | + if l.outputFile == nil { | |
136 | + return nil | |
137 | + } | |
138 | + | |
139 | + // close old file | |
140 | + err := l.outputFile.Close() | |
141 | + if err != nil { | |
142 | + return err | |
143 | + } | |
144 | + | |
145 | + // open new file | |
146 | + l.splitCount++ | |
147 | + path := filepath.Join(l.directory, l.outputFileName+fmt.Sprintf("(%d)", l.splitCount)+".txt") | |
148 | + l.outputFile, err = os.Create(path) | |
149 | + | |
150 | + return err | |
151 | +} | |
152 | + | |
153 | +func (l *Logger) shouldSplit(nextEntrySize int) bool { | |
154 | + stats, _ := l.outputFile.Stat() | |
155 | + return int64(nextEntrySize) >= (l.maxFileSize - stats.Size()) | |
156 | +} | |
157 | + | |
158 | +func printJSON(in []byte) (out []byte, err error) { | |
159 | + var buf bytes.Buffer | |
160 | + err = json.Indent(&buf, in, "", " ") | |
161 | + return buf.Bytes(), err | |
162 | +} | ... | ... |
logger/tracing.go
... | ... | @@ -0,0 +1,65 @@ |
1 | +package logger | |
2 | + | |
3 | +import ( | |
4 | + "fmt" | |
5 | + "math" | |
6 | + "runtime" | |
7 | + "strings" | |
8 | + "time" | |
9 | +) | |
10 | + | |
11 | +// getCallStack | |
12 | +func getCallStack() (stack []string) { | |
13 | + const ( | |
14 | + maxStackDepth = 10000 | |
15 | + skipRuntime = 2 // skip runtime and startup | |
16 | + skipCallers = 2 | |
17 | + thisPackage = "logger" | |
18 | + ) | |
19 | + | |
20 | + callers := make([]uintptr, maxStackDepth) // min 1 | |
21 | + | |
22 | + stackDepth := runtime.Callers(skipCallers, callers) | |
23 | + frames := runtime.CallersFrames(callers) | |
24 | + | |
25 | + for i := 0; i < skipRuntime; i++ { | |
26 | + frames.Next() | |
27 | + } | |
28 | + | |
29 | + for i := 0; i < stackDepth-skipRuntime-skipCallers; i++ { | |
30 | + frame, next := frames.Next() | |
31 | + if !strings.Contains(frame.File, thisPackage) { | |
32 | + stack = append(stack, fmt.Sprintf("[%s %d]", frame.File, frame.Line)) | |
33 | + } | |
34 | + if !next { | |
35 | + break | |
36 | + } | |
37 | + } | |
38 | + | |
39 | + reverseStack(stack) | |
40 | + | |
41 | + return stack | |
42 | +} | |
43 | + | |
44 | +// in place | |
45 | +func reverseStack(stack []string) { | |
46 | + middle := int(math.Floor(float64(len(stack)) / 2.0)) | |
47 | + | |
48 | + lastIndex := len(stack) - 1 | |
49 | + for i := 0; i < middle; i++ { | |
50 | + stack[i], stack[lastIndex] = stack[lastIndex], stack[i] | |
51 | + lastIndex-- | |
52 | + } | |
53 | +} | |
54 | + | |
55 | +func getTrace(format string, v ...interface{}) (t string) { | |
56 | + stack := getCallStack() | |
57 | + | |
58 | + t = time.Now().Format(dateTimeFormat) + ":\n" | |
59 | + for _, s := range stack { | |
60 | + t += s + "\n" | |
61 | + } | |
62 | + t += fmt.Sprintf(format, v...) + "\n" | |
63 | + | |
64 | + return t | |
65 | +} | ... | ... |
quicksort.go
1 | 1 | package webutility |
2 | 2 | |
3 | -type QSortDirection int | |
3 | +import "sort" | |
4 | 4 | |
5 | -const ( | |
6 | - QSortAscending QSortDirection = iota | |
7 | - QSortDescending | |
8 | -) | |
9 | - | |
10 | -// QuickSortable is an interface for quicksorting slices. | |
11 | -type QuickSortable interface { | |
12 | - Swap(i, j int) | |
13 | - Compare(i, j int) int | |
14 | - Len() int | |
15 | -} | |
16 | - | |
17 | -// Quicksort quicksorts que. | |
18 | -func Quicksort(que QuickSortable, low, high int, dir QSortDirection) { | |
5 | +// QuickSort quicksorts que. | |
6 | +func QuickSort(que sort.Interface, low, high int, reverse bool) { | |
19 | 7 | if low >= high { |
20 | 8 | return |
21 | 9 | } |
22 | 10 | |
23 | - if dir != QSortAscending && dir != QSortDescending { | |
24 | - return | |
25 | - } | |
26 | - | |
27 | - index := partition(que, low, high, dir) | |
28 | - Quicksort(que, low, index-1, dir) | |
29 | - Quicksort(que, index+1, high, dir) | |
11 | + index := quickSortPartition(que, low, high, reverse) | |
12 | + QuickSort(que, low, index-1, reverse) | |
13 | + QuickSort(que, index+1, high, reverse) | |
30 | 14 | } |
31 | 15 | |
32 | -func partition(que QuickSortable, low, high int, dir QSortDirection) int { | |
33 | - swap := 0 | |
34 | - // -1 -> i > j | |
35 | - // 1 -> i < j | |
36 | - if dir == QSortDescending { | |
37 | - swap = -1 | |
38 | - } else { | |
39 | - swap = 1 | |
40 | - } | |
41 | - | |
16 | +func quickSortPartition(que sort.Interface, low, high int, reverse bool) int { | |
42 | 17 | i := low - 1 |
43 | 18 | for j := low; j <= high-1; j++ { |
44 | - if que.Compare(j, high) == swap { | |
45 | - i++ | |
46 | - que.Swap(i, j) | |
19 | + if !reverse { | |
20 | + if que.Less(j, high) { | |
21 | + i++ | |
22 | + que.Swap(i, j) | |
23 | + } | |
24 | + } else { | |
25 | + if !que.Less(j, high) { | |
26 | + i++ | |
27 | + que.Swap(i, j) | |
28 | + } | |
47 | 29 | } |
48 | - continue | |
49 | 30 | } |
50 | 31 | que.Swap(i+1, high) |
51 | 32 | return i + 1 | ... | ... |
server.go
... | ... | @@ -5,14 +5,14 @@ import ( |
5 | 5 | "fmt" |
6 | 6 | "net/http" |
7 | 7 | |
8 | - "git.to-net.rs/marko.tikvic/gologger" | |
8 | + "git.to-net.rs/marko.tikvic/webutility/logger" | |
9 | 9 | "github.com/gorilla/mux" |
10 | 10 | ) |
11 | 11 | |
12 | 12 | type Server struct { |
13 | 13 | DB *sql.DB |
14 | 14 | Router *mux.Router |
15 | - Logger *gologger.Logger | |
15 | + Logger *logger.Logger | |
16 | 16 | Port string |
17 | 17 | DBs map[string]*sql.DB |
18 | 18 | dsn map[string]string |
... | ... | @@ -29,7 +29,7 @@ func NewODBCServer(dsn, port, logDir string) (s *Server, err error) { |
29 | 29 | |
30 | 30 | s.Router = mux.NewRouter() |
31 | 31 | |
32 | - if s.Logger, err = gologger.New("err", logDir, gologger.MaxLogSize1MB); err != nil { | |
32 | + if s.Logger, err = logger.New("err", logDir, logger.MaxLogSize1MB); err != nil { | |
33 | 33 | return nil, fmt.Errorf("can't create logger: %s", err.Error()) |
34 | 34 | } |
35 | 35 | ... | ... |