[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