Skip to content
This repository has been archived by the owner on Feb 10, 2022. It is now read-only.

Add docstrings and improve readability to make the source code more welcoming to newcomers. #122

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions Common/Class1.cs

This file was deleted.

38 changes: 0 additions & 38 deletions Common/Common.csproj

This file was deleted.

7 changes: 4 additions & 3 deletions QBitNinja/ActionDisposable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,24 @@ namespace QBitNinja
{
public class ActionDisposable : IDisposable
{
Action _Act;
readonly Action _Act;

public ActionDisposable(Action act)
{
_Act = act;
}

public ActionDisposable(Action start, Action act)
{
start();
_Act = act;
}

#region IDisposable Members

public void Dispose()
{
_Act();
}

#endregion
}
}
28 changes: 15 additions & 13 deletions QBitNinja/CacheBlocksRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,43 +11,45 @@ namespace QBitNinja
{
public class CacheBlocksRepository : IBlocksRepository
{
private IBlocksRepository _Repo;
private readonly IBlocksRepository _Repo;

public CacheBlocksRepository(IBlocksRepository repo)
{
if(repo == null)
throw new ArgumentNullException("repo");
this._Repo = repo;
this._Repo = repo ?? throw new ArgumentNullException("repo");
}

List<Tuple<uint256, Block>> _LastAsked = new List<Tuple<uint256, Block>>();
List<Tuple<uint256, Block>> _LastAsked = new List<Tuple<uint256, Block>>(); // A cache of blocks.


#region IBlocksRepository Members

int MaxBlocks = 70;
static readonly int MaxBlocks = 70; // The maximum number of blocks that may be cached.

public IEnumerable<NBitcoin.Block> GetBlocks(IEnumerable<NBitcoin.uint256> hashes, CancellationToken cancellation)
public IEnumerable<NBitcoin.Block> GetBlocks(IEnumerable<NBitcoin.uint256> hashes, CancellationToken cancellationToken)
{
var asked = hashes.ToList();
if(asked.Count > MaxBlocks)
return _Repo.GetBlocks(hashes, cancellation);

if (asked.Count > MaxBlocks) // Asked for more than fit in the cache size, no point in checking cache.
return _Repo.GetBlocks(hashes, cancellationToken); // Fetch from repo instead.

var lastAsked = _LastAsked;

if(lastAsked != null && asked.SequenceEqual(lastAsked.Select(a => a.Item1)))
if (lastAsked != null && asked.SequenceEqual(lastAsked.Select(a => a.Item1)))
return lastAsked.Select(l=>l.Item2);
var blocks = _Repo.GetBlocks(hashes, cancellation).ToList();
if(blocks.Count < 5)

var blocks = _Repo.GetBlocks(hashes, cancellationToken).ToList();

if (blocks.Count < 5) // Shouldn't this number match 'MaxBlocks = 70' ?
{
_LastAsked = blocks.Select(b => Tuple.Create(b.GetHash(), b)).ToList();
}
else
{
_LastAsked = null;
}

return blocks;
}

#endregion
}
}
28 changes: 12 additions & 16 deletions QBitNinja/ChainTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,27 @@
namespace QBitNinja
{
/// <summary>
/// Such table can store data keyed by Height/BlockId/TransactionId, and range query them
/// Wraps an Azure table that may store data keyed by Height/BlockId/TransactionId, and allows for range queries against it.
/// </summary>
public class ChainTable<T>
{
private readonly JsonSerializerSettings serializerSettings;
readonly CloudTable _cloudTable;
readonly CloudTable _cloudTable; // An Azure table

public ChainTable(CloudTable cloudTable, Network network)
{
if(cloudTable == null)
throw new ArgumentNullException("cloudTable");
if (network == null)
throw new ArgumentNullException(nameof(network));
JsonSerializerSettings serializerSettings = new JsonSerializerSettings();

var serializerSettings = new JsonSerializerSettings();
QBitNinja.Serializer.RegisterFrontConverters(serializerSettings, network);
this.serializerSettings = serializerSettings;
_cloudTable = cloudTable;
}

public CloudTable Table
{
get
{
return _cloudTable;
}
}
public CloudTable Table => _cloudTable;

public Scope Scope
{
Expand All @@ -50,8 +46,6 @@ public void Create(ConfirmedBalanceLocator locator, T item)
Table.Execute(TableOperation.InsertOrReplace(entity));
}



public void Delete(ConfirmedBalanceLocator locator)
{
var entity = new DynamicTableEntity(Escape(Scope), Escape(locator))
Expand All @@ -60,15 +54,16 @@ public void Delete(ConfirmedBalanceLocator locator)
};
Table.Execute(TableOperation.Delete(entity));
}

public void Delete()
{
foreach(var entity in Table.ExecuteQuery(new TableQuery()
var tableQuery = new TableQuery()
{
FilterString = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, Escape(Scope))
}))
{
};

foreach (var entity in Table.ExecuteQuery(tableQuery))
Table.Execute(TableOperation.Delete(entity));
}
}

