实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)

       缓存在O/R Mapping组件中是非常重要的,一个比较好的缓存方案,可以大大地提高对象的使用效率,避免内存空间上的浪费。目前需要在构思架构部分,但缓存的实现方式突然吸引了我,所以就对缓存进行一些思考,并研究了Gentle.NET与NHibernate的实现原理。 [这里的研究基于NHibernate 0.7.0]

NHibernate的实现方案

  在NHibernate上,缓存的机制实现充分考虑了性能与扩展性,它与Gentle.NET在实现不同的是全部是基于Hashtable而非HybridDictionary。一开始,我看见这样的实现的时候,还误以为,NHibenate过于模仿Java,而没有充分利用.NET的特性,然而,在仔细分析之后,发现直接使用Hashtable是一个非常好的思路。
  因为在HybridDictionary中,当插入一个新的对象到集合中时,该类会进行一个判断,如果集合中的元素多于9个时,则切换为Hashtable模式,这看起来非常有意思。但实际上,在O/R Mapping中,集合的数量往往都是比较多的,尤其是在企业应用中,由于网络传输数据的延迟,缓存的实现是一个非常珍贵的资源,它大大的减轻了数据库服务端的压力。就这个层次上来说,实际上实现ListDictionary并没有太大的意义。
  NHibernate的缓存机制,比起Gentle.NET来说,要复杂一些。NHibernate中,缓存对象的创建实际上通过CacheFactory产生的。这样做的原因是,在NHibernate中,缓存包括ReadOnlyCache、ReadWriteCache、NonstrictReadWriteCache这三种缓存管理类,它们都继承自ICacheConcurrencyStrategy接口,可以非常方便地添加应用了新策略的缓存管理类。
  另外,在NHibernate中,缓存对象的类型也并不是不可变的,在现有的设计上,使用了HashtableCacheProvider与HashtableCache两个类来描述Provider对象和Cache对象,分别继承于ICacheProvider与ICache,如下代码所示:
ExpandedBlockStart.gifContractedBlock.gif        /**//// <summary>
InBlock.gif        
/// Creates an <see cref="ICacheConcurrencyStrategy"/> from the parameters.
InBlock.gif        
/// </summary>
InBlock.gif        
/// <param name="usage">The name of the strategy that <see cref="ICacheProvider"/> should use for the class.</param>
InBlock.gif        
/// <param name="name">The name of the class the strategy is being created for.</param>
InBlock.gif        
/// <param name="mutable"><c>true</c> if the object being stored in the cache is mutable.</param>
ExpandedBlockEnd.gif        
/// <returns>An <see cref="ICacheConcurrencyStrategy"/> to use for this object in the <see cref="ICache"/>.</returns>

None.gif        // was private in h2.1
None.gif
        public static ICacheConcurrencyStrategy CreateCache( string usage, string name, bool mutable )
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif{
InBlock.gif            
if( log.IsDebugEnabled )
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                log.Debug( 
"cache for: " + name + "usage strategy: " + usage );
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            ICacheConcurrencyStrategy ccs 
= null;
InBlock.gif            
switch( usage )
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
case CacheFactory.ReadOnly:
InBlock.gif                    
if( mutable )
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        log.Warn( 
"read-only cache configured for mutable: " + name );
ExpandedSubBlockEnd.gif                    }

InBlock.gif                    ccs 
= new ReadOnlyCache();
InBlock.gif                    
break;
InBlock.gif                
case CacheFactory.ReadWrite:
InBlock.gif                    ccs 
= new ReadWriteCache();
InBlock.gif                    
break;
InBlock.gif                
case CacheFactory.NonstrictReadWrite:
InBlock.gif                    ccs 
= new NonstrictReadWriteCache();
InBlock.gif                    
break;
InBlock.gif                
default:
InBlock.gif                    
throw new MappingException( "cache usage attribute should be read-write, read-only, nonstrict-read-write, or transactional" );
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
return ccs;
InBlock.gif
ExpandedBlockEnd.gif        }

  可以看出,这样的实现是一个非常优秀的设计,意味着非常强大的扩展性与可维护性。
  在NHibernate的缓存方案中,使用了锁模式进行管理,它的实现是模仿操作系统中的“原语”进行的,是一个基于线程安全的实现的方案,具体的管理方式类似PV操作的形式。

转载于:https://www.cnblogs.com/William_Fire/articles/126646.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值