src/lib/udc.c 1.12
1.12 2009/02/13 02:39:05 kent
Removed flocks which seem to be unneeded. Adding qEncoding to make directory names easier to pursue under Unix.
Index: src/lib/udc.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/lib/udc.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -b -B -U 4 -r1.11 -r1.12
--- src/lib/udc.c 11 Feb 2009 23:44:11 -0000 1.11
+++ src/lib/udc.c 13 Feb 2009 02:39:05 -0000 1.12
@@ -507,26 +507,48 @@
udcBitmapClose(&bits);
}
-static char *cgiEncodeExceptDirs(char *input)
-/* CGI-encode every char in input except for the / chars. */
+static boolean qEscaped(char c)
+/* Returns TRUE if character needs to be escaped in q-encoding. */
{
-struct dyString *dy = dyStringNew(strlen(input)+16);
-char *s, *e;
+if (isalnum(c))
+ return c == 'Q';
+else
+ return c != '_' && c != '-' && c != '/' && c != '.';
+}
-for (s = input; s != NULL; s = e)
+static char *qEncode(char *input)
+/* Do a simple encoding to convert input string into "normal" characters.
+ * Abnormal letters, and '!' get converted into Q followed by two hexadecimal digits. */
+{
+/* First go through and figure out encoded size. */
+int size = 0;
+char *s, *d, c;
+s = input;
+while ((c = *s++) != 0)
{
- e = strchr(s, '/');
- if (e != NULL)
- *e++ = 0;
- char *encoded = cgiEncode(s);
- dyStringAppend(dy, encoded);
- if (e != NULL)
- dyStringAppendC(dy, '/');
- freeMem(encoded);
+ if (qEscaped(c))
+ size += 3;
+ else
+ size += 1;
}
-return dyStringCannibalize(&dy);
+
+/* Allocate and fill in output. */
+char *output = needMem(size+1);
+s = input;
+d = output;
+while ((c = *s++) != 0)
+ {
+ if (qEscaped(c))
+ {
+ sprintf(d, "Q%02X", (unsigned)c);
+ d += 3;
+ }
+ else
+ *d++ = c;
+ }
+return output;
}
struct udcFile *udcFileMayOpen(char *url, char *cacheDir)
/* Open up a cached file. Return NULL if file doesn't exist. */
@@ -543,9 +565,9 @@
protocol = cloneStringZ(url, colonPos);
afterProtocol = url + colonPos + 1;
while (afterProtocol[0] == '/')
afterProtocol += 1;
- afterProtocol = cgiEncodeExceptDirs(afterProtocol);
+ afterProtocol = qEncode(afterProtocol);
}
else
{
protocol = cloneString("transparent");
@@ -636,9 +658,9 @@
/* Do some bit-to-byte offset conversions and read in all the bytes that
* have information in the bits we're interested in. */
{
int byteStart = bitStart/8;
-int byteEnd = (bitEnd+7)/8;
+int byteEnd = bitToByteSize(bitEnd);
int byteSize = byteEnd - byteStart;
Bits *bits = needLargeMem(byteSize);
fseek(f, headerSize + byteStart, SEEK_SET);
mustRead(f, bits, byteSize);
@@ -705,13 +727,10 @@
break;
int nextSetBit = bitFindSet(b, nextClearBit, e);
int clearSize = nextSetBit - nextClearBit;
- int lockErr = flock(fileno(bits->f), LOCK_EX);
- /* TODO: update bitmap file as well as in memory. */
fetchMissingBlocks(file, bits, nextClearBit + partOffset, clearSize, bits->blockSize);
bitSetRange(b, nextClearBit, clearSize);
- lockErr = flock(fileno(bits->f), LOCK_UN);
dirty = TRUE;
if (nextSetBit >= e)
break;
@@ -721,9 +740,9 @@
if (dirty)
{
/* Update bitmap on disk.... */
int byteStart = startBlock/8;
- int byteEnd = (endBlock+7)/8;
+ int byteEnd = bitToByteSize(endBlock);
int byteSize = byteEnd - byteStart;
fseek(bits->f, byteStart + udcBitmapHeaderSize, SEEK_SET);
mustWrite(bits->f, b, byteSize);
}
@@ -782,13 +801,9 @@
struct udcBitmap *bits = udcBitmapOpen(file->bitmapFileName);
if (bits->version == file->bitmapVersion)
{
if (!udcCacheContains(file, bits, s, e-s))
- {
- int lockErr = flock(fileno(bits->f), LOCK_EX);
udcFetchMissing(file, bits, s, e);
- lockErr = flock(fileno(bits->f), LOCK_UN);
- }
}
else
{
ok = FALSE;
@@ -822,8 +837,11 @@
{
verbose(2, "udcCachePreload failed");
return 0;
}
+ /* Currently only need fseek here. Would be safer, but possibly
+ * slower to move fseek so it is always executed in front of read, in
+ * case other code is moving around file pointer. */
fseek(file->fSparse, start, SEEK_SET);
}
mustRead(file->fSparse, buf, size);
file->offset += size;
@@ -890,11 +908,9 @@
{
return file->offset;
}
- off_t size; /* Size in bytes. */
-
-bits64 rCleanup(time_t deleteTime, boolean testOnly)
+static bits64 rCleanup(time_t deleteTime, boolean testOnly)
/* Delete any bitmap or sparseData files last accessed before deleteTime */
{
struct fileInfo *file, *fileList = listDirX(".", "*", FALSE);
bits64 results = 0;