Permalink
Browse files

Merged Adam's HiLo fixes.

  • Loading branch information...
2 parents 6072327 + bb39dca commit 7c673184767d79acb9dfc2ad75929eb303b7bf6d @atheken committed Aug 4, 2010
@@ -36,17 +36,17 @@ public long GenerateId(IMongoDatabase db, string collectionName)
lock (generatorLock)
{
if (keyGeneratorsByTag.TryGetValue(collectionName, out value))
- return value.GenerateId(collectionName);
+ return value.GenerateId(collectionName, db);
- value = new HiLoIdGenerator(db, _capacity);
+ value = new HiLoIdGenerator(_capacity);
// doing it this way for thread safety
keyGeneratorsByTag = new Dictionary<string, HiLoIdGenerator>(keyGeneratorsByTag)
{
{collectionName, value}
};
}
- return value.GenerateId(collectionName);
+ return value.GenerateId(collectionName, db);
}
}
}
@@ -14,14 +14,12 @@ namespace Norm.Collections
public class HiLoIdGenerator
{
private readonly long _capacity;
- private readonly object generatorLock = new object();
+ private ReaderWriterLockSlim _lockSlim = new ReaderWriterLockSlim();
private long _currentHi;
private long _currentLo;
- private IMongoDatabase _db;
- public HiLoIdGenerator(IMongoDatabase db, long capacity)
+ public HiLoIdGenerator(long capacity)
{
- _db = db;
_currentHi = 0;
_capacity = capacity;
_currentLo = capacity + 1;
@@ -32,25 +30,26 @@ public HiLoIdGenerator(IMongoDatabase db, long capacity)
/// </summary>
/// <param name="collectionName">Collection Name</param>
/// <returns></returns>
- public long GenerateId(string collectionName)
+ public long GenerateId(string collectionName, IMongoDatabase database)
{
+ _lockSlim.EnterUpgradeableReadLock();
long incrementedCurrentLow = Interlocked.Increment(ref _currentLo);
if (incrementedCurrentLow > _capacity)
{
- lock (generatorLock)
+ _lockSlim.EnterWriteLock();
+ if (Thread.VolatileRead(ref _currentLo) > _capacity)
{
- if (Thread.VolatileRead(ref _currentLo) > _capacity)
- {
- _currentHi = GetNextHi(collectionName);
- _currentLo = 1;
- incrementedCurrentLow = 1;
- }
+ _currentHi = GetNextHi(collectionName, database);
+ _currentLo = 1;
+ incrementedCurrentLow = 1;
}
+ _lockSlim.ExitWriteLock();
}
+ _lockSlim.ExitUpgradeableReadLock();
return (_currentHi - 1) * _capacity + (incrementedCurrentLow);
}
- private long GetNextHi(string collectionName)
+ private long GetNextHi(string collectionName, IMongoDatabase database)
{
while (true)
{
@@ -59,10 +58,10 @@ private long GetNextHi(string collectionName)
var update = new Expando();
update["$inc"] = new { ServerHi = 1 };
- var hiLoKey = _db.GetCollection<NormHiLoKey>().FindAndModify(new { _id = collectionName }, update);
+ var hiLoKey = database.GetCollection<NormHiLoKey>().FindAndModify(new { _id = collectionName }, update);
if (hiLoKey == null)
{
- _db.GetCollection<NormHiLoKey>().Insert(new NormHiLoKey { CollectionName = collectionName, ServerHi = 2 });
+ database.GetCollection<NormHiLoKey>().Insert(new NormHiLoKey { CollectionName = collectionName, ServerHi = 2 });
return 1;
}
@@ -19,8 +19,11 @@ namespace Norm.Collections
/// <summary>
/// Mongo typed collection.
/// </summary>
+ /// <remarks>
+ /// This class is not (and will probably not become) thread-safe.
+ /// </remarks>
/// <typeparam retval="T">Collection type</typeparam>
- public class MongoCollection<T> : IMongoCollection<T>
+ public partial class MongoCollection<T> : IMongoCollection<T>
{
private static Dictionary<int, object> _compiledTransforms = new Dictionary<int, object>();
private static CollectionHiLoIdGenerator _collectionHiLoIdGenerator = new CollectionHiLoIdGenerator(20);

0 comments on commit 7c67318

Please sign in to comment.