text:
package org.ektorp;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.ektorp.http.URI;
import org.ektorp.impl.StdObjectMapperFactory;
import org.ektorp.util.Assert;
import org.ektorp.util.Exceptions;

/**
 *
 * @author henrik lundgren
 *
 */
public class ViewQuery {

	private final static ObjectMapper DEFAULT_MAPPER = new StdObjectMapperFactory().createObjectMapper();
	private final static String ALL_DOCS_VIEW_NAME = "_all_docs";
	private final static int NOT_SET = -1;

	private final Map<String, String> queryParams = new TreeMap<String, String>();

	private ObjectMapper mapper;

	private String dbPath;
	private String designDocId;
	private String viewName;
    private Object key;
    private Keys keys;
	private Object startKey;
	private String startDocId;
	private Object endKey;
	private String endDocId;
	private int limit = NOT_SET;
	private String staleOk;
	private boolean descending;
	private int skip = NOT_SET;
	private boolean group;
	private int groupLevel = NOT_SET;
	private boolean reduce = true;
	private boolean includeDocs = false;
	private boolean inclusiveEnd = true;
	private boolean ignoreNotFound = false;
	private boolean updateSeq = false;

	private boolean cacheOk = false;

	private String cachedQuery;
	private String listName;

	public ViewQuery() {
		mapper = DEFAULT_MAPPER;
	}
	/**
	 * Bring your own ObjectMapper.
	 * The mapper is used when serializing keys when building the query.
	 * @param om
	 */
	public ViewQuery(ObjectMapper om) {
		Assert.notNull(om, "ObjectMapper may not be null");
		mapper = om;
	}

    public String getDbPath() {
        return dbPath;
    }

    public String getDesignDocId() {
        return designDocId;
    }

    public String getViewName() {
        return viewName;
    }

    public String getStartDocId() {
        return startDocId;
    }

    public String getEndDocId() {
        return endDocId;
    }

    public int getLimit() {
        return limit;
    }

    public boolean isStaleOk() {
        return staleOk != null && ("ok".equals(staleOk) || "update_after".equals(staleOk));
    }

    public boolean isDescending() {
        return descending;
    }

    public int getSkip() {
        return skip;
    }

    public boolean isGroup() {
        return group;
    }

    public int getGroupLevel() {
        return groupLevel;
    }

    public boolean isReduce() {
        return reduce;
    }

    public boolean isIncludeDocs() {
        return includeDocs;
    }

    public boolean isInclusiveEnd() {
        return inclusiveEnd;
    }

    public boolean isUpdateSeq() {
        return updateSeq;
    }

    public ViewQuery dbPath(String s) {
		reset();
		dbPath = s;
		return this;
	}

	public ViewQuery designDocId(String s) {
		reset();
		designDocId = s;
		return this;
	}
	/**
	 * Will automatically set the query special _all_docs URI.
	 * In this case, setting designDocId will have no effect.
	 * @return
	 */
	public ViewQuery allDocs() {
		reset();
		viewName = ALL_DOCS_VIEW_NAME;
		return this;
	}

	public ViewQuery viewName(String s) {
		reset();
		viewName = s;
		return this;
	}

	public ViewQuery listName(String s) {
		reset();
		listName = s;
		return this;
	}
	/**
	 * If set to true, the view query result will be cached and subsequent queries
	 * (with cacheOk set) may be served from the cache instead of the db.
	 *
	 * Note that if the view changes, the cache will be invalidated.
	 *
	 * @param b
	 * @return
	 */
	public ViewQuery cacheOk(boolean b) {
		reset();
		cacheOk = b;
		return this;
	}

	public boolean isCacheOk() {
		return cacheOk;
	}
	/**
	 * @param Will be JSON-encoded.
	 * @return the view query for chained calls
	 */
	public ViewQuery key(String s) {
		reset();
		key = s;
		return this;
	}
	/**
	 * @param Will be parsed as JSON.
	 * @return the view query for chained calls
	 */
	public ViewQuery rawKey(String s) {
		reset();
		key = parseJson(s);
		return this;
	}

	private JsonNode parseJson(String s) {
		try {
			return mapper.readTree(s);
		} catch (Exception e) {
			throw Exceptions.propagate(e);
		}
	}
	/**
	 * @param Will be JSON-encoded.
	 * @return the view query for chained calls
	 */
	public ViewQuery key(int i) {
		reset();
		key = i;
		return this;
	}
	/**
	 * @param Will be JSON-encoded.
	 * @return the view query for chained calls
	 */
	public ViewQuery key(long l) {
		reset();
		key = l;
		return this;
	}
	/**
	 * @param Will be JSON-encoded.
	 * @return the view query for chained calls
	 */
	public ViewQuery key(float f) {
		reset();
		key = f;
		return this;
	}
	/**
	 * @param Will be JSON-encoded.
	 * @return the view query for chained calls
	 */
	public ViewQuery key(double d) {
		reset();
		key = d;
		return this;
	}
	/**
	 * @param Will be JSON-encoded.
	 * @return the view query for chained calls
	 */
	public ViewQuery key(boolean b) {
		reset();
		key = b;
		return this;
	}
	/**
	 * @param Will be JSON-encoded.
	 * @return the view query for chained calls
	 */
	public ViewQuery key(Object o) {
		reset();
		key = o;
		return this;
	}
    /**
     * For multiple-key queries (as of CouchDB 0.9). Keys will be JSON-encoded.
     * @param keyList a list of Object, will be JSON encoded according to each element's type.
     * @return the view query for chained calls
     */
    public ViewQuery keys(Collection<?> keyList) {
        reset();
        keys = Keys.of(keyList);
        return this;
    }

    public Keys getKeys() {
        return keys;
    }

    public Collection<?> getKeysValues() {
        return keys.getValues();
    }

	/**
	 * @param Will be JSON-encoded.
	 * @return the view query for chained calls
	 */
	public ViewQuery startKey(String s) {
		reset();
		startKey = s;
		return this;
	}

	/**
	 * @param Will be parsed as json
	 * @return the view query for chained calls
	 */
	public ViewQuery rawStartKey(String s) {
		reset();
		startKey = parseJson(s);
		return this;
	}
	/**
	 * @param Will be JSON-encoded.
	 * @return the view query for chained calls
	 */
	public ViewQuery startKey(int i) {
		reset();
		startKey = i;
		return this;
	}
	/**
	 * @param Will be JSON-encoded.
	 * @return the view query for chained calls
	 */
	public ViewQuery startKey(long l) {
		reset();
		startKey = l;
		return this;
	}
	/**
	 * @param Will be JSON-encoded.
	 * @return the view query for chained calls
	 */
	public ViewQuery startKey(float f) {
		reset();
		startKey = f;
		return this;
	}
	/**
	 * @param Will be JSON-encoded.
	 * @return the view query for chained calls
	 */
	public ViewQuery startKey(double d) {
		reset();
		startKey = d;
		return this;
	}
	/**
	 * @param Will be JSON-encoded.
	 * @return the view query for chained calls
	 */
	public ViewQuery startKey(boolean b) {
		reset();
		startKey = b;
		return this;
	}

	/**
	 * @param Will be JSON-encoded.
	 * @return the view query for chained calls
	 */
	public ViewQuery startKey(Object o) {
		reset();
		startKey = o;
		return this;
	}

	public ViewQuery startDocId(String s) {
		reset();
		startDocId = s;
		return this;
	}
	/**
	 * @param will be JSON-encoded.
     * @return the view query for chained calls
	 */
	public ViewQuery endKey(String s) {
		reset();
		endKey = s;
		return this;
	}
	/**
	 * @param will be parsed as JSON.
     * @return the view query for chained calls
	 */
	public ViewQuery rawEndKey(String s) {
		reset();
		endKey = parseJson(s);
		return this;
	}
	/**
	 * @param Will be JSON-encoded.
	 * @return the view query for chained calls
	 */
	public ViewQuery endKey(int i) {
		reset();
		endKey = i;
		return this;
	}
	/**
	 * @param Will be JSON-encoded.
	 * @return the view query for chained calls
	 */
	public ViewQuery endKey(long l) {
		reset();
		endKey = l;
		return this;
	}
	/**
	 * @param Will be JSON-encoded.
	 * @return the view query for chained calls
	 */
	public ViewQuery endKey(float f) {
		reset();
		endKey = f;
		return this;
	}
	/**
	 * @param Will be JSON-encoded.
	 * @return the view query for chained calls
	 */
	public ViewQuery endKey(double d) {
		reset();
		endKey = d;
		return this;
	}
	/**
	 * @param Will be JSON-encoded.
	 * @return the view query for chained calls
	 */
	public ViewQuery endKey(boolean b) {
		reset();
		endKey = b;
		return this;
	}

	/**
	 * @param Will be JSON-encoded.
	 * @return the view query for chained calls
	 */
	public ViewQuery endKey(Object o) {
		reset();
		endKey = o;
		return this;
	}

	public ViewQuery endDocId(String s) {
		reset();
		endDocId = s;
		return this;
	}
	/**
	 * limit=0 you don't get any data, but all meta-data for this View. The number of documents in this View for example.
	 * @param i the limit
     * @return the view query for chained calls
	 */
	public ViewQuery limit(int i) {
		reset();
		limit = i;
		return this;
	}
	/**
	 * The stale option can be used for higher performance at the cost of possibly not seeing the all latest data. If you set the stale option to ok, CouchDB may not perform any refreshing on the view that may be necessary.
	 * @param b the staleOk flag
     * @return the view query for chained calls
	 */
	public ViewQuery staleOk(boolean b) {
		reset();
		staleOk = b ? "ok" : null;
		return this;
	}
	/**
	 * Same as staleOk(true) but will also trigger a rebuild of the view index after the results of the view have been retrieved.
	 * (since CouchDB 1.1.0)
	 * @return
	 */
	public ViewQuery staleOkUpdateAfter() {
		reset();
		staleOk = "update_after";
		return this;
	}
	/**
	 * View rows are sorted by the key; specifying descending=true will reverse their order. Note that the descending option is applied before any key filtering, so you may need to swap the values of the startkey and endkey options to get the expected results.
	 * @param b the descending flag
     * @return the view query for chained calls
	 */
	public ViewQuery descending(boolean b) {
		reset();
		descending = b;
		return this;
	}
	/**
	 * The skip option should only be used with small values, as skipping a large range of documents this way is inefficient (it scans the index from the startkey and then skips N elements, but still needs to read all the index values to do that). For efficient paging you'll need to use startkey and limit. If you expect to have multiple documents emit identical keys, you'll need to use startkey_docid in addition to startkey to paginate correctly. The reason is that startkey alone will no longer be sufficient to uniquely identify a row.
	 * @param i the skip count
     * @return the view query for chained calls
	 */
	public ViewQuery skip(int i) {
		reset();
		skip = i;
		return this;
	}
	/**
	 * The group option controls whether the reduce function reduces to a set of distinct keys or to a single result row.
	 * @param b the group flag
     * @return the view query for chained calls
	 */
	public ViewQuery group(boolean b) {
		reset();
		group = b;
		return this;
	}