public IEnumerable<T> Query(ChainBase chain, BalanceQuery query = null)
Expand All @@ -95,6 +90,7 @@ private string ParseData(DynamicTableEntity entity)
}
return builder.ToString();
}

private void PutData(DynamicTableEntity entity, string str)
{
int i = 0;
Expand Down
45 changes: 25 additions & 20 deletions QBitNinja/CrudTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,14 @@ public CrudTableFactory(JsonSerializerSettings serializerSettings, Func<CloudTab
}

readonly Func<CloudTable> _createTable;

public Scope Scope
{
get;
private set;
}

private JsonSerializerSettings serializerSettings;
private readonly JsonSerializerSettings serializerSettings;

public CrudTable<T> GetTable<T>(string tableName)
{
Expand All @@ -45,6 +46,12 @@ public CrudTable<T> GetTable<T>(string tableName)
};
}
}

/// <summary>
/// Wraps an Azure CloudTable, offering CRUD operations for objects of a specific type, automatically
/// serializing to and from JSON when querying the CloudTable.
/// </summary>
/// <typeparam name="T"></typeparam>
public class CrudTable<T>
{
public CrudTable(CloudTable table, JsonSerializerSettings serializerSettings)
Expand All @@ -53,7 +60,7 @@ public CrudTable(CloudTable table, JsonSerializerSettings serializerSettings)
throw new ArgumentNullException("table");
if (serializerSettings == null)
throw new ArgumentNullException(nameof(serializerSettings));
_table = table;
Table = table;
Scope = new Scope();
this.serializerSettings = serializerSettings;
}
Expand All @@ -64,14 +71,12 @@ public Scope Scope
set;
}

private JsonSerializerSettings serializerSettings;
private readonly CloudTable _table;
private readonly JsonSerializerSettings serializerSettings;

public CloudTable Table
{
get
{
return _table;
}
get;
private set;
}

public async Task<bool> CreateAsync(string itemId, T item, bool orReplace = true)
Expand All @@ -82,9 +87,9 @@ public async Task<bool> CreateAsync(string itemId, T item, bool orReplace = true
var entity = new DynamicTableEntity(Escape(Scope), Escape(itemId))
{
Properties =
{
new KeyValuePair<string,EntityProperty>("data",new EntityProperty(callbackStr))
}
{
new KeyValuePair<string, EntityProperty>("data", new EntityProperty(callbackStr))
}
};
await Table.ExecuteAsync(orReplace ? TableOperation.InsertOrReplace(entity) : TableOperation.Insert(entity)).ConfigureAwait(false);
}
Expand Down Expand Up @@ -118,7 +123,7 @@ public void Delete()
}
}

void Ignore(int errorCode, Action act)
private void Ignore(int errorCode, Action act)
{
try
{
Expand All @@ -130,6 +135,7 @@ void Ignore(int errorCode, Action act)
throw;
}
}

public bool Delete(string itemId, bool includeChildren = false)
{
try
Expand All @@ -140,8 +146,8 @@ public bool Delete(string itemId, bool includeChildren = false)
}));
if (includeChildren)
{
var children = Scope.GetChild(itemId);
foreach (var child in Table.ExecuteQuery(AllInScope(children)))
var childScope = Scope.GetChild(itemId); // 'itemId' can be a path.
foreach (var child in Table.ExecuteQuery(AllInScope(childScope)))
{
Ignore(404, () => Table.Execute(TableOperation.Delete(child)));
}
Expand All @@ -156,11 +162,11 @@ public bool Delete(string itemId, bool includeChildren = false)
return true;
}

private static TableQuery AllInScope(QBitNinja.Scope children)
private static TableQuery AllInScope(QBitNinja.Scope scope)
{
return new TableQuery()
{
FilterString = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, Escape(children))
FilterString = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, Escape(scope))
};
}

Expand All @@ -185,8 +191,6 @@ private static string Escape(string key)
return result;
}



public async Task<T> ReadOneAsync(string item)
{
var e = (await Table.ExecuteAsync(TableOperation.Retrieve(Escape(Scope), Escape(item))).ConfigureAwait(false)).Result as DynamicTableEntity;
Expand All @@ -195,12 +199,10 @@ public async Task<T> ReadOneAsync(string item)
return JsonConvert.DeserializeObject<T>(e.Properties["data"].StringValue, serializerSettings);
}


public T ReadOne(string item)
{
try
{

return ReadOneAsync(item).Result;
}
catch (AggregateException aex)
Expand All @@ -210,6 +212,9 @@ public T ReadOne(string item)
}
}

/// <summary>
/// Get a CrudTable that is scoped to some nested path.
/// </summary>
public CrudTable<T> GetChild(params string[] children)
{
return new CrudTable<T>(Table, serializerSettings)
Expand Down
Loading