George Chiramattel - Software architect with over 15 years of indiustry experience. Generally interested in anything related to Technology and leading a Full Life.
link More about me

Recently in DotSVN Category

Tools used for DotSVN - Resharper

I have been using a trial version of ReSharper for my DotSVN project and I should say that I just got hooked to it. I would not have made this much progress without it and that leaves me wondering what I would do once the trial expires!!

A tool with this ease of use is needed to improve the design and code without any hesitation to refactor.
ReSharper's code navigation capabilities are also extra ordinary. You can read more about it here.

I have also used dotTrace to fix a nasty performance issue.

Overall I am very satisfied with the product.


Performance of DateTime.Parse()

I would like to write a series of posts describing the various performance issues I faced while implementing DotSVN.

In this post I discuss the performance penalty of using DateTime.Parse().

During my testing, I found that DotSVN was running quite slow. I used a trial version of 'JetBrains dotTrace 3.0' to analyze the problem. The following is a screen-shot of the dotTrace session.
DateTime.Parse() Performance issue

As you can see, 26% of the time is spend on the method call 'System.DateTime.Parse()'. This was unacceptable. After some investigation I found that the performance of the DateTime Parse method can be improved if we give some clue on formatting of the date string. This can be achieved using the ParseExact() method.

note: I have updated the code to re-use the CultureInfo class.
AlexKucherenko - Thanks for the comment.



private static readonly CultureInfo en_us_Culture = new CultureInfo("en-US");

// Parse in the format [2007-09-06T10:20:26.689093Z]
private static readonly string dateTimeFormat = "yyyy-MM-ddTHH:mm:ss.FFFFFFFZ";

public static DateTime parseDate(String dateString)
{
	DateTime parsedDate;

	bool parseResult = DateTime.TryParseExact(dateString, dateTimeFormat, 
							en_us_Culture, 
							DateTimeStyles.AdjustToUniversal, out parsedDate);
	if(!parseResult)
	{
		SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.BAD_DATE);
		SVNErrorManager.error(err);    
	}
	return parsedDate;
}


The performance gain is quite obvious with the following figure, which shows the dotTrace session after applying the above fix.
DateTime.ParseExact() solution

As you can see, DateTime.Parse() is no longer a hot Spot. This also shows the power of dotTrace, and how it helped to quickly narrow down the issue.

Announcing DotSVN.Net site

I have registered the domain dotsvn.net. This will be the new home of DotSVN project. I will continue to host the code in google code itself.

The site is pretty empty right now. I am planning to get some content uploaded during the weekend.

I have also hosted the DotSVN Asp.Net sample at code.dotsvn.net.
This sample demonstrates basic functionality of browsing any subversion FSFS repository. My target is to make this as functional as bsSvnBrowser. You can see a live demo of bsSvnBrowser here.

Once this code becomes feature complete, I will be using the same for the nTrac project.


Connecting to SVN repository using DotSVN

In this post I would like to highlight how easy it is to connect to SVN repository using DotSVN.

Steps to follow:
1) Create an instance of ISVNRepository using the SVNRepositoryFactory
// The path to the root of an SVN FSFS repository
string repositoryPath = "file://" + "SomeValidPathToFSFS";

// Creates an ISVNRepository driver according to the protocol 
// that is to be used to access a repository.
ISVNRepository repository = SVNRepositoryFactory.Create(new SVNURL(repositoryPath));
repository.OpenRepository();
2) Now that we have a connection to the repository, we can get contents using the GetDir method.
// Dictionary to receive the SVN properties
IDictionary properties = new Dictionary();

// Now we call GetDir to get the contents at the specified path
// Here we specified an empty string to get the contents of the root
// Second argument is the version, -1 indicated the latest version
// Third argument is the property collection
ICollection dirEntries = repository.GetDir("", -1, properties);
The SVNDirEntry representation of a versioned directory entry, It contains
  • The Entry name
  • Entry kind (is it a file or directory).
  • File size (in case an entry is a file)
  • The last changed revision
  • The date when the entry was last changed
  • The name of the author who last changed the entry
  • The commit log message for the last changed revision.
3) Now we can iterate through the SVNDirEntry collection.
foreach (SVNDirEntry dirEntry in dirEntries)
{
    string DirName = dirEntry.Name;
    System.Diagnostics.Debug.WriteLine(DirName);
}
And that is it. We can also call other methods in the repository like
// Gets the Universal Unique IDentifier (UUID) of this repository 
string repostoryUUID = repository.GetRepositoryUUID(true);

