[cvs] expresso commit by lhamel: add function for setting cache
limit as
JCorporate Ltd
jcorp at jcorporate.com
Tue Feb 22 02:13:14 UTC 2005
Log Message:
-----------
add function for setting cache limit as percentage
Modified Files:
--------------
expresso/expresso-web/WEB-INF/src/com/jcorporate/expresso/core/dbobj:
DBObject.java
Revision Data
-------------
Index: DBObject.java
===================================================================
RCS file: /home/javacorp/.cvs/expresso/expresso/expresso-web/WEB-INF/src/com/jcorporate/expresso/core/dbobj/DBObject.java,v
retrieving revision 1.243
retrieving revision 1.244
diff -Lexpresso-web/WEB-INF/src/com/jcorporate/expresso/core/dbobj/DBObject.java -Lexpresso-web/WEB-INF/src/com/jcorporate/expresso/core/dbobj/DBObject.java -u -r1.243 -r1.244
--- expresso-web/WEB-INF/src/com/jcorporate/expresso/core/dbobj/DBObject.java
+++ expresso-web/WEB-INF/src/com/jcorporate/expresso/core/dbobj/DBObject.java
@@ -191,6 +191,12 @@
public static final String WHERE_KEYWORD = " WHERE ";
/**
+ * attribute name
+ */
+ public static final String CACHE_LIMIT_PERCENT = "cacheLimitPercent";
+ public static final String CACHE_LIMIT_TTL = "CACHE_LIMIT_TTL";
+
+ /**
* setup flag name for checking relational integrity;
* set this to false if your DB already checks this, and you want to avoid the performance
* hit associated with checking this in the middleware.
@@ -313,7 +319,7 @@
/**
* Attributes of this DB Object
*/
- private HashMap attributes = null;
+ private Map attributes = null;
/**
* The cache size of this particular DB object
@@ -489,7 +495,7 @@
Object tmpData = null;
int fieldCount = 0;
JDBCObjectMetaData metadata = getJDBCMetaData();
- for (Iterator it = metadata.getFieldListArray().iterator(); it.hasNext();) {
+ for (Iterator it = metadata.getFieldNamesList().iterator(); it.hasNext();) {
oneFieldName = (String) it.next();
try {
@@ -568,7 +574,7 @@
}
protected void updateIsChanged() throws DBException {
- for (Iterator i = getMetaData().getFieldListArray().iterator(); i.hasNext();) {
+ for (Iterator i = getMetaData().getFieldNamesList().iterator(); i.hasNext();) {
String oneFieldName = (String) i.next();
DataField field = getDataField(oneFieldName);
field.cacheIsChangedComparison();
@@ -879,7 +885,7 @@
// special case: if there are no fields besides key
// fields, then do nothing since key fields never update this way
- if (metadata.getKeyFieldListArray().size() == metadata.getFieldListArray().size()) {
+ if (metadata.getKeyFieldListArray().size() == metadata.getFieldNamesList().size()) {
if (log.isDebugEnabled()) {
log.debug("No fields other than keys. Skipping update");
}
@@ -1963,7 +1969,7 @@
//Build an object that we're going to query with.
DBObject testObject = newInstance();
DataObjectMetaData metadata = getMetaData();
- for (Iterator i = getMetaData().getFieldListArray().iterator();
+ for (Iterator i = getMetaData().getFieldNamesList().iterator();
i.hasNext();) {
String fieldName = (String) i.next();
DataFieldMetaData fieldMetadata = metadata.getFieldMetadata(fieldName);
@@ -2325,7 +2331,7 @@
foundKeys = null;
//Pre-allocate to the size of the field list.
- ArrayList retrievedFieldList = new ArrayList(metadata.getFieldListArray().size());
+ ArrayList retrievedFieldList = new ArrayList(metadata.getFieldNamesList().size());
FastStringBuffer myStatement = FastStringBuffer.getInstance();
String sqlStatement = null;
try {
@@ -2773,7 +2779,7 @@
if (distinctFields == null) {
return (String[]) al.toArray();
}
- for (Iterator it = getMetaData().getFieldListArray().iterator(); it.hasNext();) {
+ for (Iterator it = getMetaData().getFieldNamesList().iterator(); it.hasNext();) {
String fieldName = (String) it.next();
if (distinctFields.containsKey(fieldName)) {
@@ -4568,7 +4574,7 @@
throws DBException {
String oneName = null;
- for (Iterator i = getJDBCMetaData().getFieldListArray().iterator(); i.hasNext();) {
+ for (Iterator i = getJDBCMetaData().getFieldNamesList().iterator(); i.hasNext();) {
oneName = (String) i.next();
// only concern ourselves with real fields stored in this object,
@@ -4894,19 +4900,51 @@
/**
* populateDefaultValues is called by the schema object to allow a table to
* populate itself with any desired values. <p>
- * The base class implementation does nothing. Override this method in derived
- * classes to achieve your custom behavior. <p>
+ * The base class implementation will set cache size IFF that was requested by
+ * calling setCacheLimitAsPercent() in setupFields.
+ * Override this method in derived classes to achieve your custom behavior,
+ * calling super.populateDefaultValues() if you want the above functionality. <p/>
+ <p>
* <p/>
- * The calling routine, DBTool.populateTables(), will set dbName on each
- * object, so you can get it from getDataContext(), and you can assume that the
- * user for the population action is Admin.
+ * The calling routine, DBTool.populateTables(), will set the requesting user, so
+ * you can assume that the user for the population action is Admin.
*
- * @throws DBException Upon add error, never if it isn't overridden.
+ * @throws DBException Upon add error
*/
public synchronized void populateDefaultValues()
throws DBException {
- //Base class version does nothing.
+ String fldname = (String) getDef().getFieldNamesList().get(0);
+ String percent = (String) getDef().getAttribute(fldname, CACHE_LIMIT_PERCENT);
+ String ttl = (String) getDef().getAttribute(fldname, CACHE_LIMIT_TTL);
+
+ if ( percent != null ) {
+ int minutesToLive = 10; // default
+ if ( ttl != null ) {
+ minutesToLive = Integer.parseInt(ttl);
+ }
+ // how many in table now?
+ long num = count();
+ long target = num * ( Integer.parseInt(percent) / 100 );
+ target = Math.max(50, target);
+ DBObjLimit dbl = new DBObjLimit(SecuredDBObject.SYSTEM_ACCOUNT);
+ dbl.setField(DBObjLimit.DB_OBJECT_NAME, getClass().getName());
+ boolean found = dbl.find();
+ if (!found) {
+ dbl.setField(DBObjLimit.CACHE_SIZE, target);
+ dbl.setField(DBObjLimit.PAGE_LIMIT, "30");
+ dbl.setField(DBObjLimit.TTL, minutesToLive);
+ dbl.add();
+ } else {
+ int current = dbl.getFieldInt(DBObjLimit.CACHE_SIZE);
+ if ( target != current) {
+ getLogger().debug("Setting cache limit to: " + target + " for class: " + getClass().getName());
+ }
+ dbl.setField(DBObjLimit.CACHE_SIZE, target);
+ dbl.setField(DBObjLimit.TTL, minutesToLive);
+ dbl.update(true);
+ }
+ }
} /* populateDefaultValues() */
@@ -5128,7 +5166,7 @@
}
if (retrieveFields == null) {
- retrieveFields = new HashMap(getMetaData().getFieldListArray().size());
+ retrieveFields = new HashMap(getMetaData().getFieldNamesList().size());
}
DBField oneField = null;
@@ -5561,7 +5599,7 @@
public synchronized void setAttribute(String attribName,
Object attribValue) {
if (attributes == null) {
- attributes = new HashMap();
+ attributes = new ConcurrentReaderHashMap();
}
attributes.put(attribName, attribValue);
@@ -6982,7 +7020,7 @@
//Build an object that we're going to query with.
DBObject testObject = newInstance();
DataObjectMetaData metadata = getMetaData();
- for (Iterator i = getMetaData().getFieldListArray().iterator();
+ for (Iterator i = getMetaData().getFieldNamesList().iterator();
i.hasNext();) {
String fieldName = (String) i.next();
DataFieldMetaData fieldMetadata = metadata.getFieldMetadata(fieldName);
@@ -7069,7 +7107,7 @@
sqlCommand.append(" SET ");
- for (Iterator i = getMetaData().getFieldListArray().iterator(); i.hasNext();) {
+ for (Iterator i = getMetaData().getFieldNamesList().iterator(); i.hasNext();) {
String oneFieldName = (String) i.next();
oneField = getFieldMetaData(oneFieldName);
@@ -7872,6 +7910,27 @@
}
/**
+ * set the number of cache instances allowed for this object type as a percentage
+ * of the current total records of this type. this call should be the last one
+ *
+ * This setting
+ * affects all instances -- it is a class setting, typically used during
+ * setupFields(). This setting automatically persists a record to the DB; no need to
+ * call update after calling this.
+ * author Larry Hamel, CodeGuild, Inc.
+ * @param percent maximum number of instances to cache,
+ * @param minutesToLive TTL for each instance in cache
+ */
+ public void setCacheLimitAsPercent(int percent, int minutesToLive) throws DBException {
+ if ( percent < 0 || percent > 10000 ) throw new DBException("Percent cannot be <0 nor >100");
+
+ // use first field as attribute holder (bit of a hack)
+ String fldname = (String) getDef().getFieldNamesList().get(0);
+ getDef().setAttribute(fldname, CACHE_LIMIT_PERCENT, percent + "");
+ getDef().setAttribute(fldname, CACHE_LIMIT_TTL, minutesToLive + "");
+ }
+
+ /**
* a rough estimate on object size in RAM. NOT suitable for exact calculation
*
* @return a rough estimate of object size in bytes
@@ -7963,6 +8022,8 @@
* record from database if necessary.
* All PK (primary keys) must be provided in a single parameter, in format like "getKey()".
* This method has instance method equivalent: fetchImmut()
+ * If the dbobjClass is a subclass of SecurDBObject, requesting UID is set via the RequestRegistry
+ * before any DB retrieval. However, simple SecuredDBObject subclasses use the default 'admin' privileges.
*
* @see DBObject#fetchImmut()
* @see DBObject#getKey()
@@ -7980,6 +8041,8 @@
* record from database if necessary.
* All PK (primary keys) must be set.
* This method has static method equivalent: fetchImmutable()
+ * If the dbobjClass is a subclass of SecurDBObject, requesting UID is set via the RequestRegistry
+ * before any DB retrieval. However, simple SecuredDBObject subclasses use the default 'admin' privileges.
*
* @see DBObject#getKey()
* @return DBObject of subclass the same as the calling class, or null if key not found.
More information about the cvs
mailing list