diff --git a/Website/.classpath b/Website/.classpath new file mode 100644 index 0000000..575edbc --- /dev/null +++ b/Website/.classpath @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Website/.project b/Website/.project new file mode 100644 index 0000000..4e7a5ab --- /dev/null +++ b/Website/.project @@ -0,0 +1,46 @@ + + + R-Memcached + + + + + + org.eclipse.wst.jsdt.core.javascriptValidator + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + com.genuitec.eclipse.j2eedt.core.DeploymentDescriptorValidator + + + + + com.genuitec.eclipse.ast.deploy.core.DeploymentBuilder + + + + + + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.jdt.core.javanature + org.eclipse.wst.jsdt.core.jsNature + + diff --git a/Website/.settings/.jsdtscope b/Website/.settings/.jsdtscope new file mode 100644 index 0000000..3437951 --- /dev/null +++ b/Website/.settings/.jsdtscope @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/Website/.settings/org.eclipse.jdt.core.prefs b/Website/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..11f6e46 --- /dev/null +++ b/Website/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/Website/.settings/org.eclipse.wst.common.component b/Website/.settings/org.eclipse.wst.common.component new file mode 100644 index 0000000..7630ba2 --- /dev/null +++ b/Website/.settings/org.eclipse.wst.common.component @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Website/.settings/org.eclipse.wst.common.project.facet.core.xml b/Website/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..5003545 --- /dev/null +++ b/Website/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/Website/.settings/org.eclipse.wst.jsdt.ui.superType.container b/Website/.settings/org.eclipse.wst.jsdt.ui.superType.container new file mode 100644 index 0000000..3bd5d0a --- /dev/null +++ b/Website/.settings/org.eclipse.wst.jsdt.ui.superType.container @@ -0,0 +1 @@ +org.eclipse.wst.jsdt.launching.baseBrowserLibrary \ No newline at end of file diff --git a/Website/.settings/org.eclipse.wst.jsdt.ui.superType.name b/Website/.settings/org.eclipse.wst.jsdt.ui.superType.name new file mode 100644 index 0000000..05bd71b --- /dev/null +++ b/Website/.settings/org.eclipse.wst.jsdt.ui.superType.name @@ -0,0 +1 @@ +Window \ No newline at end of file diff --git a/Website/WebRoot/WEB-INF/classes/dao/MemcachedServer$bench.class b/Website/WebRoot/WEB-INF/classes/dao/MemcachedServer$bench.class new file mode 100644 index 0000000..a8193e5 Binary files /dev/null and b/Website/WebRoot/WEB-INF/classes/dao/MemcachedServer$bench.class differ diff --git a/Website/WebRoot/WEB-INF/classes/dao/MemcachedServer.class b/Website/WebRoot/WEB-INF/classes/dao/MemcachedServer.class new file mode 100644 index 0000000..4f61cc6 Binary files /dev/null and b/Website/WebRoot/WEB-INF/classes/dao/MemcachedServer.class differ diff --git a/Website/WebRoot/WEB-INF/classes/dao/RMemcachedServer$1.class b/Website/WebRoot/WEB-INF/classes/dao/RMemcachedServer$1.class new file mode 100644 index 0000000..32adaaa Binary files /dev/null and b/Website/WebRoot/WEB-INF/classes/dao/RMemcachedServer$1.class differ diff --git a/Website/WebRoot/WEB-INF/classes/dao/RMemcachedServer$2.class b/Website/WebRoot/WEB-INF/classes/dao/RMemcachedServer$2.class new file mode 100644 index 0000000..33f1c0f Binary files /dev/null and b/Website/WebRoot/WEB-INF/classes/dao/RMemcachedServer$2.class differ diff --git a/Website/WebRoot/WEB-INF/classes/dao/RMemcachedServer$bench.class b/Website/WebRoot/WEB-INF/classes/dao/RMemcachedServer$bench.class new file mode 100644 index 0000000..515f430 Binary files /dev/null and b/Website/WebRoot/WEB-INF/classes/dao/RMemcachedServer$bench.class differ diff --git a/Website/WebRoot/WEB-INF/classes/dao/RMemcachedServer.class b/Website/WebRoot/WEB-INF/classes/dao/RMemcachedServer.class new file mode 100644 index 0000000..a5c5543 Binary files /dev/null and b/Website/WebRoot/WEB-INF/classes/dao/RMemcachedServer.class differ diff --git a/Website/WebRoot/WEB-INF/classes/servlets/GetInfoServlet.class b/Website/WebRoot/WEB-INF/classes/servlets/GetInfoServlet.class new file mode 100644 index 0000000..0844a89 Binary files /dev/null and b/Website/WebRoot/WEB-INF/classes/servlets/GetInfoServlet.class differ diff --git a/Website/WebRoot/WEB-INF/lib/json-org.jar b/Website/WebRoot/WEB-INF/lib/json-org.jar new file mode 100644 index 0000000..3e53d2e Binary files /dev/null and b/Website/WebRoot/WEB-INF/lib/json-org.jar differ diff --git a/Website/WebRoot/WEB-INF/lib/log4j-1.2.17.jar b/Website/WebRoot/WEB-INF/lib/log4j-1.2.17.jar new file mode 100644 index 0000000..068867e Binary files /dev/null and b/Website/WebRoot/WEB-INF/lib/log4j-1.2.17.jar differ diff --git a/Website/WebRoot/WEB-INF/lib/memcached.jar b/Website/WebRoot/WEB-INF/lib/memcached.jar new file mode 100644 index 0000000..016a950 Binary files /dev/null and b/Website/WebRoot/WEB-INF/lib/memcached.jar differ diff --git a/Website/WebRoot/WEB-INF/lib/netty-3.5.7.Final.jar b/Website/WebRoot/WEB-INF/lib/netty-3.5.7.Final.jar new file mode 100644 index 0000000..fb05e76 Binary files /dev/null and b/Website/WebRoot/WEB-INF/lib/netty-3.5.7.Final.jar differ diff --git a/Website/WebRoot/WEB-INF/lib/protobuf-java-2.4.1.jar b/Website/WebRoot/WEB-INF/lib/protobuf-java-2.4.1.jar new file mode 100644 index 0000000..c8ca833 Binary files /dev/null and b/Website/WebRoot/WEB-INF/lib/protobuf-java-2.4.1.jar differ diff --git a/Website/WebRoot/WEB-INF/lib/webserver.jar b/Website/WebRoot/WEB-INF/lib/webserver.jar new file mode 100644 index 0000000..507f3d5 Binary files /dev/null and b/Website/WebRoot/WEB-INF/lib/webserver.jar differ diff --git a/Website/WebRoot/scripts/json.js b/Website/WebRoot/scripts/json.js new file mode 100644 index 0000000..ef41ecd --- /dev/null +++ b/Website/WebRoot/scripts/json.js @@ -0,0 +1,538 @@ +/* + json.js + 2014-02-04 + + Public Domain + + No warranty expressed or implied. Use at your own risk. + + This file has been superceded by http://www.JSON.org/json2.js + + See http://www.JSON.org/js.html + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + This file adds these methods to JavaScript: + + object.toJSONString(whitelist) + This method produce a JSON text from a JavaScript value. + It must not contain any cyclical references. Illegal values + will be excluded. + + The default conversion for dates is to an ISO string. You can + add a toJSONString method to any date object to get a different + representation. + + The object and array methods can take an optional whitelist + argument. A whitelist is an array of strings. If it is provided, + keys in objects not found in the whitelist are excluded. + + string.parseJSON(filter) + This method parses a JSON text to produce an object or + array. It can throw a SyntaxError exception. + + The optional filter parameter is a function which can filter and + transform the results. It receives each of the keys and values, and + its return value is used instead of the original value. If it + returns what it received, then structure is not modified. If it + returns undefined then the member is deleted. + + Example: + + // Parse the text. If a key contains the string 'date' then + // convert the value to a date. + + myData = text.parseJSON(function (key, value) { + return key.indexOf('date') >= 0 ? new Date(value) : value; + }); + + This file will break programs with improper for..in loops. See + http://yuiblog.com/blog/2006/09/26/for-in-intrigue/ + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the object holding the key. + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +/*jslint evil: true, regexp: true, unparam: true */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, parseJSON, prototype, push, replace, slice, + stringify, test, toJSON, toJSONString, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (typeof JSON !== 'object') { + JSON = {}; +} + +(function () { + 'use strict'; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function (key) { + + return isFinite(this.valueOf()) + ? this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' + : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx, + escapable, + gap, + indent, + meta, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' + ? c + : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 + ? '[]' + : gap + ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' + : '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + k = rep[i]; + if (typeof k === 'string') { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 ? '{}' + : gap + ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' + : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }; + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ + .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') + .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' + ? walk({'': j}, '') + : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } + +// Augment the basic prototypes if they have not already been augmented. +// These forms are obsolete. It is recommended that JSON.stringify and +// JSON.parse be used instead. + + if (!Object.prototype.toJSONString) { + Object.prototype.toJSONString = function (filter) { + return JSON.stringify(this, filter); + }; + Object.prototype.parseJSON = function (filter) { + return JSON.parse(this, filter); + }; + } +}()); diff --git a/Website/src/client.xml b/Website/src/client.xml new file mode 100644 index 0000000..923dfd1 --- /dev/null +++ b/Website/src/client.xml @@ -0,0 +1,31 @@ + + + + 0000 + 192.168.3.224 + 10000 + 30000 + 192.168.3.224:20000 + + + 0001 + 192.168.3.204 + 10000 + 30000 + 192.168.3.204:20000 + + + 0002 + 192.168.3.244 + 10000 + 30000 + 192.168.3.244:20000 + + + 0003 + 192.168.3.218 + 10000 + 30000 + 192.168.3.218:20000 + + \ No newline at end of file diff --git a/Website/src/dao/MemcachedServer.java b/Website/src/dao/MemcachedServer.java new file mode 100644 index 0000000..35cdb53 --- /dev/null +++ b/Website/src/dao/MemcachedServer.java @@ -0,0 +1,173 @@ +/** + * Copyright (c) 2008 Greg Whalin + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the BSD license + * + * This library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + * + * You should have received a copy of the BSD License along with this + * library. + * + * @author Greg Whalin + */ +package dao; + +import java.util.Random; +import com.meetup.memcached.*; +import org.apache.log4j.PropertyConfigurator; + +public class MemcachedServer { + static String ORIGINPATH = Thread.currentThread().getContextClassLoader().getResource("").getPath(); + + public static void main(String[] args){ + MemcachedServer.run(args); + } + + public static void run(String[] args) + { + PropertyConfigurator.configure(ORIGINPATH +"log4j.properties");//¼ÓÔØ.propertiesÎļþ + String[] serverlist = { "192.168.3.224:20000", "192.168.3.204:20000" , "192.168.3.244:20000" , "192.168.3.218:20000" }; + + // initialize the pool for memcache servers + SockIOPool pool = SockIOPool.getInstance(); + pool.setServers( serverlist ); + + pool.setInitConn(5); + pool.setMinConn(5); + pool.setMaxConn(50); + pool.setMaintSleep(10); + + pool.setNagle(false); + pool.initialize(); + + int threads = Integer.parseInt(args[0]); + int runs = Integer.parseInt(args[1]); + int Nums = Integer.parseInt(args[2]); // how many kilobytes + int size = Integer.parseInt(args[3]); // how many kilobytes + double rate = Double.parseDouble(args[4]); //¶Áд±ÈÀý + + // get object to store + byte[] obj = new byte[size]; + for (int i = 0; i < size; i++) + { + obj[i] = '1'; + } + String value = new String(obj); + String[] keys = new String[Nums]; + for (int i = 0; i < Nums; i++) + { + keys[i] = "" + i; + } + +// DatabaseCon.getInstance().start(); +// for (int i = 0; i < 100000; i++) +// { +// DatabaseCon.getInstance().setKey(String.valueOf(i), value); +// } +// System.out.println("insert data successful"); + + for (int i = 0; i < threads; i++) + { + bench b = new bench(runs, Nums, i, value, keys, rate); + b.start(); + } +// pool.shutDown(); +// System.exit(1); + } + + /** + * Test code per thread. + */ + private static class bench extends Thread + { + private int runs; + private String object; + private String[] keys; + private int nums; + @SuppressWarnings("unused") + private int ticks=0; + @SuppressWarnings("unused") + private long diffTime = 0; + private double rate; + + public bench(int runs,int nums, int threadNum, String object, String[] keys, double rate) + { + this.runs = runs; + this.object = object; + this.keys = keys; + this.nums = nums; + this.rate = rate; + } + + public void run() + { + MemcachedClient mc = new MemcachedClient(); + mc.setCompressEnable(false); + mc.setCompressThreshold(0); + //DatabaseCon.getInstance().start(); + long time = 0; + time = System.nanoTime(); + randReadWrite(mc, rate); + time = System.nanoTime() - time; + System.out.println(time/1000000000.0); + } + + public void randReadWrite(MemcachedClient mc, double scale) + { + Random randNum = new Random(); + for (int i = 1; i <= runs; i++) + { +// long begin = System.nanoTime(); + if (Math.random() m_mapMemcachedClient; + static String ORIGINPATH = Thread.currentThread().getContextClassLoader().getResource("").getPath(); + public static Boolean status = false; + public static int threadCount = 0; + private static int startIndex = 0; + public static boolean initFlag = false; + + public static long time = 0; + private static Map localStats = new HashMap<>(); + public static JSONArray nodeStats = new JSONArray(); + + public static void main(String[] args){ + new Thread(new Runnable() { + public void run() { + RMemcachedServer.run(new String[]{"10","1000","1000","8","0.8"}); + } + }).start(); + while (!RMemcachedServer.initFlag) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + while (!RMemcachedServer.status) { + try { + Thread.sleep(200); + } catch (InterruptedException e) { + e.printStackTrace(); + } + RMemcachedServer.getResult(); + } + RMemcachedServer.getResult(); + System.out.println(webSession.results.length()); + //System.out.println(nodeStats); + //System.out.println(time); + + for (int i = 0; i < 50; i++){ + new Thread(new Runnable() { + public void run() { + RMemcachedServer.run(new String[]{"10","1000","1000","8","0.8"}); + } + }).start(); + while (!RMemcachedServer.initFlag) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + while (!RMemcachedServer.status) { + RMemcachedServer.getResult(); + try { + Thread.sleep(200); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + RMemcachedServer.getResult(); + System.out.println(webSession.results.length()); + } + System.exit(0); + } + + private static void initial(){ + RMemcachedServer.startIndex = 0; + RMemcachedServer.initFlag = false; + RMemcachedServer.status = false; + RMemcachedServer.time = 0; + RMemcachedServer.nodeStats = new JSONArray(); + RMemcachedServer.localStats = new HashMap<>(); + RMemcachedServer.threadCount = 0; + webSession.results = new JSONArray(); + } + + public static void run(String[] args) { + initial(); + //System.out.println(ORIGINPATH); + PropertyConfigurator.configure(ORIGINPATH + "log4j.properties"); + initConfig(); + + RegisterHandler.initHandler(); + webSession.getInstance().start(); + //new webSession().start(); + + + MemcachedMgr clientMgr = MemcachedMgr.getInstance(); + clientMgr.init(m_mapMemcachedClient); + + Server requestServer = Server.getInstance(); + requestServer.init(8888); + + localStats = new HashMap<>(); + try { + Thread.sleep(200); + } catch (Exception e) { + e.printStackTrace(); + } + getStats(); + + int threads = Integer.parseInt(args[0]); + int runs = Integer.parseInt(args[1]); + int Nums = Integer.parseInt(args[2]); + int size = Integer.parseInt(args[3]); + double rate = Double.parseDouble(args[4]); + RMemcachedServer.threadCount = threads; + + byte[] obj = new byte[size]; + for (int i = 0; i < size; i++) { + obj[i] = '1'; + } + String value = new String(obj); + String[] keys = new String[Nums]; + for (int i = 0; i < Nums; i++) { + keys[i] = "" + i; + } + RMemcachedServer.initFlag = true; + for (int i = 0; i < threads; i++) { + bench b = new bench(runs, Nums, i, value, keys, rate); + b.start(); + } + while (threadCount != 0 || startIndex < threads*runs*rate){ + //System.out.println("threadCounts= " + threadCount + " startIndex= " + startIndex); + try { + Thread.sleep(200); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + getStats(); + time = time/threads; + status = true; + requestServer.stop(); + RMemcachedServer.initFlag = false; + webSession.session = null; + System.out.println("session finish"); + } + + public static JSONArray test(){ + Map stats = new HashMap<>(); + stats.put("key", "371"); + stats.put("node", "3"); + stats.put("type", "GET"); + stats.put("value", "111111111111"); + + JSONArray jsons = new JSONArray(); + jsons.put(stats); + jsons.put(stats); + return jsons; + } + + public static JSONArray getResult() { + JSONArray results = new JSONArray(); + JSONArray arrays = webSession.results; + int endIndex = arrays.length(); + for (int i = startIndex; i < endIndex && i < startIndex + 1000; i++){ + try { + JSONObject aResult = (JSONObject) arrays.get(i); + int nodeNum = Integer.parseInt((String) aResult.get("node")); + aResult.put("node", getOriginNode(nodeNum)); + results.put(aResult); + } catch (Exception e) { + e.printStackTrace(); + } + } + startIndex = endIndex < startIndex+1000 ? endIndex : startIndex+1000; + System.out.println(results.length()); + return results; + } + + public static void getStats() { + webSession.getInstance().stats(); + while (webSession.stats.size() != 4){ + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + if (localStats == null || localStats.size() == 0) { + localStats = webSession.stats; + } else { + try { + for (int i = 0; i < 4; i++){ + int key = (int) Math.pow(2, i); + JSONObject jStats_new = new JSONObject(webSession.stats.get(key)); + JSONObject jStats_old = new JSONObject(localStats.get(key)); + int cmd_get_old = Integer.parseInt((String) jStats_old.get("cmd_get")); + int cmd_set_old = Integer.parseInt((String) jStats_old.get("cmd_set")); + int cmd_get_new = Integer.parseInt((String) jStats_new.get("cmd_get")); + int cmd_set_new = Integer.parseInt((String) jStats_new.get("cmd_set")); + int cmd_get = cmd_get_new - cmd_get_old; + int cmd_set = cmd_set_new - cmd_set_old; + Map node = new HashMap<>(); + node.put("node", i); + node.put("get", cmd_get); + node.put("set", cmd_set); + nodeStats.put(node); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + webSession.stats = new HashMap<>(); + } + + public static boolean initConfig() { + if (m_mapMemcachedClient != null && m_mapMemcachedClient.size() >0 ){ + return true; + } + m_mapMemcachedClient = new HashMap(); + String path = ORIGINPATH + "client.xml"; + readClientsXML(path); + return true; + } + + private static class bench extends Thread { + private int runs; + @SuppressWarnings("unused") + private int threadNum; + private String object; + private String[] keys; + @SuppressWarnings("unused") + private int size; + private int nums; + private double rate; + + public bench(int runs,int nums, int threadNum, String object, String[] keys, double rate) { + this.runs = runs; + this.threadNum = threadNum; + this.object = object; + this.keys = keys; + this.size = object.length(); + this.nums = nums; + this.rate = rate; + } + + public void run() { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + long time = 0; + time = System.nanoTime(); + randReadWrite(rate); + RMemcachedServer.threadCount --; + time = System.nanoTime() - time; + RMemcachedServer.time += time; + //System.out.println(time / 1000000000.0f); + } + + public void randReadWrite(double scale) { + Random randNum = new Random(); + int getCount = (int) (runs*scale); + int setCount = runs - getCount; + for (int i = 0, j = 0, k = 0; i < runs; i++) { + if ((Math.random() < scale || j >= setCount) && k <= getCount) { + webSession.getInstance().get(keys[randNum.nextInt(nums)]); + k ++; + } else { + webSession.getInstance().set(keys[randNum.nextInt(nums)], object); + j ++; + } + try { + Thread.sleep((long) 0.00001); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + + public static boolean readClientsXML(String str) { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + try { + factory.setIgnoringElementContentWhitespace(true); + + DocumentBuilder db = factory.newDocumentBuilder(); + Document xmldoc = db.parse(new File(str)); + Element elmtInfo = xmldoc.getDocumentElement(); + NodeList nodes = elmtInfo.getChildNodes(); + for (int i = 0; i < nodes.getLength(); i++) { + Node result = nodes.item(i); + if (result.getNodeType() == Node.ELEMENT_NODE + && result.getNodeName().equals("client")) { + NodeList ns = result.getChildNodes(); + ClientConfig localClient = new ClientConfig(); + int m = 0; + for (int j = 0; j < ns.getLength(); j++) { + Node record = ns.item(j); + if (record.getNodeType() == Node.ELEMENT_NODE) { + if (record.getNodeName().equals("id")) { + m++; + localClient.id = Integer.decode(record + .getTextContent()); + } else if (record.getNodeName().equals("host")) { + m++; + localClient.host = record.getTextContent(); + } else if (record.getNodeName().equals("client_port")) { + m++; + localClient.client_port = Integer.decode(record + .getTextContent()); + } else if (record.getNodeName().equals("memcached")) { + m++; + localClient.memcached = record.getTextContent(); + } + } + } + if (m == 4) { + m_mapMemcachedClient.put(localClient.id, localClient); + } + } + } + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } catch (SAXException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return true; + } + + public static String getOriginNode(int num) { + String out = ""; + while (num != 0){ + int n = getMax(num); + num = num % (int)Math.pow(2, n); + out += out==""?"":"-"; + out += n; + } + return out; + } + private static int getMax(int num){ + int n = -1; + while (num != 0){ + num = num / 2; + n ++; + } + return n; + } +} diff --git a/Website/src/log4j.properties b/Website/src/log4j.properties new file mode 100644 index 0000000..8e1b149 --- /dev/null +++ b/Website/src/log4j.properties @@ -0,0 +1,4 @@ +log4j.rootLogger=WARN, stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n \ No newline at end of file