// Returns the latest revision of this repository
long latestRev = repository.GetLatestRevision();

FireBug is an amazing FireFox plugin for developers

I have been using Firebug Firefox plugin. This is a really useful tool, and I would definitely recommend this for anyone who is interested in Web development. If you are new to this tool, I suggest that you go through this article, as a good introduction.

I have captured a few scenarios where this proved useful to me.

JavaScript debugging
Javascript debugging is a really compelling feature of Firebug.

FireBug JavaScript Debugging

As you can see, you can easily put break-point and step through .js loaded in the browser.

Network Monitoring

FireBug can present a time-line of the various resources downloaded to render a given page. This is very useful for understanding performance issues with a page.
FireBug Network Monitoring

XML HTTP Request monitoring (XHR)

With this feature, we can track the actual request and response between the browser and server.
I used this feature to track the JSON response from the DotSVN server.
FireBug Console XHR monitoring


The SVNKit influence on DotSVN

I used two good references when doing DotSVN. The first is (obviously) the SVN code itself. It is written in C using Apache Portable Runtime (APR).

What I would like to highlight is the second reference that I used - which is SVNKit. SVNKit is:

... a pure Java Subversion client library. You would like to use SVNKit when you need to access or modify Subversion repository from your Java application, be it a standalone program, plugin or web application. Being a pure Java program, SVNKit doesn't need any additional configuration or native binaries to work on any OS that runs Java.

I used VStudio's 'Java Language Conversion Assistant 3.0' to create a C# version of the SVNKit code. Though it had thousands of migration errors, this exercise gave me a good idea of the effort involved in completing DotSVN. I used the skeleton code from the migration as the basis for most of the my classes.

DotSVN has a different namespace structure (as shown in the figure below):
DotSVN Namespace and project structure

DotSVN depends more heavily on .Net base class libraries (like Deflate stream, custom Date parsing etc). It also uses generics and collection classes more efficiently.


DotSVN progress

I am personally quite happy with the progress that I could make on DotSVN. Using this library, it is currently possible to do the following operations.
  • Open an FSFS SVN repository
  • Enumerate its contents
  • Retrieve the properties collection of each element
  • Get the contents as a stream
I have also added three sample application. One is a console based application. The second one is a WinForms GUI sample that is very similar to the TortoiseSVN repository browser. The third one, is a browser based SVN repository viewer using Yahoo UI controls.


"Block length does not match with its complement." in DeflateStream

I wanted to discuss a problem that I faced while implementing the repository layer of DotSVN.
When I tried to use the System.IO.Compression.DeflateStream to decompress the repository, I get the exception 'System.IO.InvalidDataException' : "Block length does not match with its complement."

I Googled around an found this article that explains the problem. The feedback from Microsoft on how to fix this issue is as follows:
...skipping past the first two bytes solved the problem. Those bytes are part of the zlib specification (RFC 1950), not the deflate specification (RFC 1951). Those bytes contain information about the compression method and flags.

The zlib and deflate formats are related; the compressed data part of zlib-formatted data may be stored in the deflate format. In particular, if the compression method in the zlib header is set to 8, then the compressed data is stored in the deflate format. This is true in the case of the stream you submitted, which was taken from a pdf file.

Our DeflateStream, on the other hand, represents the deflate specification (RFC 1951) but not RFC 1950. So your workaround of skipping past the first 2 bytes to get to the deflate data will definitely work.
So the actual code would look like the following:
// create a file stream, as before
FileStream fs = new FileStream("file", FileMode.Open);

// skip first two bytes
fs.ReadByte();
fs.ReadByte();

// now create the deflate stream and proceed as usual
DeflateStream l_Stream = new DeflateStream(fs, CompressionMode.Decompress);

Significant milestone reached for DotSVN

I am happy to announce the first increment release of DotSVN.

DotSVN is a 100% compatible (at the repository level) port of SVN - very similar to SVNKit. It can be used to access or modify SVN repository from DotNet application, be it a standalone program or from an Asp.Net web application. As mentioned here, this project was started to support the nTrac project.

 Sample GUI Client for DotSVN
Sample .Net application build using DotSVN, accessing an FSFS file repository using 'file access'.