	public ViewQuery groupLevel(int i) {
		reset();
		groupLevel = i;
		return this;
	}
	/**
	 * If a view contains both a map and reduce function, querying that view will by default return the result of the reduce function. The result of the map function only may be retrieved by passing reduce=false as a query parameter.
     * @param b the reduce flag
     * @return the view query for chained calls
	 */
	public ViewQuery reduce(boolean b) {
		reset();
		reduce = b;
		return this;
	}
	/**
	 * The include_docs option will include the associated document. Although, the user should keep in mind that there is a race condition when using this option. It is possible that between reading the view data and fetching the corresponding document that the document has changed. If you want to alleviate such concerns you should emit an object with a _rev attribute as in emit(key, {"_rev": doc._rev}). This alleviates the race condition but leaves the possiblity that the returned document has been deleted (in which case, it includes the "_deleted": true attribute).
	 * @param b the includeDocs flag
     * @return the view query for chained calls
	 */
	public ViewQuery includeDocs(boolean b) {
		reset();
		includeDocs = b;
		return this;
	}
	/**
	 * The inclusive_end option controls whether the endkey is included in the result. It defaults to true.
	 * @param b the inclusiveEnd flag
     * @return the view query for chained calls
	 */
	public ViewQuery inclusiveEnd(boolean b) {
		reset();
		inclusiveEnd = b;
		return this;
	}

	/**
	 * The update_seq option adds a field to the result indicating the update_seq the view reflects.  It defaults to false.
	 * @param b the updateSeq flag
	 * @return the view query for chained calls
	 */
	public ViewQuery updateSeq(boolean b) {
		reset();
		updateSeq = b;
		return this;
	}

	public ViewQuery queryParam(String name, String value) {
		queryParams.put(name, value);
		return this;
	}

	/**
	 * Resets internal state so this builder can be used again.
	 */
	public void reset() {
		cachedQuery = null;
	}

	public Object getKey() {
		return key;
	}

    public boolean hasMultipleKeys() {
    	return keys != null;
    }

    public String getKeysAsJson() {
    	if (keys == null) {
    		return "{\"keys\":[]}";
    	}
        return keys.toJson(mapper);
    }

    public Object getStartKey() {
		return startKey;
	}

	public Object getEndKey() {
		return endKey;
	}

	public String buildQuery() {
		if (cachedQuery != null) {
			return cachedQuery;
		}

        URI query = buildQueryURI();

		cachedQuery = query.toString();
		return cachedQuery;
	}

    public URI buildQueryURI() {
		URI query = buildViewPath();

		if (isNotEmpty(key)) {
			query.param("key", jsonEncode(key));
		}

		if (isNotEmpty(startKey)) {
			query.param("startkey", jsonEncode(startKey));
		}

		if (isNotEmpty(endKey)) {
			query.param("endkey", jsonEncode(endKey));
		}

		if (isNotEmpty(startDocId)) {
			query.param("startkey_docid", startDocId);
		}

		if (isNotEmpty(endDocId)) {
			query.param("endkey_docid", endDocId);
		}

		if (hasValue(limit)) {
			query.param("limit", limit);
		}

		if (staleOk != null) {
			query.param("stale", staleOk);
		}

		if (descending) {
			query.param("descending", "true");
		}

		if (!inclusiveEnd) {
			query.param("inclusive_end", "false");
		}

		if (!reduce) {
			query.param("reduce", "false");
		}

		if (hasValue(skip)) {
			query.param("skip", skip);
		}

		if (includeDocs) {
			query.param("include_docs", "true");
		}

		if (group) {
			query.param("group", "true");
		}

		if (hasValue(groupLevel)) {
			query.param("group_level", groupLevel);
		}

		if (!queryParams.isEmpty()) {
			appendQueryParams(query);
		}

		if(updateSeq) {
			query.param("update_seq", "true");
		}
		return query;
	}

    @edu.umd.cs.findbugs.annotations.SuppressWarnings({"SA_FIELD_SELF_ASSIGNMENT", "CN_IMPLEMENTS_CLONE_BUT_NOT_CLONEABLE"})
	public ViewQuery clone() {
		ViewQuery copy = new ViewQuery();
		copy.mapper = mapper;
		copy.cacheOk = cacheOk;
		copy.dbPath = dbPath;
		copy.descending = descending;
		copy.designDocId = designDocId;
		copy.endDocId = endDocId;
		copy.endKey = endKey;
		copy.group = group;
		copy.groupLevel = groupLevel;
		copy.ignoreNotFound = ignoreNotFound;
		copy.includeDocs = includeDocs;
		copy.inclusiveEnd = inclusiveEnd;
		copy.key = key;
		if (keys != null) {
			copy.keys = keys.clone();
		}
		copy.limit = limit;
		copy.listName = listName;
		copy.queryParams.putAll(queryParams);
		copy.reduce = reduce;
		copy.skip = copy.skip;
		copy.staleOk = staleOk;
		copy.startDocId = startDocId;
		copy.startKey = startKey;
		copy.updateSeq = updateSeq;
		copy.viewName = viewName;
		return copy;
	}

	private String jsonEncode(Object key) {
		try {
			return mapper.writeValueAsString(key);
		} catch (Exception e) {
			throw Exceptions.propagate(e);
		}
	}
	private void appendQueryParams(URI query) {
		for (Map.Entry<String, String> param : queryParams.entrySet()) {
			query.param(param.getKey(), param.getValue());
		}
	}

	private URI buildViewPath() {
		assertHasText(dbPath, "dbPath");
		assertHasText(viewName, "viewName");

		URI uri = URI.of(dbPath);
		if (isNotEmpty(listName)) {
			uri.append(designDocId).append("_list").append(listName).append(viewName);
		} else if (ALL_DOCS_VIEW_NAME.equals(viewName)) {
			uri.append(viewName);
		} else {
			assertHasText(designDocId, "designDocId");
			uri.append(designDocId).append("_view").append(viewName);
		}
		return uri;
	}

	private void assertHasText(String s, String fieldName) {
		if (s == null || s.length() == 0) {
			throw new IllegalStateException(String.format("%s must have a value", fieldName));
		}
	}

	private boolean hasValue(int i) {
		return i != NOT_SET;
	}

	private boolean isNotEmpty(Object s) {
		return s != null;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((cachedQuery == null) ? 0 : cachedQuery.hashCode());
		result = prime * result + ((dbPath == null) ? 0 : dbPath.hashCode());
		result = prime * result + (descending ? 1231 : 1237);
		result = prime * result
				+ ((designDocId == null) ? 0 : designDocId.hashCode());
		result = prime * result
				+ ((endDocId == null) ? 0 : endDocId.hashCode());
		result = prime * result + ((endKey == null) ? 0 : endKey.hashCode());
		result = prime * result + (group ? 1231 : 1237);
		result = prime * result + groupLevel;
		result = prime * result + (ignoreNotFound ? 1231 : 1237);
		result = prime * result + (includeDocs ? 1231 : 1237);
		result = prime * result + (inclusiveEnd ? 1231 : 1237);
		result = prime * result + (updateSeq ? 1231 : 1237);
		result = prime * result + ((key == null) ? 0 : key.hashCode());
		result = prime * result + limit;
		result = prime * result
				+ ((listName == null) ? 0 : listName.hashCode());
		result = prime * result
				+ ((queryParams == null) ? 0 : queryParams.hashCode());
		result = prime * result + (reduce ? 1231 : 1237);
		result = prime * result + skip;
		result = prime * result + ((staleOk == null) ? 0 : staleOk.hashCode());
		result = prime * result
				+ ((startDocId == null) ? 0 : startDocId.hashCode());
		result = prime * result
				+ ((startKey == null) ? 0 : startKey.hashCode());
		result = prime * result
				+ ((viewName == null) ? 0 : viewName.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ViewQuery other = (ViewQuery) obj;
		if (cachedQuery == null) {
			if (other.cachedQuery != null)
				return false;
		} else if (!cachedQuery.equals(other.cachedQuery))
			return false;
		if (dbPath == null) {
			if (other.dbPath != null)
				return false;
		} else if (!dbPath.equals(other.dbPath))
			return false;
		if (descending != other.descending)
			return false;
		if (designDocId == null) {
			if (other.designDocId != null)
				return false;
		} else if (!designDocId.equals(other.designDocId))
			return false;
		if (endDocId == null) {
			if (other.endDocId != null)
				return false;
		} else if (!endDocId.equals(other.endDocId))
			return false;
		if (endKey == null) {
			if (other.endKey != null)
				return false;
		} else if (!endKey.equals(other.endKey))
			return false;
		if (group != other.group)
			return false;
		if (groupLevel != other.groupLevel)
			return false;
		if (ignoreNotFound != other.ignoreNotFound)
			return false;
		if (includeDocs != other.includeDocs)
			return false;
		if (inclusiveEnd != other.inclusiveEnd)
			return false;
		if (updateSeq != other.updateSeq)
			return false;
		if (key == null) {
			if (other.key != null)
				return false;
		} else if (!key.equals(other.key))
			return false;
		if (limit != other.limit)
			return false;
		if (listName == null) {
			if (other.listName != null)
				return false;
		} else if (!listName.equals(other.listName))
			return false;
		if (queryParams == null) {
			if (other.queryParams != null)
				return false;
		} else if (!queryParams.equals(other.queryParams))
			return false;
		if (reduce != other.reduce)
			return false;
		if (skip != other.skip)
			return false;
		if (staleOk == null) {
			if (other.staleOk != null)
				return false;
		} else if (!staleOk.equals(other.staleOk))
			return false;
		if (startDocId == null) {
			if (other.startDocId != null)
				return false;
		} else if (!startDocId.equals(other.startDocId))
			return false;
		if (startKey == null) {
			if (other.startKey != null)
				return false;
		} else if (!startKey.equals(other.startKey))
			return false;
		if (viewName == null) {
			if (other.viewName != null)
				return false;
		} else if (!viewName.equals(other.viewName))
			return false;
		return true;
	}
	public void setIgnoreNotFound(boolean ignoreNotFound) {
		this.ignoreNotFound = ignoreNotFound;
	}

	public boolean isIgnoreNotFound() {
		return ignoreNotFound;
	}

	@Override
	public String toString() {
		return buildQuery();
	}

	public static class Keys {

		private final List<?> keys;

		public static Keys of(Collection<?> keys) {
			return new Keys(keys.toArray());
		}

		public static Keys of(Object... keys) {
			return new Keys(keys);
		}

		private Keys(Collection<?> keys) {
			this.keys = new ArrayList<Object>(keys);
		}

		private Keys(Object[] keys) {
			this.keys = Arrays.asList(keys);
		}

        public List<?> getValues() {
            return Collections.unmodifiableList(keys);
		}

        @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="CN_IMPLEMENTS_CLONE_BUT_NOT_CLONEABLE")
		public Keys clone() {
			return new Keys(keys);
		}

		public String toJson() {
			return toJson(DEFAULT_MAPPER);
		}

		public String toJson(ObjectMapper mapper) {
			ObjectNode rootNode = mapper.createObjectNode();
			ArrayNode keysNode = rootNode.putArray("keys");
			for (Object key : keys) {
				keysNode.addPOJO(key);
			}
			try {
				return mapper.writeValueAsString(rootNode);
			} catch (Exception e) {
				throw Exceptions.propagate(e);
			}
		}
	}

}


