Check-in [c1c3fa70b5]
Overview
Comment:Optimized path name lookup
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: c1c3fa70b5c7d0ea86acb9b8db5229fc8965d926ef4cec73f23ee8e251554629
User & Date: rkeene on 2019-09-17 21:35:39.089
Other Links: manifest | tags
Context
2019-09-17
21:39
Cause a negative threshold to be really high check-in: 3c48891a32 user: rkeene tags: trunk
21:35
Optimized path name lookup check-in: c1c3fa70b5 user: rkeene tags: trunk
20:43
Fixed issue where coverage files were not cleaned up and ignored check-in: 2f92a3a715 user: rkeene tags: trunk
Changes
35
36
37
38
39
40
41





42










43
44


















45
46


47
48
49
50
51
52
53
54

55
56
57
58
59
60

61
62
63


64
65
66
67
68
69
70













71


72
73
74

75
76
77
78
79
80
81
82
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77


78
79
80
81
82
83
84
85


86
87





88



89
90
91






92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

110

111
112
113
114
115
116
117







+
+
+
+
+

+
+
+
+
+
+
+
+
+
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+






-
-
+

-
-
-
-
-
+
-
-
-
+
+

-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+


-
+
-







		const unsigned char *fileContents;
		const char          **dirChildren;
	} data;
};

<?
	package require xvfs

	set ::xvfs::hashNameThreshold 3
	if {[info exists ::env(XVFS_CREATE_HASH_NAME_THRESHOLD)]} {
		set ::xvfs::hashNameThreshold $::env(XVFS_CREATE_HASH_NAME_THRESHOLD)
	}
	xvfs::main $argv

	proc emitFilenameVerification {indentLevel outputFileNameLen outputFileIndexes} {
		set indent [string repeat "\t" $indentLevel]
		foreach outputFileIndex $outputFileIndexes {
?><?= $indent ?>if (memcmp(path, xvfs_<?= $::xvfs::fsName ?>_data[<?= $outputFileIndex ?>].name, <?= $outputFileNameLen ?>) == 0) {
<?= $indent ?>	return(<?= $outputFileIndex ?>);
<?= $indent ?>}
<?
		}
	}
?>
static long xvfs_<?= $::xvfs::fsName ?>_nameToIndex(const char *path) {
<?
	for {set index 0} {$index < [llength $::xvfs::outputFiles]} {incr index} {
		set outputFileName [lindex $::xvfs::outputFiles $index]
		set outputFileNameLen [string length $outputFileName]
		set outputFileNameHash [zlib adler32 $outputFileName 0]
		lappend outputFileNameHashToIndex([list $outputFileNameLen $outputFileNameHash]) $index
		lappend outputFileNameLenToIndex($outputFileNameLen) $index
	}

	set needZlib false
	foreach {outputFileNameLen outputFileIndexes} [lsort -stride 2 -dictionary [array get outputFileNameLenToIndex]] {
		if {[llength $outputFileIndexes] > $::xvfs::hashNameThreshold} {
			set needZlib true
			break;
		}
	}
?><?
	if {$needZlib} {
	unsigned int pathHash;
	size_t pathLen;
?>	unsigned int pathHash;
<?	} ?>	size_t pathLen;
	
	if (path == NULL) {
		return(XVFS_NAME_LOOKUP_ERROR);
	}

	pathLen = strlen(path);
	pathHash = Tcl_ZlibAdler32(0, (const unsigned char *) path, pathLen);
	switch (pathHash) {
	switch (pathLen) {
<?
	for {set index 0} {$index < [llength $::xvfs::outputFiles]} {incr index} {
		set outputFile [lindex $::xvfs::outputFiles $index]
		set outputFileHash [zlib adler32 $outputFile 0]
		lappend outputFileHashToIndex($outputFileHash) $index
	}

	
	foreach {outputFileHash outputFileIndexes} [lsort -stride 2 -dictionary [array get outputFileHashToIndex]] {
?>		case <?= $outputFileHash ?>:
	foreach {outputFileNameLen outputFileIndexes} [lsort -stride 2 -dictionary [array get outputFileNameLenToIndex]] {
?>		case <?= $outputFileNameLen ?>:
<?
			foreach outputFileIndex $outputFileIndexes {
				set outputFileName [lindex $::xvfs::outputFiles $outputFileIndex]
				set outputFileNameLen [string length $outputFileName]
?>			if (pathLen == <?= $outputFileNameLen ?> && memcmp(path, xvfs_<?= $::xvfs::fsName ?>_data[<?= $outputFileIndex ?>].name, pathLen) == 0) {
				return(<?= $outputFileIndex ?>);
			}
			if {[llength $outputFileIndexes] > $::xvfs::hashNameThreshold} {
?>			pathHash = Tcl_ZlibAdler32(0, (const unsigned char *) path, <?= $outputFileNameLen ?>);
			switch (pathHash) {
<?
				foreach {key outputFileIndexes} [lsort -stride 2 -dictionary [array get outputFileNameHashToIndex [list $outputFileNameLen *]]] {
					set outputFileNameHash [lindex $key 1]
?>				case <?= $outputFileNameHash ?>:
<?
					emitFilenameVerification 5 $outputFileNameLen $outputFileIndexes
?>					break;	
<?
				}
?>			}
<?
			} else {
				emitFilenameVerification 3 $outputFileNameLen $outputFileIndexes
			}
?>			break;
<?	} ?>
<?	} ?>	}
	}
	
	return(XVFS_NAME_LOOKUP_ERROR);
}

static const char **xvfs_<?= $::xvfs::fsName ?>_getChildren(const char *path, Tcl_WideInt *count) {
	struct xvfs_file_data *fileInfo;
	long inode;