Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(198)

Side by Side Diff: dm/tools/jobsim_client/edit_distance.go

Issue 2339413003: Refactor and test jobsim_client. (Closed)
Patch Set: Use pool from options Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « dm/tools/jobsim_client/.gitignore ('k') | dm/tools/jobsim_client/edit_distance_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The LUCI Authors. All rights reserved. 1 // Copyright 2016 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 package main 5 package main
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "encoding/json" 9 "encoding/json"
10 "fmt"
11 "math" 10 "math"
12 "strings" 11 "strings"
13 12
14 "github.com/maruel/subcommands" 13 "github.com/maruel/subcommands"
15 ) 14 )
16 15
17 var cmdEditDistance = &subcommands.Command{ 16 var cmdEditDistance = &subcommands.Command{
18 UsageLine: `edit-distance [options]`, 17 UsageLine: `edit-distance [options]`,
19 ShortDesc: `Computes the edit distance of two strings.`, 18 ShortDesc: `Computes the edit distance of two strings.`,
20 LongDesc: `Computes the edit distance of two strings using insertion, de letion, 19 LongDesc: `Computes the edit distance of two strings using insertion, de letion,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 OpHistory string `json:"op_history"` 62 OpHistory string `json:"op_history"`
64 Error string `json:"error,omitempty"` 63 Error string `json:"error,omitempty"`
65 } 64 }
66 65
67 func (e *editDistanceRun) Run(a subcommands.Application, args []string) int { 66 func (e *editDistanceRun) Run(a subcommands.Application, args []string) int {
68 e.start(a, e, cmdEditDistance) 67 e.start(a, e, cmdEditDistance)
69 68
70 p := &EditParams{} 69 p := &EditParams{}
71 err := json.NewDecoder(bytes.NewBufferString(e.questDesc.Parameters)).De code(p) 70 err := json.NewDecoder(bytes.NewBufferString(e.questDesc.Parameters)).De code(p)
72 if err != nil { 71 if err != nil {
73 » » e.finish(0, "", err) 72 » » return e.finish(EditResult{Error: err.Error()})
73 » }
74
75 » rslt, stop := e.compute(p)
76 » if stop {
74 return 0 77 return 0
75 } 78 }
76 79
77 » e.finish(e.compute(p)) 80 » return e.finish(rslt)
78 » return 0
79 } 81 }
80 82
81 var editSymbolLookup = map[string]string{ 83 var editSymbolLookup = map[string]string{
82 "substitution": "~", 84 "substitution": "~",
83 "insertion": "+", 85 "insertion": "+",
84 "deletion": "-", 86 "deletion": "-",
85 "equality": "=", 87 "equality": "=",
86 "transposition": "X", 88 "transposition": "X",
87 } 89 }
88 90
89 func (e *editDistanceRun) compute(p *EditParams) (uint32, string, error) { 91 func (e *editDistanceRun) compute(p *EditParams) (rslt EditResult, stop bool) {
90 // If one string is empty, the edit distance is the length of the other 92 // If one string is empty, the edit distance is the length of the other
91 // string. 93 // string.
92 if len(p.A) == 0 { 94 if len(p.A) == 0 {
93 » » return uint32(len(p.B)), strings.Repeat("+", len(p.B)), nil 95 » » rslt.Distance = uint32(len(p.B))
96 » » rslt.OpHistory = strings.Repeat("+", len(p.B))
97 » » return
94 } else if len(p.B) == 0 { 98 } else if len(p.B) == 0 {
95 » » return uint32(len(p.A)), strings.Repeat("-", len(p.A)), nil 99 » » rslt.Distance = uint32(len(p.A))
100 » » rslt.OpHistory = strings.Repeat("-", len(p.A))
101 » » return
96 } 102 }
97 103
98 // If both strings are exactly equality, the distance between them is 0. 104 // If both strings are exactly equality, the distance between them is 0.
99 if p.A == p.B { 105 if p.A == p.B {
100 » » return 0, strings.Repeat("=", len(p.A)), nil 106 » » rslt.OpHistory = strings.Repeat("=", len(p.A))
107 » » return
101 } 108 }
102 109
103 toDep := []interface{}{ 110 toDep := []interface{}{
104 &EditParams{ // substitution || equality 111 &EditParams{ // substitution || equality
105 A: p.A[1:], 112 A: p.A[1:],
106 B: p.B[1:], 113 B: p.B[1:],
107 }, 114 },
108 &EditParams{ // deletion (remove a char from A) 115 &EditParams{ // deletion (remove a char from A)
109 A: p.A[1:], 116 A: p.A[1:],
110 B: p.B, 117 B: p.B,
111 }, 118 },
112 &EditParams{ // insertion (add the char to A) 119 &EditParams{ // insertion (add the char to A)
113 A: p.A, 120 A: p.A,
114 B: p.B[1:], 121 B: p.B[1:],
115 }, 122 },
116 } 123 }
117 if e.useTransposition && len(p.A) > 1 && len(p.B) > 1 { 124 if e.useTransposition && len(p.A) > 1 && len(p.B) > 1 {
118 » » if p.A[0] == p.B[1] && p.B[0] == p.A[1] { 125 » » if p.A[0] == p.B[1] && p.A[1] == p.B[0] {
119 toDep = append(toDep, &EditParams{ // transposition 126 toDep = append(toDep, &EditParams{ // transposition
120 A: p.A[2:], 127 A: p.A[2:],
121 B: p.B[2:], 128 B: p.B[2:],
122 }) 129 })
123 } 130 }
124 } 131 }
125 132
126 opNames := []string{ 133 opNames := []string{
127 "substitution", "deletion", "insertion", "transposition", 134 "substitution", "deletion", "insertion", "transposition",
128 } 135 }
129 if p.A[0] == p.B[0] { 136 if p.A[0] == p.B[0] {
130 opNames[0] = "equality" 137 opNames[0] = "equality"
131 } 138 }
132 139
133 retval := uint32(math.MaxUint32) 140 retval := uint32(math.MaxUint32)
134 opname := "" 141 opname := ""
135 opchain := "" 142 opchain := ""
136 » for i, rslt := range e.depOn(toDep...) { 143
144 » depsData, stop := e.depOn(toDep...)
145 » if stop {
146 » » return
147 » }
148
149 » for i, dep := range depsData {
137 result := &EditResult{} 150 result := &EditResult{}
138 » » err := json.NewDecoder(bytes.NewBufferString(rslt)).Decode(resul t) 151 » » err := json.NewDecoder(bytes.NewBufferString(dep)).Decode(result )
139 if err != nil { 152 if err != nil {
140 » » » return 0, "", err 153 » » » rslt.Error = err.Error()
154 » » » return
141 } 155 }
142 156
143 opName := opNames[i] 157 opName := opNames[i]
144 if result.Error != "" { 158 if result.Error != "" {
145 » » » return 0, "!" + result.OpHistory, fmt.Errorf(result.Erro r) 159 » » » rslt.OpHistory = "!" + result.OpHistory
160 » » » rslt.Error = result.Error
161 » » » return
146 } 162 }
147 cost := result.Distance 163 cost := result.Distance
148 if opName != "equality" { 164 if opName != "equality" {
149 // all operations (except equality) cost 1 165 // all operations (except equality) cost 1
150 cost++ 166 cost++
151 } 167 }
152 if cost < retval { 168 if cost < retval {
153 retval = cost 169 retval = cost
154 opname = opName 170 opname = opName
155 opchain = result.OpHistory 171 opchain = result.OpHistory
156 } 172 }
157 } 173 }
158 174
159 » return retval, editSymbolLookup[opname] + opchain, nil 175 » rslt.Distance = retval
176 » rslt.OpHistory = editSymbolLookup[opname] + opchain
177 » return
160 } 178 }
161
162 func (e *editDistanceRun) finish(dist uint32, opHistory string, err error) {
163 if err == nil {
164 e.cmdRun.finish(&EditResult{dist, opHistory, ""})
165 } else {
166 e.cmdRun.finish(&EditResult{Error: err.Error()})
167 }
168 }
OLDNEW
« no previous file with comments | « dm/tools/jobsim_client/.gitignore ('k') | dm/tools/jobsim_client/edit_distance_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698