text:
package org.apache.tomcat.jdbc.test;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.junit.After;
import org.junit.Before;

import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
import org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory;
import org.apache.tomcat.jdbc.pool.PoolConfiguration;
import org.apache.tomcat.jdbc.pool.PoolProperties;

/**
 * @version 1.0
 */
public abstract class DefaultTestCase {

    protected org.apache.tomcat.jdbc.pool.DataSource datasource;
    protected BasicDataSource tDatasource;
//    protected ComboPooledDataSource c3p0Datasource;
    protected int threadcount = 10;
    protected int iterations = 100000;

    public org.apache.tomcat.jdbc.pool.DataSource createDefaultDataSource() {
        org.apache.tomcat.jdbc.pool.DataSource datasource = null;
        PoolConfiguration p = new DefaultProperties();
        p.setFairQueue(false);
        p.setJmxEnabled(false);
        p.setTestWhileIdle(false);
        p.setTestOnBorrow(false);
        p.setTestOnReturn(false);
        p.setValidationInterval(30000);
        p.setTimeBetweenEvictionRunsMillis(30000);
        p.setMaxActive(threadcount);
        p.setInitialSize(threadcount);
        p.setMaxWait(10000);
        p.setRemoveAbandonedTimeout(10);
        p.setMinEvictableIdleTimeMillis(10000);
        p.setMinIdle(threadcount);
        p.setLogAbandoned(false);
        p.setRemoveAbandoned(false);
        datasource = new org.apache.tomcat.jdbc.pool.DataSource();
        datasource.setPoolProperties(p);
        return datasource;
    }

    @Before
    public void init() throws Exception {
        this.datasource = createDefaultDataSource();
    }

    protected void transferProperties() {
        try {
            Properties p = new Properties();
            for (int i=0; i< ALL_PROPERTIES.length; i++) {

                String property = ALL_PROPERTIES[i];
                String dbcpProperty = handleRenames(property);

                String name = "get" + Character.toUpperCase(property.charAt(0)) + property.substring(1);
                String bname = "is" + name.substring(3);
                Method get = null;
                try {
                    get = PoolProperties.class.getMethod(name, new Class[0]);
                }catch (NoSuchMethodException x) {
                    try {
                        get = PoolProperties.class.getMethod(bname, new Class[0]);
                    }catch (NoSuchMethodException x2) {
                        String msg = x2.getMessage();
                        if (msg.indexOf("isPoolPreparedStatements")>=0) {
                            //noop - ignore known missing properties
                        } else if (msg.indexOf("isMaxOpenPreparedStatements")>=0) {
                            //noop - ignore known missing properties
                        } else {
                            System.err.println("Missing property:"+x2.getMessage());
                        }
                    }
                }
                   if (get!=null) {
                       Object value = get.invoke(datasource.getPoolProperties(), new Object[0]);
                       if (value!=null) {
                           p.setProperty(dbcpProperty, value.toString());
                       }
                }
            }
            tDatasource = BasicDataSourceFactory.createDataSource(p);
        }catch (Exception x) {
            x.printStackTrace();
        }
    }

    private String handleRenames(String oldName) {
        if (RENAMED.containsKey(oldName)) {
            return RENAMED.get(oldName);
        }
        return oldName;
    }

    protected void transferPropertiesToC3P0() throws Exception {
//        System.setProperty("com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL", "WARNING");
//        MLog.getLogger().setLevel(MLevel.WARNING);
//        MLog.getLogger("com").setLevel(MLevel.WARNING);
//        //http://www.mchange.com/projects/c3p0/index.html#automaticTestTable
//        ComboPooledDataSource c3p0 = new ComboPooledDataSource();
//        c3p0.setAcquireIncrement(1);
//        c3p0.setAcquireRetryAttempts(2);
//        c3p0.setAcquireRetryDelay(datasource.getPoolProperties().getMaxWait());
//        c3p0.setCheckoutTimeout(datasource.getPoolProperties().getMaxWait());
//        c3p0.setDebugUnreturnedConnectionStackTraces(datasource.getPoolProperties().isLogAbandoned());
//        c3p0.setIdleConnectionTestPeriod(datasource.getPoolProperties().getTimeBetweenEvictionRunsMillis()/1000);
//        c3p0.setInitialPoolSize(datasource.getPoolProperties().getInitialSize());
//        c3p0.setMaxIdleTime(datasource.getPoolProperties().getMinEvictableIdleTimeMillis()/1000);
//        c3p0.setMaxIdleTimeExcessConnections(datasource.getPoolProperties().getMaxIdle());
//        c3p0.setMaxPoolSize(datasource.getPoolProperties().getMaxActive());
//        c3p0.setMinPoolSize(datasource.getPoolProperties().getMinIdle());
//        c3p0.setPassword(datasource.getPoolProperties().getPassword());
//        c3p0.setPreferredTestQuery(datasource.getPoolProperties().getValidationQuery());
//        c3p0.setTestConnectionOnCheckin(datasource.getPoolProperties().isTestOnReturn());
//        c3p0.setTestConnectionOnCheckout(datasource.getPoolProperties().isTestOnBorrow());
//        c3p0.setUnreturnedConnectionTimeout(datasource.getPoolProperties().getRemoveAbandonedTimeout());
//        c3p0.setUser(datasource.getPoolProperties().getUsername());
//        c3p0.setUsesTraditionalReflectiveProxies(true);
//        c3p0.setJdbcUrl(datasource.getPoolProperties().getUrl());
//        c3p0.setDriverClass(datasource.getPoolProperties().getDriverClassName());
//        this.c3p0Datasource = c3p0;

      /**
        acquireIncrement
        acquireRetryAttempts
        acquireRetryDelay
        autoCommitOnClose
        automaticTestTable
        breakAfterAcquireFailure
        checkoutTimeout
        connectionCustomizerClassName
        connectionTesterClassName
        debugUnreturnedConnectionStackTraces
        factoryClassLocation
        forceIgnoreUnresolvedTransactions
        idleConnectionTestPeriod
        initialPoolSize
        maxAdministrativeTaskTime
        maxConnectionAge
        maxIdleTime
        maxIdleTimeExcessConnections
        maxPoolSize
        maxStatements
        maxStatementsPerConnection
        minPoolSize
        numHelperThreads
        overrideDefaultUser
        overrideDefaultPassword
        password
        preferredTestQuery
        propertyCycle
        testConnectionOnCheckin
        testConnectionOnCheckout
        unreturnedConnectionTimeout
        user
        usesTraditionalReflectiveProxies
        */
    }

    @After
    public void tearDown() throws Exception {
        try {
            datasource.close();
        } catch (Exception ignore){
            // Ignore
        }
        try {
            tDatasource.close();
        } catch (Exception ignore){
            // Ignore
        }
        //try {((ComboPooledDataSource)c3p0Datasource).close(true);}catch(Exception ignore){}
        datasource = null;
        tDatasource = null;
        //c3p0Datasource = null;
        System.gc();
        org.apache.tomcat.jdbc.test.driver.Driver.reset();
    }

    private static final String PROP_DEFAULTAUTOCOMMIT = "defaultAutoCommit";
    private static final String PROP_DEFAULTREADONLY = "defaultReadOnly";
    private static final String PROP_DEFAULTTRANSACTIONISOLATION = "defaultTransactionIsolation";
    private static final String PROP_DEFAULTCATALOG = "defaultCatalog";
    private static final String PROP_DRIVERCLASSNAME = "driverClassName";
    private static final String PROP_MAXACTIVE = "maxActive";
    private static final String PROP_MAXIDLE = "maxIdle";
    private static final String PROP_MINIDLE = "minIdle";
    private static final String PROP_INITIALSIZE = "initialSize";
    private static final String PROP_MAXWAIT = "maxWait";
    private static final String PROP_TESTONBORROW = "testOnBorrow";
    private static final String PROP_TESTONRETURN = "testOnReturn";
    private static final String PROP_TIMEBETWEENEVICTIONRUNSMILLIS = "timeBetweenEvictionRunsMillis";
    private static final String PROP_NUMTESTSPEREVICTIONRUN = "numTestsPerEvictionRun";
    private static final String PROP_MINEVICTABLEIDLETIMEMILLIS = "minEvictableIdleTimeMillis";
    private static final String PROP_TESTWHILEIDLE = "testWhileIdle";
    private static final String PROP_PASSWORD = "password";
    private static final String PROP_URL = "url";
    private static final String PROP_USERNAME = "username";
    private static final String PROP_VALIDATIONQUERY = "validationQuery";
    private static final String PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED = "accessToUnderlyingConnectionAllowed";
    private static final String PROP_REMOVEABANDONED = "removeAbandoned";
    private static final String PROP_REMOVEABANDONEDTIMEOUT = "removeAbandonedTimeout";
    private static final String PROP_LOGABANDONED = "logAbandoned";
    private static final String PROP_POOLPREPAREDSTATEMENTS = "poolPreparedStatements";
    private static final String PROP_MAXOPENPREPAREDSTATEMENTS = "maxOpenPreparedStatements";
    private static final String PROP_CONNECTIONPROPERTIES = "connectionProperties";

    private static final String[] ALL_PROPERTIES = {
        PROP_DEFAULTAUTOCOMMIT,
        PROP_DEFAULTREADONLY,
        PROP_DEFAULTTRANSACTIONISOLATION,
        PROP_DEFAULTCATALOG,
        PROP_DRIVERCLASSNAME,
        PROP_MAXACTIVE,
        PROP_MAXIDLE,
        PROP_MINIDLE,
        PROP_INITIALSIZE,
        PROP_MAXWAIT,
        PROP_TESTONBORROW,
        PROP_TESTONRETURN,
        PROP_TIMEBETWEENEVICTIONRUNSMILLIS,
        PROP_NUMTESTSPEREVICTIONRUN,
        PROP_MINEVICTABLEIDLETIMEMILLIS,
        PROP_TESTWHILEIDLE,
        PROP_PASSWORD,
        PROP_URL,
        PROP_USERNAME,
        PROP_VALIDATIONQUERY,
        PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED,
        PROP_REMOVEABANDONED,
        PROP_REMOVEABANDONEDTIMEOUT,
        PROP_LOGABANDONED,
        PROP_POOLPREPAREDSTATEMENTS,
        PROP_MAXOPENPREPAREDSTATEMENTS,
        PROP_CONNECTIONPROPERTIES
    };

    private static final Map<String,String> RENAMED = new HashMap<>();

    static {
        RENAMED.put(PROP_MAXACTIVE, "maxTotal");
    }
}

redpajama_set_name: RedPajamaGithub


text:
project_path: /web/_project.yaml
book_path: /web/ilt/pwa/_book.yaml

