FileLogCache.cpp #3

  • //
  • guest/
  • sam_stafford/
  • p4hl/
  • src/
  • dlls/
  • FileLogCache.cpp
  • View
  • Commits
  • Open Download .zip Download (2 KB)
// FileLogCache.cpp: implementation of the FileLogCache class.
//
//////////////////////////////////////////////////////////////////////

#include "FileLogCache.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

/* Create a new FileLogCache.  After a FileLogCache has been constructed,
 * not much else needs to be done to it. */
FileLogCache::FileLogCache(StrBuf filepath)
{
	changes = new ChangeSorter();
	main = new FileHead(filepath, this); //Create the "main" FileHead.
	from = NULL;
	into = NULL;
	main->scanMain(); //check all revs in "main"
}

FileHead* FileLogCache::AddFrom(StrBuf filepath)
{
	if (from == NULL) //If we don't have any "from" FileHeads yet:
	{
		from = new FileHead(filepath, this);
		return from;
	} //otherwise:
	FileHead* working = new FileHead(filepath, this);
	working->next = from;
	from = working;
	return from;
}

/*AddInto works much like AddFrom - I don't think it needs explanation. */
FileHead* FileLogCache::AddInto(StrBuf filepath)
{
	if (into == NULL)
	{
		into = new FileHead(filepath, this);
		return into;
	}
	FileHead* working = new FileHead(filepath, this);
	working->next = into;
	into = working;
	return into;
}

FileHead* FileLogCache::AddAfter(StrBuf filepath, FileHead* caller)
{
	if (caller == main) return AddFrom(filepath);
	FileHead* working = new FileHead(filepath, this);
	working->next = caller->next;
	caller->next = working;
	return working;
}


FileHead* FileLogCache::Get(StrBuf filepath, bool exfrom, FileHead* caller)
{
	if (main->file == filepath){ //Was it main?
		return main;
	}
	FileHead* working = from; //Is it in from?
	while (working != NULL)
	{
		if (working->file == filepath) return working;
		working = working->next;
	}
	working = into; //Is it in into?
	while (working != NULL)
	{
		if (working->file == filepath) return working;
		working = working->next;
	}
	/* Make a new one, then. */
	if (caller == main) //If the caller was "main"...
	{
		if (exfrom) return AddFrom(filepath);
		else return AddInto(filepath);
	}
	else
	{
		return AddAfter(filepath, caller);
	}
}

FileLogCache::~FileLogCache() //Clean up everything when deleting this object.
{
	if (main != NULL) delete main;
	if (from != NULL) delete from;
	if (into != NULL) delete into;
	delete changes;
}
# Change User Description Committed
#13 1709 Sam Stafford Propagate bug fix and include change from p4hltest.

No functional change - P4HL never used "numarrows" so the bug
doesn't affect it.
#12 1689 Sam Stafford Integrate 02.1 API and code cleanup to P4HL.
 Lots of work.  Phew.
#11 1600 Sam Stafford Integrate case-insensitivity fix to P4HL.

Integration only change.
#10 1586 Sam Stafford Migrate outstanding changes into P4HL - no functional change.
#9 1557 Sam Stafford Integrate bug fix for testing.
 Looks good so far.
#8 1548 Sam Stafford Integrate RevType change to make sure it works.
 It does.
#7 1521 Sam Stafford Integrated change 1520 to P4HL.
 Updated CObjectFile::Expand() to use
the new variable name.

Infrastructure change.
#6 1457 Sam Stafford Use RunTag() to queue up filelog commands.
 Should in theory improve
performance, although I haven't noticed any great difference.

Integration only change.
#5 1450 Sam Stafford Major performance improvement - use one ClientApi connection for all
filelogs.
Improves querying time about tenfold on large requests!

Had to move client->Final() to the constructor to ensure that
connection is cleaned up promptly and doesn't hang things up.
#4 1433 Sam Stafford Integ display: if you see one of a file's revisions, you see them all.
Previously, your view was limited to those revisions which were
directly
related to the file you asked about.  However, if you asked about a
file branched from the mainline, this meant that you couldn't see
mainline changes that weren't yet integrated into your branch, and
that's
not terribly useful.
#3 975 Sam Stafford Nigh-complete fix for job 4 - the "scan" methods all
go from tail to head now, and Get uses the improved
"addAfter" method where appropriate.

An unforeseen problem was the fact that a complex integ
history can get followed through more than one possible
path, causing later versions of a given file to get scanned
before earlier versions, and messing up the graph.

This is fixed (albeit in a kludgey fashion) in scanMain here
by making two passes through the FileHead, caching the files
on the first pass and actually running scans on the second
pass.  A slightly more efficient way of handling it might be
to keep a list of FileRevs that need to be scanned - perhaps
by declaring a temporary FileHead to serve as a list?  Once
it's been hammered out in scanMain() satisfactorily that method
can be employed in the other scan methods.
#2 974 Sam Stafford Partial fixes to the sorting of a FileLogCache as it's created.
  FileRevs are now doubly-linked. 
  FileHead now has a scanMain() function that acts as an interleaved
   scanFrom and scanInto.

The next step will be to have scans go from #1 to #head (this is
why FileRevs are now doubly linked).
#1 937 Sam Stafford Renaming my guest directory to the more conventional
sam_stafford.
//guest/samwise/p4hl/src/dlls/FileLogCache.cpp
#1 936 Sam Stafford Adding P4HL to the public depot.
 See relnotes.txt for
installation instructions; all relevant files are under
p4hl/dist.

Source code is under p4hl/src in the form of a VC++ project.