static final int MAXIMUM_CAPACITY = 1 << 30:缓存最大容量,该数值必须是2的幂,同时小于这个最大值2^30
static final int MAX_SEGMENTS = 1 << 16:Segment数组最大容量
static final int CONTAINS_VALUE_RETRIES = 3:containsValue方法的重试次数
static final int DRAIN_THRESHOLD = 0x3F(63):Number of cache access operations that can be buffered per segment before the cache’s recency ordering information is updated. This is used to avoid lock contention by recording a memento of reads and delaying a lock acquisition until the threshold is crossed or a mutation occurs.
static final int DRAIN_MAX = 16:一次清理操作中,最大移除的entry数量
final int segmentMask:定位segment
final int segmentShift:定位segment,同时让entry分布均匀,尽量平均分布在每个segment[i]中
final Segment
LocalCache初始化
LocalCache构造入口如下: LocalCache(CacheBuilder super K, ? super V> builder, @Nullable CacheLoader super K, V> loader) 其中,builder就是通过CacheBuilder创建的实例,这个在上面的小节中已经讲解了,下面看一下LocalCache初始化部分的代码:
LocalCache(
CacheBuilder super K, ? super V> builder, @Nullable CacheLoader super K, V> loader) {
//并发程度,根据我们传的参数和默认最大值中选取小者。//如果没有指定该参数的情况下,CacheBuilder将其置为UNSET_INT即为-1//getConcurrencyLevel方法获取时,如果为-1就返回默认值4//否则返回用户传入的参数
concurrencyLevel = Math.min(builder.getConcurrencyLevel(), MAX_SEGMENTS);
//键值的引用类型,没有指定的话,默认为强引用类型
keyStrength = builder.getKeyStrength();
valueStrength = builder.getValueStrength();
//判断相同的方法,强引用类型就是Equivalence.equals()
keyEquivalence = builder.getKeyEquivalence();
valueEquivalence = builder.getValueEquivalence();
maxWeight = builder.getMaximumWeight();
weigher = builder.getWeigher();
expireAfterAccessNanos = builder.getExpireAfterAccessNanos();
expireAfterWriteNanos = builder.getExpireAfterWriteNanos();
refreshNanos = builder.getRefreshNanos();
//移除消息监听器
removalListener = builder.getRemovalListener();
//如果我们指定了移除消息监听器的话,会创建一个队列,临时保存移除的内容
removalNotificationQueue = (removalListener == NullListener.INSTANCE)
? LocalCache.>discardingQueue()
: new ConcurrentLinkedQueue>();
ticker = builder.getTicker(recordsTime());
//创建新的缓存内容(entry)的工厂,会根据引用类型选择对应的工厂
entryFactory = EntryFactory.getFactory(keyStrength, usesAccessEntries(), usesWriteEntries());
globalStatsCounter = builder.getStatsCounterSupplier().get();
defaultLoader = loader;
//初始化缓存容量,默认为16int initialCapacity = Math.min(builder.getInitialCapacity(), MAXIMUM_CAPACITY);
if (evictsBySize() && !customWeigher()) {
initialCapacity = Math.min(initialCapacity, (int) maxWeight);
}
// Find the lowest power-of-two segmentCount that exceeds concurrencyLevel, unless// maximumSize/Weight is specified in which case ensure that each segment gets at least 10// entries. The special casing for size-based eviction is only necessary because that eviction// happens per segment instead of globally, so too many segments compared to the maximum size// will result in random eviction behavior.int segmentShift = 0;
int segmentCount = 1;
//根据并发程度来计算segement数组的大小(大于等于concurrencyLevel的最小的2的幂,这里即为4)while (segmentCount < concurrencyLevel
&& (!evictsBySize() || segmentCount * 20 <= maxWeight)) {
++segmentShift;
segmentCount <<= 1;
}
//这里的segmentShift和segmentMask用来打散entry,让缓存内容尽量均匀分布在每个segment下this.segmentShift = 32 - segmentShift;
segmentMask = segmentCount - 1;
//这里进行初始化segment数组,大小即为4this.segments = newSegmentArray(segmentCount);
//每个segment的容量,总容量/segment的大小,向上取整,这里就是16/4=4int segmentCapacity = initialCapacity / segmentCount;
if (segmentCapacity * segmentCount < initialCapacity) {
++segmentCapacity;
}
//这里计算每个Segment[i]下的table的大小int segmentSize = 1;
//SegmentSize为小于segmentCapacity的最大的2的幂,这里为4while (segmentSize < segmentCapacity) {
segmentSize <<= 1;
}
//初始化每个segment[i]//注:根据权重的方法使用较少,这里走else分支if (evictsBySize()) {
// Ensure sum of segment max weights = overall max weightslong maxSegmentWeight = maxWeight / segmentCount + 1;
long remainder = maxWeight % segmentCount;
for (int i = 0; i < this.segments.length; ++i) {
if (i == remainder) {
maxSegmentWeight--;
}
this.segments[i] =
createSegment(segmentSize, maxSegmentWeight, builder.getStatsCounterSupplier().get());
}
} else {
for (int i = 0; i < this.segments.length; ++i) {
this.segments[i] =
createSegment(segmentSize, UNSET_INT, builder.getStatsCounterSupplier().get());
}
}
}
static class Segment extends ReentrantLock {
final LocalCache map;
/**
* The number of live elements in this segment's region.
*/volatileint count;
/**
* The weight of the live elements in this segment's region.
*/@GuardedBy("this")
long totalWeight;
/**
* Number of updates that alter the size of the table. This is used during bulk-read methods to
* make sure they see a consistent snapshot: If modCounts change during a traversal of segments
* loading size or checking containsValue, then we might have an inconsistent view of state
* so (usually) must retry.
*/int modCount;
/**
* The table is expanded when its size exceeds this threshold. (The value of this field is
* always {@code (int) (capacity * 0.75)}.)
*/int threshold;
/**
* The per-segment table.
*/volatile AtomicReferenceArray> table;
/**
* The maximum weight of this segment. UNSET_INT if there is no maximum.
*/finallong maxSegmentWeight;
/**
* The key reference queue contains entries whose keys have been garbage collected, and which
* need to be cleaned up internally.
*/final ReferenceQueue keyReferenceQueue;
/**
* The value reference queue contains value references whose values have been garbage collected,
* and which need to be cleaned up internally.
*/final ReferenceQueue valueReferenceQueue;
/**
* The recency queue is used to record which entries were accessed for updating the access
* list's ordering. It is drained as a batch operation when either the DRAIN_THRESHOLD is
* crossed or a write occurs on the segment.
*/final Queue> recencyQueue;
/**
* A counter of the number of reads since the last write, used to drain queues on a small
* fraction of read operations.
*/final AtomicInteger readCount = new AtomicInteger();
/**
* A queue of elements currently in the map, ordered by write time. Elements are added to the
* tail of the queue on write.
*/@GuardedBy("this")
final Queue> writeQueue;
/**
* A queue of elements currently in the map, ordered by access time. Elements are added to the
* tail of the queue on access (note that writes count as accesses).
*/@GuardedBy("this")
final Queue> accessQueue;
/** Accumulates cache statistics. */final StatsCounter statsCounter;
}
返回做IO数目最多的50条语句以及它们的执行计划。
select top 50
(total_logical_reads/execution_count) as avg_logical_reads,
(total_logical_writes/execution_count) as avg_logical_writes,
(tot
The CUDA 5 Release Candidate is now available at http://developer.nvidia.com/<wbr></wbr>cuda/cuda-pre-production. Now applicable to a broader set of algorithms, CUDA 5 has advanced fe
Essential Studio for WinRT界面控件包含了商业平板应用程序开发中所需的所有控件,如市场上运行速度最快的grid 和chart、地图、RDL报表查看器、丰富的文本查看器及图表等等。同时,该控件还包含了一组独特的库,用于从WinRT应用程序中生成Excel、Word以及PDF格式的文件。此文将对其另外一个强大的控件——网格控件进行专门的测评详述。
网格控件功能
1、
Project Euler是个数学问题求解网站,网站设计的很有意思,有很多problem,在未提交正确答案前不能查看problem的overview,也不能查看关于problem的discussion thread,只能看到现在problem已经被多少人解决了,人数越多往往代表问题越容易。
看看problem 1吧:
Add all the natural num
Adding id and class names to CMenu
We use the id and htmlOptions to accomplish this. Watch.
//in your view
$this->widget('zii.widgets.CMenu', array(
'id'=>'myMenu',
'items'=>$this-&g
Given a collection of integers that might contain duplicates, nums, return all possible subsets.
Note:
Elements in a subset must be in non-descending order.
The solution set must not conta