{# wf_updated_on: 2017-04-14 #}
{# wf_published_on: 2017-04-14 #}

# Responsive Design {: .page-title }

Users interact with the web using an increasingly diverse range of devices.
These devices all have different viewport sizes, pixel widths and densities,
scroll and zoom capabilities, etc. This video describes responsive-design
techniques that help you create web apps that work well on any device.

{% setvar videoId "T-hVjfc7E-c" %}
{% setvar slidesId "1uG20FaNBMQGNjMZGN1SelJ05HVBm5u6fRSCj5ldFftg" %}

{% include "web/ilt/pwa/_slides.html" %}


text:
#ifndef __MSDP2XXX_H___
#define __MSDP2XXX_H___

#include "msdp2xxx_base.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * SDP device structure.
 */
typedef struct {
        /** Address of device (1-31). */
        unsigned char addr;
        /** SDP device input file handler. */
        SDP_F f_in;
        /** SDP device output file handler, normaly f_in == f_out. */
        SDP_F f_out;
} sdp_t;

/* High leve operation functions */
#ifdef _WIN32
int sdp_open(sdp_t *sdp, const wchar_t *fname, int addr);
#else
int sdp_open(sdp_t *sdp, const char *fname, int addr);
#endif
int sdp_openf(sdp_t *sdp, SDP_F f, int addr);
void sdp_close(sdp_t *sdp);

int sdp_get_dev_addr(const sdp_t *sdp);
int sdp_get_va_maximums(const sdp_t *sdp, sdp_va_t *va_maximums);
int sdp_get_volt_limit(const sdp_t *sdp, double *volt);
int sdp_get_va_data(const sdp_t *sdp, sdp_va_data_t *va_data);
int sdp_get_va_setpoint(const sdp_t *sdp, sdp_va_t *va_setpoints);
int sdp_get_preset(const sdp_t *sdp, int presn, sdp_va_t *va_preset);
int sdp_get_program(const sdp_t *sdp, int progn, sdp_program_t *program);
int sdp_get_lcd_info(const sdp_t *sdp, sdp_lcd_info_t *lcd_info);
int sdp_remote(const sdp_t *sdp, int enable);
int sdp_run_preset(const sdp_t *sdp, int preset);
int sdp_run_program(const sdp_t *sdp, int count);
int sdp_select_ifce(const sdp_t *sdp, sdp_ifce_t ifce);
int sdp_set_curr(const sdp_t *sdp, double curr);
int sdp_set_volt(const sdp_t *sdp, double volt);
int sdp_set_volt_limit(const sdp_t *sdp, double volt);
int sdp_set_output(const sdp_t *sdp, int enable);
int sdp_set_poweron_output(const sdp_t *sdp, int presn, int enable);
int sdp_set_preset(const sdp_t *sdp, int presn, const sdp_va_t *va_preset);
int sdp_set_program(const sdp_t *sdp, int progn, const sdp_program_t *program);
int sdp_stop(const sdp_t *sdp);

#ifdef __cplusplus
} // extern "C"
#endif

#endif


text:
using System;
using System.Collections.Generic;
using System.Text;

namespace Avalonia.Data.Core
{
    public class TypeCastNode : ExpressionNode
    {
        public override string Description => $"as {TargetType.FullName}";

        public Type TargetType { get; }

        public TypeCastNode(Type type)
        {
            TargetType = type;
        }

        protected virtual object Cast(object value)
        {
            return TargetType.IsInstanceOfType(value) ? value : null;
        }

        protected override void StartListeningCore(WeakReference<object> reference)
        {
            if (reference.TryGetTarget(out object target))
            {
                target = Cast(target);
                reference = target == null ? NullReference : new WeakReference<object>(target);
            }

            base.StartListeningCore(reference);
        }
    }
}


text:
import { DataType } from 'breeze-client';

import { nameof } from '../../utilities';
import { BaseDataTypeSetup } from './base-datatype-setup';

/**
 * @classdesc Sets up the breeze DataType.DateTime enum symbol.
 * @see {DataType.DateTime}
 */
export class DateTimeDataTypeSetup extends BaseDataTypeSetup {
    public name = nameof<DataType>('DateTime');

    public fmtOData = (val: any) => {
        if (!val) {
            return null;
        }

        try {
            return val.toISOString();
        } catch (e) {
            this.handleInvalidValue(val);
        }
    }
}


text:
<?php
// This script was created for demonstrating remote querying for the first combobox example
// in examples/form/combos.html. It doesn't take into account start or limit or any other
// querystring param, but it could be easily extended to do so.

$states = array(
    "Alabama" => array("AL", "Alabama", "The Heart of Dixie"),
    "Alaska" => array("AK", "Alaska", "The Land of the Midnight Sun"),
    "Arkansas" => array("AR", "Arkansas", "The Natural State"),
    "Arizona" => array("AZ", "Arizona", "The Grand Canyon State"),
    "California" => array("CA", "California", "The Golden State"),
    "Colorado" => array("CO", "Colorado", "The Mountain State"),
    "Connecticut" => array("CT", "Connecticut", "The Constitution State"),
    "Delaware" => array("DE", "Delaware", "The First State"),
    "Florida" => array("FL", "Florida", "The Sunshine State"),
    "Georgia" => array("GA", "Georgia", "The Peach State"),
    "Hawaii" => array("HI", "Hawaii", "The Aloha State"),
    "Idaho" => array("ID", "Idaho", "Famous Potatoes"),
    "Illinois" => array("IL", "Illinois", "The Prairie State"),
    "Indiana" => array("IN", "Indiana", "The Hospitality State"),
    "Iowa" => array("IA", "Iowa", "The Corn State"),
    "Kansas" => array("KS", "Kansas", "The Sunflower State"),
    "Kentucky" => array("KY", "Kentucky", "The Bluegrass State"),
    "Louisiana" => array("LA", "Louisiana", "The Bayou State"),
    "Maine" => array("ME", "Maine", "The Pine Tree State"),
    "Maryland" => array("MD", "Maryland", "Chesapeake State"),
    "Massachusetts" => array("MA", "Massachusetts", "The Spirit of America"),
    "Michigan" => array("MI", "Michigan", "Great Lakes State"),
    "Minnesota" => array("MN", "Minnesota", "North Star State"),
    "Mississippi" => array("MS", "Mississippi", "Magnolia State"),
    "Missouri" => array("MO", "Missouri", "Show Me State"),
    "Montana" => array("MT", "Montana", "Big Sky Country"),
    "Nebraska" => array("NE", "Nebraska", "Beef State"),
    "Nevada" => array("NV", "Nevada", "Silver State"),
    "New Hampshire" => array("NH", "New Hampshire", "Granite State"),
    "New Jersey" => array("NJ", "New Jersey", "Garden State"),
    "New Mexico" => array("NM", "New Mexico", "Land of Enchantment"),
    "New York" => array("NY", "New York", "Empire State"),
    "North Carolina" => array("NC", "North Carolina", "First in Freedom"),
    "North Dakota" => array("ND", "North Dakota", "Peace Garden State"),
    "Ohio" => array("OH", "Ohio", "The Heart of it All"),
    "Oklahoma" => array("OK", "Oklahoma", "Oklahoma is OK"),
    "Oregon" => array("OR", "Oregon", "Pacific Wonderland"),
    "Pennsylvania" => array("PA", "Pennsylvania", "Keystone State"),
    "Rhode Island" => array("RI", "Rhode Island", "Ocean State"),
    "South Carolina" => array("SC", "South Carolina", "Nothing Could be Finer"),
    "South Dakota" => array("SD", "South Dakota", "Great Faces, Great Places"),
    "Tennessee" => array("TN", "Tennessee", "Volunteer State"),
    "Texas" => array("TX", "Texas", "Lone Star State"),
    "Utah" => array("UT", "Utah", "Salt Lake State"),
    "Vermont" => array("VT", "Vermont", "Green Mountain State"),
    "Virginia" => array("VA", "Virginia", "Mother of States"),
    "Washington" => array("WA", "Washington", "Green Tree State"),
    "West Virginia" => array("WV", "West Virginia", "Mountain State"),
    "Wisconsin" => array("WI", "Wisconsin", "America's Dairyland")
);

$query = '/^' . $_GET['q'] . '/i';
$found = array();

function filter_states($val, $i) {
    if (preg_match($GLOBALS['query'], $i)) {
        array_push($GLOBALS['found'], $GLOBALS['states'][$i]);
    }
}

array_walk($states, "filter_states");

echo json_encode(array(
    "total" => count($found),
    "data" => $found
));

?>


text:
package amitkma.stitchlib.executors;

import java.util.concurrent.Callable;

/**
 * Create by Amit Kumar on 22/5/17
 * Email : mr.doc10jl96@gmail.com
 * Company : Dot Wave Ltd.
 */

public class StitchCallable<T> implements Callable<T> {

    private final Callable<T> mCallable;

    public StitchCallable(Callable<T> callable) {
        this.mCallable = callable;
    }

    @Override
    public T call() throws Exception {
        return mCallable.call();
    }
}


text:
<?php
/**
 * Message translations.
 *
 * This file is automatically generated by 'yii message' command.
 * It contains the localizable messages extracted from source code.
 * You may modify this file by translating the extracted messages.
 *
 * Each array element represents the translation (value) of a message (key).
 * If the value is empty, the message is considered as not translated.
 * Messages that no longer need translation will have their translations
 * enclosed between a pair of '@@' marks.
 *
 * Message string can be used with plural forms format. Check i18n section
 * of the guide for details.
 *
 * NOTE: this file must be saved in UTF-8 encoding.
 */
return [
    'ID' => 'ID',
    'Content' => 'Contenido',
    'Entity' => 'Entidad',
    'Entity ID' => 'ID Entidad',
    'Parent ID' => 'Parent ID',
    'Status' => 'Estado',
    'Level' => 'Nivel',
    'Created by' => 'Creado por',
    'Updated by' => 'Actualizado por',
    'Related to' => 'Relacionado con',
    'Url' => 'Url',
    'Created date' => 'Created date',
    'Updated date' => 'Updated date',
    'View' => 'View',
    'Update' => 'Actualizar',
    'Delete' => 'Borrar',
    'Reply' => 'Reply',
    'Comments ({0})' => 'Comentarios ({0})',
    'Comment cannot be blank.' => 'El comentario no puede estar vacio.',
    'Comment has not been deleted. Please try again!' => 'El comentario no ha sido borrado. ¡Intentelo de nuevo!',
    'Add a comment...' => 'Añade un comentario...',
    'Comment' => 'Comenta',
    'Oops, something went wrong. Please try again later.' => 'Oops, algo fue mal. Por favor intentelo de nuevo mas tarde.',
    'The requested page does not exist.' => 'The requested page does not exist.',
    'Comment has been deleted.' => 'El comentario ha sido eliminado.',
    'Comment has been saved.' => 'El comentario ha sido guardado.',
    'Click here to cancel reply.' => 'Pulsa aqui para cancelar la respuesta.',
    'Comments Management' => 'Comments Management',
    'Select Status' => 'Select Status',
    'Select Author' => 'Select Author',
    'Update Comment: {0}' => 'Actualizar Comentario: {0}',
    'Active' => 'Activo',
    'Deleted' => 'Borrado',
    'Go Back' => 'Vuelve atrás',
];


text:
package org.openengsb.config.view;

import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.model.Model;

public class EditContextPage extends BasePage {
    private final Model<String> contextModel;

    @SuppressWarnings("serial")
    public EditContextPage() {
        Form<?> form = new Form<Object>("form") {
            @Override
            public void onSubmit() {
                EditContextPage.this.onSubmit();
            }
        };
        add(form);

        contextModel = new Model<String>(contextService.getContext());
        TextArea<String> area = new TextArea<String>("area", contextModel);
        form.add(area);
    }

    protected void onSubmit() {
        contextService.updateContext(contextModel.getObject());
    }
}


text:
package tls

import (
	"crypto/tls"
	"crypto/x509"
	"net"
	"strings"
	"testing"

	mynet "github.com/Symantec/Dominator/lib/net"
)

var (
	serverAddress   string
	tlsCertificate  tls.Certificate
	x509Certificate *x509.Certificate
)

func init() {
	var err error
	tlsCertificate, x509Certificate, err = NewTestCertificate()
	if err != nil {
		panic(err)
	}
	config := &tls.Config{Certificates: []tls.Certificate{tlsCertificate}}
	listener, err := tls.Listen("tcp", "localhost:", config)
	if err != nil {
		panic(err)
	}
	serverAddress = listener.Addr().String()
	go func() {
		for {
			accept(listener)
		}
	}()
}

func accept(listener net.Listener) {
	conn, err := listener.Accept()
	if err != nil {
		return
	}
	defer conn.Close()
	conn.(*tls.Conn).Handshake()
}

func TestDialSkipVerify(t *testing.T) {
	dialer := NewDialer(nil, &tls.Config{InsecureSkipVerify: true})
	if conn, err := dialer.Dial("tcp", serverAddress); err != nil {
		t.Fatal(err)
	} else {
		conn.Close()
	}
}

func TestDialNoConfig(t *testing.T) {
	dialer := NewDialer(nil, nil)
	if conn, err := dialer.Dial("tcp", serverAddress); err != nil {
		if strings.Contains(err.Error(),
			"certificate signed by unknown authority") {
			return
		}
		t.Fatal(err)
	} else {
		conn.Close()
		t.Fatal("Dial with nil config did not fail")
	}
}

func TestDialConfig(t *testing.T) {
	caCertPool := x509.NewCertPool()
	caCertPool.AddCert(x509Certificate)
	dialer := NewDialer(nil, &tls.Config{RootCAs: caCertPool})
	if conn, err := dialer.Dial("tcp", serverAddress); err != nil {
		t.Fatal(err)
	} else {
		conn.Close()
	}
}

func TestDialSkipVerifyMeasuringDialer(t *testing.T) {
	dialer := NewDialer(mynet.NewMeasuringDialer(&net.Dialer{}),
		&tls.Config{InsecureSkipVerify: true})
	if conn, err := dialer.Dial("tcp", serverAddress); err != nil {
		t.Fatal(err)
	} else {
		conn.Close()
	}
}


text:
using namespace llvm;

#define DEBUG_TYPE "bpf-mi-checking"

namespace {

struct BPFMIPreEmitChecking : public MachineFunctionPass {

  static char ID;
  MachineFunction *MF;
  const TargetRegisterInfo *TRI;

  BPFMIPreEmitChecking() : MachineFunctionPass(ID) {
    initializeBPFMIPreEmitCheckingPass(*PassRegistry::getPassRegistry());
  }

private:
  // Initialize class variables.
  void initialize(MachineFunction &MFParm);

  void checkingIllegalXADD(void);

public:

  // Main entry point for this pass.
  bool runOnMachineFunction(MachineFunction &MF) override {
    if (!skipFunction(MF.getFunction())) {
      initialize(MF);
      checkingIllegalXADD();
    }
    return false;
  }
};

// Initialize class variables.
void BPFMIPreEmitChecking::initialize(MachineFunction &MFParm) {
  MF = &MFParm;
  TRI = MF->getSubtarget<BPFSubtarget>().getRegisterInfo();
  LLVM_DEBUG(dbgs() << "*** BPF PreEmit checking pass ***\n\n");
}

// Make sure all Defs of XADD are dead, meaning any result of XADD insn is not
// used.
//
// NOTE: BPF backend hasn't enabled sub-register liveness track, so when the
// source and destination operands of XADD are GPR32, there is no sub-register
// dead info. If we rely on the generic MachineInstr::allDefsAreDead, then we
// will raise false alarm on GPR32 Def.
//
// To support GPR32 Def, ideally we could just enable sub-registr liveness track
// on BPF backend, then allDefsAreDead could work on GPR32 Def. This requires
// implementing TargetSubtargetInfo::enableSubRegLiveness on BPF.
//
// However, sub-register liveness tracking module inside LLVM is actually
// designed for the situation where one register could be split into more than
// one sub-registers for which case each sub-register could have their own
// liveness and kill one of them doesn't kill others. So, tracking liveness for
// each make sense.
//
// For BPF, each 64-bit register could only have one 32-bit sub-register. This
// is exactly the case which LLVM think brings no benefits for doing
// sub-register tracking, because the live range of sub-register must always
// equal to its parent register, therefore liveness tracking is disabled even
// the back-end has implemented enableSubRegLiveness. The detailed information
// is at r232695:
//
//   Author: Matthias Braun <matze@braunis.de>
//   Date:   Thu Mar 19 00:21:58 2015 +0000
//   Do not track subregister liveness when it brings no benefits
//
// Hence, for BPF, we enhance MachineInstr::allDefsAreDead. Given the solo
// sub-register always has the same liveness as its parent register, LLVM is
// already attaching a implicit 64-bit register Def whenever the there is
// a sub-register Def. The liveness of the implicit 64-bit Def is available.
// For example, for "lock *(u32 *)(r0 + 4) += w9", the MachineOperand info could
// be:
//
//   $w9 = XADDW32 killed $r0, 4, $w9(tied-def 0),
//                        implicit killed $r9, implicit-def dead $r9
//
// Even though w9 is not marked as Dead, the parent register r9 is marked as
// Dead correctly, and it is safe to use such information or our purpose.
static bool hasLiveDefs(const MachineInstr &MI, const TargetRegisterInfo *TRI) {
  const MCRegisterClass *GPR64RegClass =
    &BPFMCRegisterClasses[BPF::GPRRegClassID];
  std::vector<unsigned> GPR32LiveDefs;
  std::vector<unsigned> GPR64DeadDefs;

  for (const MachineOperand &MO : MI.operands()) {
    bool RegIsGPR64;

    if (!MO.isReg() || MO.isUse())
      continue;

    RegIsGPR64 = GPR64RegClass->contains(MO.getReg());
    if (!MO.isDead()) {
      // It is a GPR64 live Def, we are sure it is live. */
      if (RegIsGPR64)
        return true;
      // It is a GPR32 live Def, we are unsure whether it is really dead due to
      // no sub-register liveness tracking. Push it to vector for deferred
      // check.
      GPR32LiveDefs.push_back(MO.getReg());
      continue;
    }

    // Record any GPR64 dead Def as some unmarked GPR32 could be alias of its
    // low 32-bit.
    if (RegIsGPR64)
      GPR64DeadDefs.push_back(MO.getReg());
  }

  // No GPR32 live Def, safe to return false.
  if (GPR32LiveDefs.empty())
    return false;

  // No GPR64 dead Def, so all those GPR32 live Def can't have alias, therefore
  // must be truely live, safe to return true.
  if (GPR64DeadDefs.empty())
    return true;

  // Otherwise, return true if any aliased SuperReg of GPR32 is not dead.
  std::vector<unsigned>::iterator search_begin = GPR64DeadDefs.begin();
  std::vector<unsigned>::iterator search_end = GPR64DeadDefs.end();
  for (auto I : GPR32LiveDefs)
    for (MCSuperRegIterator SR(I, TRI); SR.isValid(); ++SR)
       if (std::find(search_begin, search_end, *SR) == search_end)
         return true;

  return false;
}

void BPFMIPreEmitChecking::checkingIllegalXADD(void) {
  for (MachineBasicBlock &MBB : *MF) {
    for (MachineInstr &MI : MBB) {
      if (MI.getOpcode() != BPF::XADDW &&
          MI.getOpcode() != BPF::XADDD &&
          MI.getOpcode() != BPF::XADDW32)
        continue;

      LLVM_DEBUG(MI.dump());
      if (hasLiveDefs(MI, TRI)) {
        DebugLoc Empty;
        const DebugLoc &DL = MI.getDebugLoc();
        if (DL != Empty)
          report_fatal_error("line " + std::to_string(DL.getLine()) +
                             ": Invalid usage of the XADD return value", false);
        else
          report_fatal_error("Invalid usage of the XADD return value", false);
      }
    }
  }

  return;
}

} // end default namespace

INITIALIZE_PASS(BPFMIPreEmitChecking, "bpf-mi-pemit-checking",
                "BPF PreEmit Checking", false, false)

char BPFMIPreEmitChecking::ID = 0;
FunctionPass* llvm::createBPFMIPreEmitCheckingPass()
{
  return new BPFMIPreEmitChecking();
}


text:
package hcsoci

import (
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"

	specs "github.com/opencontainers/runtime-spec/specs-go"
	"github.com/pkg/errors"

	"github.com/Microsoft/hcsshim/internal/devices"
	"github.com/Microsoft/hcsshim/internal/guestpath"
	hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
	"github.com/Microsoft/hcsshim/internal/log"
	"github.com/Microsoft/hcsshim/internal/oci"
	"github.com/Microsoft/hcsshim/internal/resources"
	"github.com/Microsoft/hcsshim/internal/uvm"
	"github.com/Microsoft/hcsshim/osversion"
	"github.com/Microsoft/hcsshim/pkg/annotations"
)

const deviceUtilExeName = "device-util.exe"

// getSpecKernelDrivers gets any device drivers specified on the spec.
// Drivers are optional, therefore do not return an error if none are on the spec.
func getSpecKernelDrivers(annots map[string]string) ([]string, error) {
	drivers := oci.ParseAnnotationCommaSeparated(annotations.VirtualMachineKernelDrivers, annots)
	for _, driver := range drivers {
		if _, err := os.Stat(driver); err != nil {
			return nil, errors.Wrapf(err, "failed to find path to drivers at %s", driver)
		}
	}
	return drivers, nil
}

// getDeviceExtensionPaths gets any device extensions paths specified on the spec.
// device extensions are optional, therefore if none are on the spec, do not return an error.
func getDeviceExtensionPaths(annots map[string]string) ([]string, error) {
	extensions := oci.ParseAnnotationCommaSeparated(annotations.DeviceExtensions, annots)
	for _, ext := range extensions {
		if _, err := os.Stat(ext); err != nil {
			return nil, errors.Wrapf(err, "failed to find path to driver extensions at %s", ext)
		}
	}
	return extensions, nil
}

// getGPUVHDPath gets the gpu vhd path from the shim options or uses the default if no
// shim option is set. Right now we only support Nvidia gpus, so this will default to
// a gpu vhd with nvidia files
func getGPUVHDPath(annot map[string]string) (string, error) {
	gpuVHDPath, ok := annot[annotations.GPUVHDPath]
	if !ok || gpuVHDPath == "" {
		return "", errors.New("no gpu vhd specified")
	}
	if _, err := os.Stat(gpuVHDPath); err != nil {
		return "", errors.Wrapf(err, "failed to find gpu support vhd %s", gpuVHDPath)
	}
	return gpuVHDPath, nil
}

// getDeviceUtilHostPath is a simple helper function to find the host path of the device-util tool
func getDeviceUtilHostPath() string {
	return filepath.Join(filepath.Dir(os.Args[0]), deviceUtilExeName)
}

func isDeviceExtensionsSupported() bool {
	// device extensions support was added from 20348 onwards.
	return osversion.Build() >= 20348
}

// getDeviceExtensions is a helper function to read the files at `extensionPaths` and unmarshal the contents
// into a `hcsshema.DeviceExtension` to be added to a container's hcs create document.
func getDeviceExtensions(annotations map[string]string) (*hcsschema.ContainerDefinitionDevice, error) {
	extensionPaths, err := getDeviceExtensionPaths(annotations)
	if err != nil {
		return nil, err
	}

	if len(extensionPaths) == 0 {
		return nil, nil
	}

	if !isDeviceExtensionsSupported() {
		return nil, fmt.Errorf("device extensions are not supported on this build (%d)", osversion.Build())
	}

	results := &hcsschema.ContainerDefinitionDevice{
		DeviceExtension: []hcsschema.DeviceExtension{},
	}
	for _, extensionPath := range extensionPaths {
		data, err := ioutil.ReadFile(extensionPath)
		if err != nil {
			return nil, errors.Wrapf(err, "failed to read extension file at %s", extensionPath)
		}
		extension := hcsschema.DeviceExtension{}
		if err := json.Unmarshal(data, &extension); err != nil {
			return nil, errors.Wrapf(err, "failed to unmarshal extension file at %s", extensionPath)
		}
		results.DeviceExtension = append(results.DeviceExtension, extension)
	}
	return results, nil
}

// handleAssignedDevicesWindows does all of the work to setup the hosting UVM, assign in devices
// specified on the spec, and install any necessary, specified kernel drivers into the UVM.
//
// Drivers must be installed after the target devices are assigned into the UVM.
// This ordering allows us to guarantee that driver installation on a device in the UVM is completed
// before we attempt to create a container.
func handleAssignedDevicesWindows(
	ctx context.Context,
	vm *uvm.UtilityVM,
	annotations map[string]string,
	specDevs []specs.WindowsDevice) (resultDevs []specs.WindowsDevice, closers []resources.ResourceCloser, err error) {
	defer func() {
		if err != nil {
			// best effort clean up allocated resources on failure
			for _, r := range closers {
				if releaseErr := r.Release(ctx); releaseErr != nil {
					log.G(ctx).WithError(releaseErr).Error("failed to release container resource")
				}
			}
			closers = nil
			resultDevs = nil
		}
	}()

	// install the device util tool in the UVM
	toolHostPath := getDeviceUtilHostPath()
	options := vm.DefaultVSMBOptions(true)
	toolsShare, err := vm.AddVSMB(ctx, toolHostPath, options)
	if err != nil {
		return nil, closers, fmt.Errorf("failed to add VSMB share to utility VM for path %+v: %s", toolHostPath, err)
	}
	closers = append(closers, toolsShare)
	deviceUtilPath, err := vm.GetVSMBUvmPath(ctx, toolHostPath, true)
	if err != nil {
		return nil, closers, err
	}

	// assign device into UVM and create corresponding spec windows devices
	for _, d := range specDevs {
		pciID, index := getDeviceInfoFromPath(d.ID)
		vpciCloser, locationPaths, err := devices.AddDevice(ctx, vm, d.IDType, pciID, index, deviceUtilPath)
		if err != nil {
			return nil, nil, err
		}
		closers = append(closers, vpciCloser)
		for _, value := range locationPaths {
			specDev := specs.WindowsDevice{
				ID:     value,
				IDType: uvm.VPCILocationPathIDType,
			}
			log.G(ctx).WithField("parsed devices", specDev).Info("added windows device to spec")
			resultDevs = append(resultDevs, specDev)
		}
	}

	return resultDevs, closers, nil
}

// handleAssignedDevicesLCOW does all of the work to setup the hosting UVM, assign in devices
// specified on the spec
//
// For LCOW, drivers must be installed before the target devices are assigned into the UVM so they
// can be linked on arrival.
func handleAssignedDevicesLCOW(
	ctx context.Context,
	vm *uvm.UtilityVM,
	annotations map[string]string,
	specDevs []specs.WindowsDevice) (resultDevs []specs.WindowsDevice, closers []resources.ResourceCloser, err error) {
	defer func() {
		if err != nil {
			// best effort clean up allocated resources on failure
			for _, r := range closers {
				if releaseErr := r.Release(ctx); releaseErr != nil {
					log.G(ctx).WithError(releaseErr).Error("failed to release container resource")
				}
			}
			closers = nil
			resultDevs = nil
		}
	}()

	gpuPresent := false

	// assign device into UVM and create corresponding spec windows devices
	for _, d := range specDevs {
		switch d.IDType {
		case uvm.VPCIDeviceIDType, uvm.VPCIDeviceIDTypeLegacy, uvm.GPUDeviceIDType:
			gpuPresent = gpuPresent || d.IDType == uvm.GPUDeviceIDType
			pciID, index := getDeviceInfoFromPath(d.ID)
			vpci, err := vm.AssignDevice(ctx, pciID, index, "")
			if err != nil {
				return resultDevs, closers, errors.Wrapf(err, "failed to assign device %s, function %d to pod %s", pciID, index, vm.ID())
			}
			closers = append(closers, vpci)

			// update device ID on the spec to the assigned device's resulting vmbus guid so gcs knows which devices to
			// map into the container
			d.ID = vpci.VMBusGUID
			resultDevs = append(resultDevs, d)
		default:
			return resultDevs, closers, errors.Errorf("specified device %s has unsupported type %s", d.ID, d.IDType)
		}
	}

	if gpuPresent {
		gpuSupportVhdPath, err := getGPUVHDPath(annotations)
		if err != nil {
			return resultDevs, closers, errors.Wrapf(err, "failed to add gpu vhd to %v", vm.ID())
		}
		// use lcowNvidiaMountPath since we only support nvidia gpus right now
		// must use scsi here since DDA'ing a hyper-v pci device is not supported on VMs that have ANY virtual memory
		// gpuvhd must be granted VM Group access.
		options := []string{"ro"}
		scsiMount, err := vm.AddSCSI(
			ctx,
			gpuSupportVhdPath,
			guestpath.LCOWNvidiaMountPath,
			true,
			false,
			options,
			uvm.VMAccessTypeNoop,
		)
		if err != nil {
			return resultDevs, closers, errors.Wrapf(err, "failed to add scsi device %s in the UVM %s at %s", gpuSupportVhdPath, vm.ID(), guestpath.LCOWNvidiaMountPath)
		}
		closers = append(closers, scsiMount)
	}

	return resultDevs, closers, nil
}

func installPodDrivers(ctx context.Context, vm *uvm.UtilityVM, annotations map[string]string) (closers []resources.ResourceCloser, err error) {
	defer func() {
		if err != nil {
			// best effort clean up allocated resources on failure
			for _, r := range closers {
				if releaseErr := r.Release(ctx); releaseErr != nil {
					log.G(ctx).WithError(releaseErr).Error("failed to release container resource")
				}
			}
		}
	}()

	// get the spec specified kernel drivers and install them on the UVM
	drivers, err := getSpecKernelDrivers(annotations)
	if err != nil {
		return closers, err
	}
	for _, d := range drivers {
		driverCloser, err := devices.InstallKernelDriver(ctx, vm, d)
		if err != nil {
			return closers, err
		}
		closers = append(closers, driverCloser)
	}
	return closers, err
}

func getDeviceInfoFromPath(rawDevicePath string) (string, uint16) {
	indexString := filepath.Base(rawDevicePath)
	index, err := strconv.ParseUint(indexString, 10, 16)
	if err == nil {
		// we have a vf index
		return filepath.Dir(rawDevicePath), uint16(index)
	}
	// otherwise, just use default index and full device ID given
	return rawDevicePath, 0
}


text:
buffer<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

    <title>BUbiNG</title>

BUbiNG is a high-speed distributed crawler. BUbiNG agents coordinate autonomously to download data from the web.

Configuring your hardware

BUbiNG requires a number of features from your system.

If you want to run multiple agents, your network must be configured so that communication is possible. The default BUbiNG JGroups
    configuration file (that can be found in BUbiNG's jar under the name <samp>jgroups.xml</samp>) uses multicast over UDP, so you must be sure that a multicast route is set up. Please read the JGroups documentation
    to find how to set up the route and check that it works.

You can specify an alternate JGroups configuration file using the JVM
    property {@value it.unimi.di.law.bubing.Agent#JGROUPS_CONFIGURATION_PROPERTY_NAME}.

Your system must be configured so that a large number of processes and files are allowed. Under linux, we use

	* - nofile 65536
	* - nproc  32768

    as a setup in <samp>limits.d</samp> (or equivalent configuration directory).

A number of system configurations (typically set in <samp>/etc/sysctl.d</samp>, say by creating a file <samp>/etc/sysctl.d/bubing</samp>) must be altered:

# increase TCP max buffer size settable using setsockopt()
net.core.rmem_max = 8388608
net.core.wmem_max = 8388608

# increase conntrack size (or remove iptables modules)
net.netfilter.nf_conntrack_max = 1048576
net.netfilter.nf_conntrack_buckets = 16386

# Wait a maximum of 5 * 2 = 10 seconds in the TIME_WAIT state after a FIN, to handle
# any remaining packets in the network.
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 5
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 5

# No protection from SYN flood attack (to run proxy tests)
net.ipv4.tcp_syncookies = 0

# Disable packet forwarding.
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0

# Increase system file descriptor limit. Generally, set this to 64 * R, where
# R is the amount of RAM in MB your box has (minus a buffer?)
fs.file-max = 262144

# Send the first keepalive time after 60 seconds
net.ipv4.tcp_keepalive_time = 60

# Timeout broken connections faster (amount of time to wait for FIN)
net.ipv4.tcp_fin_timeout = 30

# Let the networking stack reuse TIME_WAIT connections when it thinks it's safe to do so
net.ipv4.tcp_tw_reuse = 1

# Don't Log Spoofed Packets, Source Routed Packets, Redirect Packets
net.ipv4.conf.all.log_martians = 0

# Make more local ports available
net.ipv4.ip_local_port_range = 1024 65000

The above file is sourceable with <samp>sysctl</samp>.

You must be sure that either you are using a resilient DNS server that is going to sustain your request rate, or
    run locally a recursive name server. This is the best practice, because BUbiNG is going to require million of resolutions
    and will cache them internally. Thus, your DNS server can have a quite small cache. Our settings for <samp>bind9</samp> are
    as follows:

	allow-query     { localhost; };
	recursion yes;

	/* These must be coordinated with internal DNSJava settings. */
	max-cache-size 10000;
	max-cache-ttl 3600;
	max-ncache-ttl 60;

Moreover, we run bind with the <samp>-4</samp> option to avoid IPv6 resolution of each host and
    with the <samp>-U 8</samp> option to avoid the constant logging about the maximum number of FD events.

The file system should be set up for performance. If you have an <samp>ext4</samp> partition, we
	suggest to use the tune2fs utility to set the <samp>journal_data_writeback</samp> option, and to mount
	the partition using the options <samp>noatime</samp> and <samp>data=writeback</samp>.

If you intend to access SSL sites with strong security, you must download and install the
	Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files.

To check that your system is properly configured, it is essential that a number of trial runs are performed using the
   {@link it.unimi.di.law.bubing.test.NamedGraphServerHttpProxy} in random mode. For instance,

   java -Xmx4G -server it.unimi.di.law.bubing.test.NamedGraphServerHttpProxy -s 100000000 -d 50 -m 3 -t 1000 -D .0001 -A1000 - &

	will start the proxy using 100 million hosts, average page degree 50, average depth 3, 1000 threads and a 0.01% pages being
	broken (connect or read timeouts). By starting BUbiNG with the configuration option <samp>proxyHost=localhost</samp> (the
	port, 8080, is understood) you can test that your memory and system settings are satisfactory without using any network
	bandwidth.

Configuring BUbiNG

BUbiNG uses a configuration file to set up its internal values. Such values are fully documented
	in {@link it.unimi.di.law.bubing.StartupConfiguration}; the name of the keys are derived by reflection from
	the field names. Default values are annotated using the {@link it.unimi.di.law.bubing.StartupConfiguration.OptionalSpecification}
	annotation in {@link it.unimi.di.law.bubing.StartupConfiguration}. This is an example configuration file:

rootDir=crawl-eu
maxUrlsPerSchemeAuthority=1000
parsingThreads=64
dnsThreads=50
fetchingThreads=512
fetchFilter=true
scheduleFilter=( SchemeEquals(http) or SchemeEquals(https) ) and HostEndsWithOneOf(.ad\,.al\,.at\,.be\,.bg\,.ch\,.cz\,.de\,.dk\,.ee\,.es\,.eu\,.fi\,.fo\,.fr\,.gb\,.gr\,.hr\,.hu\,.ie\,.im\,.is\,.it\,.li\,.lt\,.lu\,.lv\,.mc\,.md\,.me\,.nl\,.no\,.pl\,.pt\,.ro\,.se\,.si\,.sk\,.sm\,.uk\,.va) and not PathEndsWithOneOf(.axd\,.xls\,.rar\,.sflb\,.tmb\,.pdf\,.js\,.swf\,.rss\,.kml\,.m4v\,.tif\,.avi\,.iso\,.mov\,.ppt\,.bib\,.docx\,.css\,.fits\,.png\,.gif\,.jpg\,.jpeg\,.ico\,.doc\,.wmv\,.mp3\,.mp4\,.aac\,.ogg\,.wma\,.gz\,.bz2\,.Z\,.z\,.zip) and URLShorterThan(2048) and DuplicateSegmentsLessThan(3)
followFilter=true
parseFilter=( ContentTypeStartsWith(text/) or PathEndsWithOneOf(.html\,.htm\,.txt) ) and not IsProbablyBinary()
storeFilter=( ContentTypeStartsWith(text/) or PathEndsWithOneOf(.html\,.htm\,.txt) ) and not IsProbablyBinary()
schemeAuthorityDelay=10s
ipDelay=2s
maxUrls=500M
bloomFilterPrecision=1E-8
seed=file:/some/path/eu.seed
socketTimeout=60s
connectionTimeout=60s
fetchDataBufferByteSize=200K
cookiePolicy=compatibility
cookieMaxByteSize=2000
userAgent=BUbiNG (+http://law.di.unimi.it/BUbiNG.html)
userAgentFrom=youremail@yourdomain.com
robotsExpiration=1h
responseBodyMaxByteSize=2M
digestAlgorithm=MurmurHash3
startPaused=false
workbenchMaxByteSize=512Mi
urlCacheMaxByteSize=1Gi
sieveSize=64Mi
parserSpec=HTMLParser(MurmurHash3)
keepAliveTime=1s

Note that almost all these properties are modifiable at runtime using the JMX interface.

There are two main activities related to the preparation of configuration files:

Choosing your filters

Every phase of BUbiNG's activity is controlled by a filter that you can specify using boolean operations
	and atoms from {@link it.unimi.di.law.warc.filters}.

Sizing the various component

BUbiNG will use a constant amount of memory for its activities, except for storing host information, for which it
	assumes to have enough core memory. The shown values are a good choice for a 64 GiB machine.

Starting a crawl

First of all, we suggest to run as root the command <samp>sysctl -p /etc/sysctl.d/bubing</samp> (where the file <samp>bubing</samp> contains the settings discussed before)
	as in our experience some of the parameters turn out to be not correctly set after boot, even in included in <samp>/etc/sysctl.d</samp>.

A BUbiNG is started using the {@link it.unimi.di.law.bubing.Agent} class, as in:

java -server -Xss256K -Xms20G -XX:+UseNUMA -XX:+UseConcMarkSweepGC  \
	-XX:+UseTLAB -XX:+ResizeTLAB -XX:NewRatio=4 -XX:MaxTenuringThreshold=15 -XX:+CMSParallelRemarkEnabled \
	-verbose:gc -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution \
	-XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime \
	-XX:+PrintSafepointStatistics -XX:PrintSafepointStatisticsCount=1 \
	-Djava.rmi.server.hostname=192.168.0.20 \
	-Djava.net.preferIPv4Stack=true \
	-Djgroups.bind_addr=192.168.0.20 \
	-Dlogback.configurationFile=bubing-logback.xml \
	-Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false \
	it.unimi.di.law.bubing.Agent -h 192.168.0.20 -P eu.properties -g eu agent -n 2>err >out

The JVM options are of course just an example for a 64-core, 64 GiB hardware, and should be customized. It is
	important, however, that the thread stack size (<samp>-Xss</samp>) is set to a small value (as BUbiNG uses
	thousands of threads).

The IP address specified will be
	used for JGroups and JMX communication: if you have an internal high-speed interface, this is the place to use it. Otherwise,
	just use the standard IP address of the machine. This crawl will use a property file named <samp>eu.properties</samp>, start an
	agent with name <samp>agent</samp> part of a crawl group named <samp>eu</samp>. Logback
	will be configured by the file bubing-logback.xml (see below).

In the standard BUbiNG setup, agents
	in the same crawl groups coordinates autonomously using consistent hashing, so if you want to perform a multi-agent crawl
	you must just be sure to have properly configured your hardware and JGroups so they work together. A simple way to check
	that this is true is to start the crawl in pause mode, check from the logs that all agents are visible to each other,
	and then start the crawl.

We use Logback for logging. We suggest a separate log for messages above the
	WARN level, to be able to find errors quickly. The file used in the command above could be as follows (assuming you want to write your logs in <samp>/tmp</samp>):

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <appender name="all" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>/tmp/bubing.log</file>
    <encoder>
      <pattern>%d %r %p [%t] %logger{1} - %m%n</pattern>
    </encoder>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <maxHistory>100</maxHistory>
      <FileNamePattern>/tmp/bubing.%d{yyyy-MM-dd_HH}.log</FileNamePattern>
    </rollingPolicy>
  </appender>
  <appender name="warn" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>/tmp/bubing.warn</file>
    <encoder>
      <pattern>%d %r %p [%t] %logger{1} - %m%n</pattern>
    </encoder>
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
      <level>WARN</level>
    </filter>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <maxHistory>100</maxHistory>
      <FileNamePattern>/tmp/bubing.%d.warn</FileNamePattern>
    </rollingPolicy>
  </appender>
  <root level="INFO">
    <appender-ref ref="all"/>
    <appender-ref ref="warn"/>
  </root>
  <logger name="net.htmlparser.jericho" level="OFF"/>
  <logger name="it.unimi.di.law.bubing" level="INFO"/>
  <logger name="it.unimi.di.law.bubing.frontier.FetchingThread$DNSJavaClientConnectionManager" level="INFO"/>
  <logger name="org.apache.http.impl.client" level="WARN"/>
  <logger name="org.apache.http.wire" level="WARN"/>
</configuration>

Tuning the garbage collector

BUbiNG's object handling deeply violates the weak generational hypothesis, that is, the idea that most allocated objects
	die young. During a crawl, dozens (of even hundreds) of millions of small objects have a lifetime of minutes or hours, and then disappear. Using
	the default settings of the garbage collector leads to a constant promotion these objects to the old generation, causing frequent
	full collections that decrease progressively the crawl speed.

The settings suggested above modify radically the garbage collector behavior. One third of the available memory is allocated
	for new objects, and we try to delay tenuring as much as possible by swapping objects
	between the survivor spaces the maximum possible number of times (15, as the counter has only four
	bits). Note that frequent minor collections have little impact
	on the crawler, as even during collections the operating system is filling socket buffers, flushing file buffers, handling memory mapping, etc.
	We also require dynamic thread-local allocation buffers, as the allocation needs of, say, fetching threads and parsing threads are very
	different.

It is always a good idea to log garbage collection information (as suggested above)
	and to examine the resulting log using a tool like
	Chewiebug. Ideally, you should see frequent minor collection, and
	small sets of objects promoted to the old generation.

The actual values of the parameter should be chosen in the following order:

you must decide the amount of heap, which should be as large as possible, considering that you will need
	to leave some memory for caching, memory-mapped files, etc. Running a simulated crawl for a few hundred million pages
	is a good idea, as it is difficult to estimate the actual space occupied by the JVM (e.g., there is a large amount of
	system memory used);

you must decide the ratio between the new and the old generation; in principle, the largest possible
	new generation (<samp>-XX:NewRatio=1</samp>) will give the highest throughput, but if you are low on memory you might
	end up with out-of-memory errors because of a too small old generation.

The last final judge of a correct configuration of the garbage collector is the stability of the crawling speed.

How BUbiNG uses memory

Once you have decided the amount of memory that you want to use for the crawler, you must decide how to divide this
	memory among BUbiNG's components. Most of the memory used by BUbiNG can be divided as follows:

The workbench

The workbench keeps around the URLs (actually, the path+queries) that will be fetched in a short time. Depending on the number of threads, your
	network feed, etc., the workbench must be large enough to keep a few URLs for a number of hosts that is sufficient to saturate your bandwidth.
	We suggest starting with a large value (e.g., a gigabyte), check in the logs which percentage is actually used, and then lower the amount.

The  {@linkplain it.unimi.di.law.bubing.sieve sieve}

The sieve keeps track of which URLs have ever been seen. The default implementation, {@linkplain it.unimi.di.law.bubing.sieve.MercatorSieve}, accumulates
	URLs on disk and associated 64-bit fingerprints in RAM until it is full. Then, it flushes the data and generates a stream of ready URLs. The largest the sieve,
	the less flushes, the less I/O. The {@link it.unimi.di.law.bubing.StartupConfiguration#sieveSize} should be multiplied by 12 to obtain approximately the amount of memory allocated.

The fetching thread cache

Each fetching thread must download data to a cache, whose size is determined by {@link it.unimi.di.law.bubing.StartupConfiguration#fetchDataBufferByteSize}. The cache
	is transparently extended to {@link it.unimi.di.law.bubing.StartupConfiguration#responseBodyMaxByteSize} using a file on disk, but too much disk access will slow
	down the crawler.

The Bloom filter

If you are using near-duplicate detection there is a large amount of memory used by the Bloom filter which keeps track of digests. The
	amount of memory used depends on {@link it.unimi.di.law.bubing.StartupConfiguration#maxUrls} and
	{@link it.unimi.di.law.bubing.StartupConfiguration#bloomFilterPrecision}, and it is explained {@linkplain it.unimi.dsi.util.BloomFilter here}.

The URL cache

The URL cache keeps track of 128-bit MurmurHash3 fingerprints of recently seen URLs; it significantly reduces the number of URLs
	broadcast in a distributed crawl, besides lightening the load on the sieve. Its size
	must be fixed a priori using {@link it.unimi.di.law.bubing.StartupConfiguration#urlCacheMaxByteSize}. Look at the hit/miss ratio in the logs to understand
	whether you have a large enough cache (the bigger, the better).

Data associated to visit states

This is a relatively small amount of data (less than one kilobyte) associated with each host currently visited. It consists in some metadata
	associated with the host, its cookies, and its <samp>robots.txt</samp> exclusion information. The size of the cookies can be controlled using a
	{@link it.unimi.di.law.bubing.StartupConfiguration#cookieMaxByteSize}. This is the only part of the data accumulated by BUbiNG that might, over
	time, grow without bound.

How BUbiNG uses disks

BUbiNG's activity requires a lot of disk I/O. Some of the I/O activity, like the flushes of the {@linkplain it.unimi.di.law.bubing.sieve.MercatorSieve},
	are stop-of-the-world events and require no particular care. However, there are three activities that happen concurrently during the crawling:

Accessing the disk queues

Part of the URLs waiting to be crawled are virtualized—stored on disk. These URLs
	are accessed frequently by memory mapping in a semi-random fashion; they are stored in {@link it.unimi.di.law.bubing.StartupConfiguration#frontierDir}.

Dumping large responses

Only the first {@link it.unimi.di.law.bubing.StartupConfiguration#fetchDataBufferByteSize} bytes of a response are kept in main memory: the remaining
	part, up to  {@link it.unimi.di.law.bubing.StartupConfiguration#responseBodyMaxByteSize} bytes, is dumped on a disk cache. There is one such cache
	per parsing thread, so the disk activity can be quite intensive. The caches are stored in {@link it.unimi.di.law.bubing.StartupConfiguration#responseCacheDir}.

Storing data

If you use a disk-based store, such as the default {@link it.unimi.di.law.bubing.store.WarcStore}, data will be continuously written in {@link it.unimi.di.law.bubing.StartupConfiguration#storeDir}.

Logging

Depending on your Logback configuration, logging can be quite I/O intensive.

Ideally, these four activities should use different disks, and, if possible, {@link it.unimi.di.law.bubing.StartupConfiguration#frontierDir} should
	live on solid-state storage.

Following a crawl

There are two sources of information about the inner works of BUbiNG: JMX and the logs. Most internals of BUbiNG are
    modifiable at runtime using JMX, and looking at the logs reveals a lot information about what's going on. We suggest to
    regularly grep for <samp>ERROR</samp> and check standard error to catch problems at an early stage.

Pausing, suspending or stopping a crawl

If you just want to pause a crawl, there is a JMX {@link it.unimi.di.law.bubing.Agent#pause()} operation that will suspend crawling activity
    until {@link it.unimi.di.law.bubing.Agent#resume()} is invoked. Alternatively, you can
    {@linkplain it.unimi.di.law.bubing.Agent#stop() stop the crawl}, which will cause the crawl state to be snapped to disk.
    At that point, the crawl can restart by launching the agent with the same configuration but without the <samp>-n</samp> option.


text:
h1 {
	text-decoration: overline;
}


text:
package org.mycontroller.standalone.db.migration;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;

import org.mycontroller.standalone.db.DaoUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * @author Jeeva Kandasamy (jkandasa)
 * @since 0.0.3
 */
@Slf4j
public class ClientPostgreSql extends ClientBase implements IMigrationClient {

    public void renameColumn(String tableName, String oldColumnName, String newColumnName) throws SQLException {
        if (hasColumn(tableName, oldColumnName)) {
            int dropCount = DaoUtils.getUserDao().getDao().executeRaw(
                    "ALTER TABLE " + getTableName(tableName) + " RENAME COLUMN "
                            + getColumnName(oldColumnName) + " TO " + getColumnName(newColumnName));
            _logger.debug("Renamed OldColumn:{}, NewColumn:{}, Table:{}, Drop count:{}", oldColumnName, newColumnName,
                    tableName, dropCount);
        } else {
            _logger.warn("Selected column[{}] not found! Table:{}", oldColumnName, tableName);
        }
    }

    public void alterColumn(String tableName, String columnName, String columnDefinition) throws SQLException {
        int alterCount = DaoUtils.getUserDao().getDao().executeRaw("ALTER TABLE "
                + tableName + " ALTER COLUMN " + getColumnName(columnName) + " TYPE " + columnDefinition);
        _logger.debug("Altered column:{}, columnDefinition:{}, table:{}, add count:{}",
                columnName, columnDefinition, tableName, alterCount);
    }

    public void renameTable(String tableName, String newTableName) throws SQLException {
        if (hasTable(tableName)) {
            int changeCount = DaoUtils.getUserDao().getDao().executeRaw(
                    "ALTER TABLE " + getTableName(tableName) + " RENAME TO " + getTableName(newTableName));
            _logger.debug("Renamed table:{}, NewTable:{}, Change count:{}", tableName, newTableName, changeCount);
        } else {
            _logger.warn("Selected table[{}] not found!", tableName);
        }
    }

    public void dropTable(String tableName) throws SQLException {
        if (hasTable(tableName)) {
            int dropCount = DaoUtils.getUserDao().getDao()
                    .executeRaw("DROP TABLE " + getTableName(tableName) + " CASCADE");
            _logger.debug("Dropped table:{}, drop count:{}", tableName, dropCount);
            List<HashMap<String, String>> rows = getRowsByQuery(
                    "SELECT c.relname as seq FROM pg_class c WHERE c.relkind = 'S' and c.relname like '"
                            + tableName + "_%_seq'");
            //Drop sequences
            for (HashMap<String, String> row : rows) {
                if (row.get("seq").matches(tableName + "_[a-z]*?_seq")) {
                    dropCount = DaoUtils.getUserDao().getDao()
                            .executeRaw("DROP SEQUENCE " + row.get("seq") + " CASCADE");
                    _logger.info("Dropped sequence:{}, drop count:{}", row.get("seq"), dropCount);
                } else {
                    _logger.info("Sequence does not matched:{}, table name:{}", row.get("seq"), tableName);
                }
            }
        } else {
            _logger.warn("Selected table[{}] not found!", tableName);
        }
    }

    @Override
    public void renameSequence(String sequenceName, String newSequenceName) throws SQLException {
        int changeCount = DaoUtils.getUserDao().getDao().executeRaw(
                "ALTER SEQUENCE IF EXISTS " + getSequenceName(sequenceName)
                        + " RENAME TO " + getSequenceName(newSequenceName));
        _logger.debug("Renamed sequence from '{}' to '{}', affected count:{}",
                sequenceName, newSequenceName, changeCount);

    }

    @Override
    public void dropSequence(String sequenceName) throws SQLException {
        int dropCount = DaoUtils.getUserDao().getDao()
                .executeRaw("DROP SEQUENCE IF EXISTS " + getSequenceName(sequenceName) + " CASCADE");
        _logger.info("Dropped sequence:{}, drop count:{}", sequenceName, dropCount);
    }

}


text:
/* =======================================================================
 * WeekHistory.js
 * Version: 1.0
 * Date: 2016/02/13
 * By: Rich DeBourke
 * License: MIT
 *
 * https://github.com/RichDeBourke/javascript-binary-data-storage
 * ======================================================================= */

(function (window) {
    "use strict";

    var localStorageData,
        storageName,
        storageRequirement = 544, // Define the required storage when the plugin is first used
        storageBlocks = Math.ceil(storageRequirement / 32),

        getWeeklyHistory = function (localStorageName, optionalStorageRequirement) {
            var historyArray = [],
                tmpData,
                i,
                j;

            storageName = localStorageName;

            if (optionalStorageRequirement) {
                storageRequirement = optionalStorageRequirement;
                storageBlocks = Math.ceil(storageRequirement / 32);
            }

            try {

                localStorageData = JSON.parse(window.localStorage.getItem(storageName));
            }
            catch (err) {
                localStorageData = false;
            }

            if (localStorageData) {
                // convert the data to an array (weeklyHistoryArray) - true for weeks that have already been read
                for (i = 0; i < storageBlocks; i += 1) {
                    tmpData = localStorageData[i];
                    for (j = 0; j < 32; j += 1) {
                        if (tmpData & 0x1) {
                            historyArray.push(true);
                        } else {
                            historyArray.push(false);
                        }
                        tmpData = tmpData >> 1;
                    }
                }
            } else { // if no local storage, LocalStorageData will be null, so create an array of all zero (false) values
                localStorageData = [];
                for (i = 0; i < storageBlocks; i += 1) {
                    localStorageData.push(0x0);
                }
            }

            return historyArray;
        },

        updateWeeklyHistory = function (baseDate, currentDate) {
            // Early versions of Safari need the date in an array format rather than just a string
            function dateStringToArray(dateString) {
                return (dateString.split(/[^0-9]/));
            }

            var baseDateArray = dateStringToArray(baseDate), // Base date for the array - the starting point
                currentDateArray = dateStringToArray(currentDate),
                baseDateObj = new Date(baseDateArray[0], baseDateArray[1] - 1, baseDateArray[2]),
                currentWeekObj = new Date(currentDateArray[0], currentDateArray[1] - 1, currentDateArray[2]),
                weekDelta = Math.round((currentWeekObj - baseDateObj) / (1000 * 60 * 60 * 24 * 7)),
                weekBlock = Math.floor(weekDelta / 32),
                weekOffset = weekDelta % 32,
                success = true;

            localStorageData[weekBlock] = localStorageData[weekBlock] | Math.pow(2, weekOffset);

            try {
                window.localStorage.setItem(storageName, JSON.stringify(localStorageData));
            }
            catch (err) {
                success = false;
            }

            return success;
        },

        clearHistory = function (confirm) {
            if (confirm) {
                if (window.confirm("Do you really want to clear the history?")) {
                    window.localStorage.removeItem(storageName);
                }
            } else {
                window.localStorage.removeItem(storageName);
            }

        };

    // Make the functions accessible from the global scope
    window.getWeeklyHistory = getWeeklyHistory;

    window.updateWeeklyHistory = updateWeeklyHistory;

    window.clearHistory = clearHistory;

}(window));


text:
package org.thymeleaf.spring.view;

import org.springframework.beans.factory.annotation.Autowired;
import org.thymeleaf.spring5.view.ThymeleafView;

public class TestThymeleafView extends ThymeleafView {

    @Autowired
    private ViewBean viewBean;
    private String something;

    public TestThymeleafView() {
        super();
    }

    public ViewBean getViewBean() {
        return viewBean;
    }

    public void setViewBean(final ViewBean viewBean) {
        this.viewBean = viewBean;
    }

    public String getSomething() {
        return something;
    }

    public void setSomething(final String something) {
        this.something = something;
    }

    public static class ViewBean {

        private String value;

        public String getValue() {
            return value;
        }

        public void setValue(final String value) {
            this.value = value;
        }

    }

}