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;