001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.object.config;
006:
007: import com.tc.object.lockmanager.api.LockLevel;
008:
009: import java.util.Collections;
010: import java.util.HashMap;
011: import java.util.Map;
012:
013: /**
014: * Describe a lock level from a set of enumerated values. Use the static constants or
015: * the static factory method {@link #lockLevelByName(String)} to get an instance. There are
016: * 8 types of locks defined in the config - these can all be applied to auto locks, but
017: * only the ones without AUTO_SYNCHRONIZED prefix can be used with named locks.
018: *
019: * From a concurrency perspective, there are four levels of locking that allow different
020: * amounts of access to a section:
021: * <ul>
022: * <li>WRITE - like Java synchronized sections - only one thread in the cluster may enter</li>
023: * <li>READ - allow either one writer or multiple readers at any given time</li>
024: * <li>CONCURRENT - perform no locking, but serve to mark memory transaction boundaries</li>
025: * <li>SYNCHRONOUS_WRITE - like WRITE but do not commit until the data has been saved to disk</li>
026: * </ul>
027: *
028: * In addition, for autolocks, there is an extra attribute called "auto-synhcronized" that indicates
029: * that the method should be made synchronized before auto-locking. This is useful in code you don't have
030: * control over that needs to be be made synchronized for use in a clustered environment.
031: */
032: public class ConfigLockLevel {
033: static final String WRITE_NAME = "write";
034: static final String READ_NAME = "read";
035: static final String CONCURRENT_NAME = "concurrent";
036: static final String SYNCHRONOUS_WRITE_NAME = "synchronous-write";
037: static final String AUTO_SYNCHRONIZED_WRITE_NAME = "auto-synchronized-write";
038: static final String AUTO_SYNCHRONIZED_READ_NAME = "auto-synchronized-read";
039: static final String AUTO_SYNCHRONIZED_CONCURRENT_NAME = "auto-synchronized-concurrent";
040: static final String AUTO_SYNCHRONIZED_SYNCHRONOUS_WRITE_NAME = "auto-synchronized-synchronous-write";
041:
042: /** WRITE lock, auto-synchronize=false */
043: public static final ConfigLockLevel WRITE = new ConfigLockLevel(
044: WRITE_NAME, LockLevel.WRITE);
045: /** READ lock, auto-synchronize=false */
046: public static final ConfigLockLevel READ = new ConfigLockLevel(
047: READ_NAME, LockLevel.READ);
048: /** CONCURRENT lock, auto-synchronize=false */
049: public static final ConfigLockLevel CONCURRENT = new ConfigLockLevel(
050: CONCURRENT_NAME, LockLevel.CONCURRENT);
051: /** SYNCHRONOUS_WRITE lock, auto-synchronize=false */
052: public static final ConfigLockLevel SYNCHRONOUS_WRITE = new ConfigLockLevel(
053: SYNCHRONOUS_WRITE_NAME, LockLevel.SYNCHRONOUS_WRITE);
054: /** WRITE lock, auto-synchronize=true */
055: public static final ConfigLockLevel AUTO_SYNCHRONIZED_WRITE = new ConfigLockLevel(
056: AUTO_SYNCHRONIZED_WRITE_NAME, LockLevel.WRITE);
057: /** READ lock, auto-synchronize=false */
058: public static final ConfigLockLevel AUTO_SYNCHRONIZED_READ = new ConfigLockLevel(
059: AUTO_SYNCHRONIZED_READ_NAME, LockLevel.READ);
060: /** CONCURRENT lock, auto-synchronize=false */
061: public static final ConfigLockLevel AUTO_SYNCHRONIZED_CONCURRENT = new ConfigLockLevel(
062: AUTO_SYNCHRONIZED_CONCURRENT_NAME, LockLevel.CONCURRENT);
063: /** SYNCHRONOUS_WRITE lock, auto-synchronize=false */
064: public static final ConfigLockLevel AUTO_SYNCHRONIZED_SYNCHRONOUS_WRITE = new ConfigLockLevel(
065: AUTO_SYNCHRONIZED_SYNCHRONOUS_WRITE_NAME,
066: LockLevel.SYNCHRONOUS_WRITE);
067:
068: private static final Map locksByLevel;
069:
070: static {
071: HashMap tmp = new HashMap();
072:
073: tmp.put(WRITE_NAME, WRITE);
074: tmp.put(READ_NAME, READ);
075: tmp.put(CONCURRENT_NAME, CONCURRENT);
076: tmp.put(SYNCHRONOUS_WRITE_NAME, SYNCHRONOUS_WRITE);
077: tmp.put(AUTO_SYNCHRONIZED_WRITE_NAME, AUTO_SYNCHRONIZED_WRITE);
078: tmp.put(AUTO_SYNCHRONIZED_READ_NAME, AUTO_SYNCHRONIZED_READ);
079: tmp.put(AUTO_SYNCHRONIZED_CONCURRENT_NAME,
080: AUTO_SYNCHRONIZED_CONCURRENT);
081: tmp.put(AUTO_SYNCHRONIZED_SYNCHRONOUS_WRITE_NAME,
082: AUTO_SYNCHRONIZED_SYNCHRONOUS_WRITE);
083:
084: locksByLevel = Collections.unmodifiableMap(tmp);
085: }
086:
087: private final String lockLevelName;
088: private final int level;
089:
090: private ConfigLockLevel(String lockTypeName, int type) {
091: this .lockLevelName = lockTypeName;
092: this .level = type;
093: }
094:
095: /**
096: * @return Ordinal lock level value
097: */
098: public int getLevel() {
099: return level;
100: }
101:
102: public String toString() {
103: return lockLevelName;
104: }
105:
106: /**
107: * Provide an instance of the constant for the specified name
108: * or null if name is invalid
109: * @param typeName Lock level name
110: * @return Lock level instance
111: */
112: public static ConfigLockLevel lockLevelByName(String typeName) {
113: ConfigLockLevel rv = null;
114: if (typeName != null)
115: rv = (ConfigLockLevel) locksByLevel.get(typeName);
116: return rv;
117: }
118: }
|