-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[core] Record latency of successful and failed operations separately #507
Merged
Merged
Changes from 3 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
66c2b6c
[core] Fix some coding style issues in DBWrapper.java
stfeng2 d4ff9ec
[core] Record latency of successful and failed operations separately
stfeng2 3e3d401
[core] Incorporate CR feedback
stfeng2 78563ec
[core] Incorporate CR feedback (2)
stfeng2 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,25 @@ | ||
/** | ||
* Copyright (c) 2010 Yahoo! Inc. All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you | ||
* may not use this file except in compliance with the License. You | ||
* may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||
* implied. See the License for the specific language governing | ||
* permissions and limitations under the License. See accompanying | ||
* LICENSE file. | ||
/** | ||
* Copyright (c) 2010 Yahoo! Inc. All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you | ||
* may not use this file except in compliance with the License. You | ||
* may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||
* implied. See the License for the specific language governing | ||
* permissions and limitations under the License. See accompanying | ||
* LICENSE file. | ||
*/ | ||
|
||
package com.yahoo.ycsb; | ||
|
||
import java.util.Arrays; | ||
import java.util.HashMap; | ||
import java.util.HashSet; | ||
import java.util.Properties; | ||
import java.util.Set; | ||
import java.util.Vector; | ||
|
@@ -26,157 +28,196 @@ | |
|
||
/** | ||
* Wrapper around a "real" DB that measures latencies and counts return codes. | ||
* Also reports latency separately between OK and failed operations. | ||
*/ | ||
public class DBWrapper extends DB | ||
{ | ||
DB _db; | ||
Measurements _measurements; | ||
|
||
public DBWrapper(DB db) | ||
{ | ||
_db=db; | ||
_measurements=Measurements.getMeasurements(); | ||
} | ||
|
||
/** | ||
* Set the properties for this DB. | ||
*/ | ||
public void setProperties(Properties p) | ||
{ | ||
_db.setProperties(p); | ||
} | ||
|
||
/** | ||
* Get the set of properties for this DB. | ||
*/ | ||
public Properties getProperties() | ||
{ | ||
return _db.getProperties(); | ||
} | ||
|
||
/** | ||
* Initialize any state for this DB. | ||
* Called once per DB instance; there is one DB instance per client thread. | ||
*/ | ||
public void init() throws DBException | ||
{ | ||
_db.init(); | ||
} | ||
|
||
/** | ||
* Cleanup any state for this DB. | ||
* Called once per DB instance; there is one DB instance per client thread. | ||
*/ | ||
public void cleanup() throws DBException | ||
{ | ||
long ist=_measurements.getIntendedtartTimeNs(); | ||
long st = System.nanoTime(); | ||
_db.cleanup(); | ||
long en=System.nanoTime(); | ||
measure("CLEANUP",ist, st, en); | ||
} | ||
|
||
/** | ||
* Read a record from the database. Each field/value pair from the result will be stored in a HashMap. | ||
* | ||
* @param table The name of the table | ||
* @param key The record key of the record to read. | ||
* @param fields The list of fields to read, or null for all of them | ||
* @param result A HashMap of field/value pairs for the result | ||
* @return The result of the operation. | ||
*/ | ||
public Status read(String table, String key, Set<String> fields, HashMap<String,ByteIterator> result) | ||
{ | ||
long ist=_measurements.getIntendedtartTimeNs(); | ||
long st = System.nanoTime(); | ||
Status res=_db.read(table,key,fields,result); | ||
long en=System.nanoTime(); | ||
measure("READ",ist, st, en); | ||
_measurements.reportStatus("READ",res); | ||
return res; | ||
} | ||
|
||
/** | ||
* Perform a range scan for a set of records in the database. Each field/value pair from the result will be stored in a HashMap. | ||
* | ||
* @param table The name of the table | ||
* @param startkey The record key of the first record to read. | ||
* @param recordcount The number of records to read | ||
* @param fields The list of fields to read, or null for all of them | ||
* @param result A Vector of HashMaps, where each HashMap is a set field/value pairs for one record | ||
* @return The result of the operation. | ||
*/ | ||
public Status scan(String table, String startkey, int recordcount, Set<String> fields, Vector<HashMap<String,ByteIterator>> result) | ||
{ | ||
long ist=_measurements.getIntendedtartTimeNs(); | ||
long st = System.nanoTime(); | ||
Status res=_db.scan(table,startkey,recordcount,fields,result); | ||
long en=System.nanoTime(); | ||
measure("SCAN",ist, st, en); | ||
_measurements.reportStatus("SCAN",res); | ||
return res; | ||
} | ||
|
||
private void measure(String op, long intendedStartTimeNanos, long startTimeNanos, long endTimeNanos) { | ||
_measurements.measure(op, (int)((endTimeNanos-startTimeNanos)/1000)); | ||
_measurements.measureIntended(op, (int)((endTimeNanos-intendedStartTimeNanos)/1000)); | ||
DB _db; | ||
Measurements _measurements; | ||
|
||
boolean reportLatencyForEachError = false; | ||
HashSet<String> latencyTrackedErrors = new HashSet<String>(); | ||
|
||
public DBWrapper(DB db) | ||
{ | ||
_db=db; | ||
_measurements=Measurements.getMeasurements(); | ||
} | ||
|
||
/** | ||
* Set the properties for this DB. | ||
*/ | ||
public void setProperties(Properties p) | ||
{ | ||
_db.setProperties(p); | ||
} | ||
|
||
/** | ||
* Get the set of properties for this DB. | ||
*/ | ||
public Properties getProperties() | ||
{ | ||
return _db.getProperties(); | ||
} | ||
|
||
/** | ||
* Initialize any state for this DB. | ||
* Called once per DB instance; there is one DB instance per client thread. | ||
*/ | ||
public void init() throws DBException | ||
{ | ||
_db.init(); | ||
|
||
this.reportLatencyForEachError = Boolean.parseBoolean(getProperties(). | ||
getProperty("reportlatencyforeacherror", "false")); | ||
|
||
if (!reportLatencyForEachError) { | ||
String latencyTrackedErrors = getProperties().getProperty( | ||
"latencytrackederrors", null); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here, pull these into variables. |
||
if (latencyTrackedErrors != null) { | ||
this.latencyTrackedErrors = new HashSet<String>(Arrays.asList( | ||
latencyTrackedErrors.split(","))); | ||
} | ||
} | ||
|
||
/** | ||
* Update a record in the database. Any field/value pairs in the specified values HashMap will be written into the record with the specified | ||
* record key, overwriting any existing values with the same field name. | ||
* | ||
* @param table The name of the table | ||
* @param key The record key of the record to write. | ||
* @param values A HashMap of field/value pairs to update in the record | ||
* @return The result of the operation. | ||
*/ | ||
public Status update(String table, String key, HashMap<String,ByteIterator> values) | ||
{ | ||
long ist=_measurements.getIntendedtartTimeNs(); | ||
long st = System.nanoTime(); | ||
Status res=_db.update(table,key,values); | ||
long en=System.nanoTime(); | ||
measure("UPDATE",ist, st, en); | ||
_measurements.reportStatus("UPDATE",res); | ||
return res; | ||
} | ||
|
||
/** | ||
* Insert a record in the database. Any field/value pairs in the specified values HashMap will be written into the record with the specified | ||
* record key. | ||
* | ||
* @param table The name of the table | ||
* @param key The record key of the record to insert. | ||
* @param values A HashMap of field/value pairs to insert in the record | ||
* @return The result of the operation. | ||
*/ | ||
public Status insert(String table, String key, HashMap<String,ByteIterator> values) | ||
{ | ||
long ist=_measurements.getIntendedtartTimeNs(); | ||
long st = System.nanoTime(); | ||
Status res=_db.insert(table,key,values); | ||
long en=System.nanoTime(); | ||
measure("INSERT",ist, st, en); | ||
_measurements.reportStatus("INSERT",res); | ||
return res; | ||
} | ||
|
||
/** | ||
* Delete a record from the database. | ||
* | ||
* @param table The name of the table | ||
* @param key The record key of the record to delete. | ||
* @return The result of the operation. | ||
*/ | ||
public Status delete(String table, String key) | ||
{ | ||
long ist=_measurements.getIntendedtartTimeNs(); | ||
long st = System.nanoTime(); | ||
Status res=_db.delete(table,key); | ||
long en=System.nanoTime(); | ||
measure("DELETE",ist, st, en); | ||
_measurements.reportStatus("DELETE",res); | ||
return res; | ||
} | ||
|
||
System.err.println("DBWrapper: report latency for each error is " + | ||
this.reportLatencyForEachError + " and specific error codes to track" + | ||
" for latency are: " + this.latencyTrackedErrors.toString()); | ||
} | ||
|
||
/** | ||
* Cleanup any state for this DB. | ||
* Called once per DB instance; there is one DB instance per client thread. | ||
*/ | ||
public void cleanup() throws DBException | ||
{ | ||
long ist=_measurements.getIntendedtartTimeNs(); | ||
long st = System.nanoTime(); | ||
_db.cleanup(); | ||
long en=System.nanoTime(); | ||
measure("CLEANUP", Status.OK, ist, st, en); | ||
} | ||
|
||
/** | ||
* Read a record from the database. Each field/value pair from the result | ||
* will be stored in a HashMap. | ||
* | ||
* @param table The name of the table | ||
* @param key The record key of the record to read. | ||
* @param fields The list of fields to read, or null for all of them | ||
* @param result A HashMap of field/value pairs for the result | ||
* @return The result of the operation. | ||
*/ | ||
public Status read(String table, String key, Set<String> fields, | ||
HashMap<String,ByteIterator> result) | ||
{ | ||
long ist=_measurements.getIntendedtartTimeNs(); | ||
long st = System.nanoTime(); | ||
Status res=_db.read(table,key,fields,result); | ||
long en=System.nanoTime(); | ||
measure("READ", res, ist, st, en); | ||
_measurements.reportStatus("READ", res); | ||
return res; | ||
} | ||
|
||
/** | ||
* Perform a range scan for a set of records in the database. | ||
* Each field/value pair from the result will be stored in a HashMap. | ||
* | ||
* @param table The name of the table | ||
* @param startkey The record key of the first record to read. | ||
* @param recordcount The number of records to read | ||
* @param fields The list of fields to read, or null for all of them | ||
* @param result A Vector of HashMaps, where each HashMap is a set field/value pairs for one record | ||
* @return The result of the operation. | ||
*/ | ||
public Status scan(String table, String startkey, int recordcount, | ||
Set<String> fields, Vector<HashMap<String,ByteIterator>> result) | ||
{ | ||
long ist=_measurements.getIntendedtartTimeNs(); | ||
long st = System.nanoTime(); | ||
Status res=_db.scan(table,startkey,recordcount,fields,result); | ||
long en=System.nanoTime(); | ||
measure("SCAN", res, ist, st, en); | ||
_measurements.reportStatus("SCAN", res); | ||
return res; | ||
} | ||
|
||
private void measure(String op, Status result, long intendedStartTimeNanos, | ||
long startTimeNanos, long endTimeNanos) { | ||
String measurementName = op; | ||
if (result != Status.OK) { | ||
if (this.reportLatencyForEachError || | ||
this.latencyTrackedErrors.contains(result.getName())) { | ||
measurementName = op + "-" + result.getName(); | ||
} else { | ||
measurementName = op + "-FAILED"; | ||
} | ||
} | ||
_measurements.measure(measurementName, | ||
(int)((endTimeNanos-startTimeNanos)/1000)); | ||
_measurements.measureIntended(measurementName, | ||
(int)((endTimeNanos-intendedStartTimeNanos)/1000)); | ||
} | ||
|
||
/** | ||
* Update a record in the database. Any field/value pairs in the specified values HashMap will be written into the record with the specified | ||
* record key, overwriting any existing values with the same field name. | ||
* | ||
* @param table The name of the table | ||
* @param key The record key of the record to write. | ||
* @param values A HashMap of field/value pairs to update in the record | ||
* @return The result of the operation. | ||
*/ | ||
public Status update(String table, String key, | ||
HashMap<String,ByteIterator> values) | ||
{ | ||
long ist=_measurements.getIntendedtartTimeNs(); | ||
long st = System.nanoTime(); | ||
Status res=_db.update(table,key,values); | ||
long en=System.nanoTime(); | ||
measure("UPDATE", res, ist, st, en); | ||
_measurements.reportStatus("UPDATE", res); | ||
return res; | ||
} | ||
|
||
/** | ||
* Insert a record in the database. Any field/value pairs in the specified | ||
* values HashMap will be written into the record with the specified | ||
* record key. | ||
* | ||
* @param table The name of the table | ||
* @param key The record key of the record to insert. | ||
* @param values A HashMap of field/value pairs to insert in the record | ||
* @return The result of the operation. | ||
*/ | ||
public Status insert(String table, String key, | ||
HashMap<String,ByteIterator> values) | ||
{ | ||
long ist=_measurements.getIntendedtartTimeNs(); | ||
long st = System.nanoTime(); | ||
Status res=_db.insert(table,key,values); | ||
long en=System.nanoTime(); | ||
measure("INSERT", res, ist, st, en); | ||
_measurements.reportStatus("INSERT", res); | ||
return res; | ||
} | ||
|
||
/** | ||
* Delete a record from the database. | ||
* | ||
* @param table The name of the table | ||
* @param key The record key of the record to delete. | ||
* @return The result of the operation. | ||
*/ | ||
public Status delete(String table, String key) | ||
{ | ||
long ist=_measurements.getIntendedtartTimeNs(); | ||
long st = System.nanoTime(); | ||
Status res=_db.delete(table,key); | ||
long en=System.nanoTime(); | ||
measure("DELETE", res, ist, st, en); | ||
_measurements.reportStatus("DELETE", res); | ||
return res; | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you pull the property string and default values into variables? You can see this convention in CoreWorkload: https://github.com/brianfrankcooper/YCSB/blob/master/core/src/main/java/com/yahoo/ycsb/workloads/CoreWorkload.java#L110-L117
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.