Keyboard Shortcuts

File
u :up to issue
m :publish + mail comments
M :edit review message
j / k :jump to file after / before current file
J / K :jump to next file with a comment after / before current file
Side-by-side diff
i :toggle intra-line diffs
e :expand all comments
c :collapse all comments
s :toggle showing all comments
n / p :next / previous diff chunk or comment
N / P :next / previous comment
<Up> / <Down> :next / previous line
<Enter> :respond to / edit current comment
d :mark current comment as done
Issue
u :up to list of issues
m :publish + mail comments
j / k :jump to patch after / before current patch
o / <Enter> :open current patch in side-by-side view
i :open current patch in unified diff view
Issue List
j / k :jump to issue after / before current issue
o / <Enter> :open current issue
# : close issue
Comment/message editing
<Ctrl> + s or <Ctrl> + Enter :save comment
<Esc> :cancel edit
Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(84)
Issues Repositories Search
Open Issues | Closed Issues | All Issues | Sign in with your Google Account to create issues and add comments

Delta Between Two Patch Sets: src/pkg/database/sql/sql.go

Issue 116930043: code review 116930043: database/sql: Avoid re-preparing statements when all co...
Left Patch Set: diff -r 277f98d885558a00e899f6e89958e97470fd8ab4 https://code.google.com/p/go Created 11 years, 4 months ago
Right Patch Set: diff -r c31e69cab80bd1ef8dd17b8269a8c108c167b516 https://code.google.com/p/go Created 11 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | src/pkg/database/sql/sql_test.go » ('j') | no next file with change/comment »
('i') | ('e') | ('c') | ('s')
LEFTRIGHT
1 // Copyright 2011 The Go Authors. All rights reserved. 1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // Package sql provides a generic interface around SQL (or SQL-like) 5 // Package sql provides a generic interface around SQL (or SQL-like)
6 // databases. 6 // databases.
7 // 7 //
8 // The sql package must be used in conjunction with a database driver. 8 // The sql package must be used in conjunction with a database driver.
9 // See http://golang.org/s/sqldrivers for a list of drivers. 9 // See http://golang.org/s/sqldrivers for a list of drivers.
10 // 10 //
(...skipping 1308 matching lines...) | | Loading...
1319 if s.tx != nil { 1319 if s.tx != nil {
1320 s.mu.Unlock() 1320 s.mu.Unlock()
1321 ci, err = s.tx.grabConn() // blocks, waiting for the connection. 1321 ci, err = s.tx.grabConn() // blocks, waiting for the connection.
1322 if err != nil { 1322 if err != nil {
1323 return 1323 return
1324 } 1324 }
1325 releaseConn = func(error) {} 1325 releaseConn = func(error) {}
1326 return ci, releaseConn, s.txsi.si, nil 1326 return ci, releaseConn, s.txsi.si, nil
1327 } 1327 }
1328 1328
1329 » var cs connStmt 1329 » connStmtInfo := func(cs connStmt) (ci *driverConn, releaseConn func(erro r), si driver.Stmt, err error) {
bradfitz 2014年09月02日 16:08:06 This could be a top-level function, but better I r
This could be a top-level function, but better I realize is to just ditch it and inline it. Easier to understand callers that way anyway. I'll do this before I submit to not drag this on longer.
1330 » var dc *driverConn 1330 » » conn := cs.dc
1331 » match := false 1331 » » return conn, conn.releaseConn, cs.si, nil
1332 » }
1333
1332 for i := 0; i < len(s.css); i++ { 1334 for i := 0; i < len(s.css); i++ {
1333 v := s.css[i] 1335 v := s.css[i]
1334 _, err := s.db.connIfFree(v.dc) 1336 _, err := s.db.connIfFree(v.dc)
1335 if err == nil { 1337 if err == nil {
1336 » » » match = true 1338 » » » s.mu.Unlock()
1337 » » » cs = v 1339 » » » return connStmtInfo(v)
1338 » » » break
1339 } 1340 }
1340 if err == errConnClosed { 1341 if err == errConnClosed {
1341 // Lazily remove dead conn from our freelist. 1342 // Lazily remove dead conn from our freelist.
1342 s.css[i] = s.css[len(s.css)-1] 1343 s.css[i] = s.css[len(s.css)-1]
1343 s.css = s.css[:len(s.css)-1] 1344 s.css = s.css[:len(s.css)-1]
1344 i-- 1345 i--
1345 } 1346 }
1346 1347
1347 } 1348 }
1348 s.mu.Unlock() 1349 s.mu.Unlock()
1349 if match {
1350 goto found
1351 }
1352 1350
1353 // If all connections are busy, either wait for one to become available (if 1351 // If all connections are busy, either wait for one to become available (if
1354 // we've already hit the maximum number of open connections) or create a 1352 // we've already hit the maximum number of open connections) or create a
1355 // new one. 1353 // new one.
1356 // 1354 //
1357 // TODO(bradfitz): or always wait for one? make configurable later? 1355 // TODO(bradfitz): or always wait for one? make configurable later?
1358 » dc, err = s.db.conn() 1356 » dc, err := s.db.conn()
1359 if err != nil { 1357 if err != nil {
1360 return nil, nil, nil, err 1358 return nil, nil, nil, err
1361 } 1359 }
1362 1360
1363 // Do another pass over the list to see whether this statement has 1361 // Do another pass over the list to see whether this statement has
1364 // already been prepared on the connection assigned to us. 1362 // already been prepared on the connection assigned to us.
1365 s.mu.Lock() 1363 s.mu.Lock()
1366 for _, v := range s.css { 1364 for _, v := range s.css {
1367 if v.dc == dc { 1365 if v.dc == dc {
1368 » » » match = true 1366 » » » s.mu.Unlock()
1369 » » » cs = v 1367 » » » return connStmtInfo(v)
1370 » » » break
1371 } 1368 }
1372 } 1369 }
1373 s.mu.Unlock() 1370 s.mu.Unlock()
1374 if match {
1375 goto found
1376 }
1377 1371
1378 // No luck; we need to prepare the statement on this connection 1372 // No luck; we need to prepare the statement on this connection
1379 dc.Lock() 1373 dc.Lock()
1380 si, err = dc.prepareLocked(s.query) 1374 si, err = dc.prepareLocked(s.query)
1381 dc.Unlock() 1375 dc.Unlock()
1382 if err != nil { 1376 if err != nil {
1383 s.db.putConn(dc, err) 1377 s.db.putConn(dc, err)
1384 return nil, nil, nil, err 1378 return nil, nil, nil, err
1385 } 1379 }
1386 s.mu.Lock() 1380 s.mu.Lock()
1387 » cs = connStmt{dc, si} 1381 » cs := connStmt{dc, si}
1388 s.css = append(s.css, cs) 1382 s.css = append(s.css, cs)
1389 s.mu.Unlock() 1383 s.mu.Unlock()
1390 1384
1391 found: 1385 » return connStmtInfo(cs)
1392 » conn := cs.dc
1393 » return conn, conn.releaseConn, cs.si, nil
1394 } 1386 }
1395 1387
1396 // Query executes a prepared query statement with the given arguments 1388 // Query executes a prepared query statement with the given arguments
1397 // and returns the query results as a *Rows. 1389 // and returns the query results as a *Rows.
1398 func (s *Stmt) Query(args ...interface{}) (*Rows, error) { 1390 func (s *Stmt) Query(args ...interface{}) (*Rows, error) {
1399 s.closemu.RLock() 1391 s.closemu.RLock()
1400 defer s.closemu.RUnlock() 1392 defer s.closemu.RUnlock()
1401 1393
1402 var rowsi driver.Rows 1394 var rowsi driver.Rows
1403 for i := 0; i < maxBadConnRetries; i++ { 1395 for i := 0; i < maxBadConnRetries; i++ {
(...skipping 323 matching lines...) | | Loading...
1727 var buf [2 << 10]byte 1719 var buf [2 << 10]byte
1728 return string(buf[:runtime.Stack(buf[:], false)]) 1720 return string(buf[:runtime.Stack(buf[:], false)])
1729 } 1721 }
1730 1722
1731 // withLock runs while holding lk. 1723 // withLock runs while holding lk.
1732 func withLock(lk sync.Locker, fn func()) { 1724 func withLock(lk sync.Locker, fn func()) {
1733 lk.Lock() 1725 lk.Lock()
1734 fn() 1726 fn()
1735 lk.Unlock() 1727 lk.Unlock()
1736 } 1728 }
LEFTRIGHT
« no previous file | src/pkg/database/sql/sql_test.go » ('j') | ('i') | ('e') | ('c') | ('s')
Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b

AltStyle によって変換されたページ (->オリジナル) /