Ubuntu Lucid Lynx and the Wallowing Walrus

I have a fairly old computer that I use as a sort-of server at home.  P4, 3GHz, 1GB RAM, 120GB HDD.  I have Ubuntu installed, and just upgraded to 10.04 LTS.

I installed VMWare Server 2.02 a year ago, to allow a Windows XP instance to run a copy of Pastel Accounting, used by my wife’s company.  Unfortunately VMWare has to be manually patched to install in Ubuntu, and it’s been like that for a long time.  And after each kernel update, it has to be recompiled.  That is, however, not the biggest problem.  It’s the swapping of memory.

1GB of RAM is not really enough for a Gnome desktop and Windows XP.  A 1.6GB swap partition was in order, but strangely enough, the system has become less and responsive.  On inspection it seems that the swapping is slowing things down to a crawl at times.

I tried moving the swap partition a new USB flash drive.  Initially it work really well.  The flash drive is substantially faster than the hard drive, so performance must have increased 10 fold.  Then the flash drive get corrupted and things fell apart completely.

So I investigated swapd.  I figured since the swap partition was at the end of the drive, the head movement across the disk was slowing thing down too much. Put the info is pretty vague and I haven’t taken the time to figure out if it would be worthwhile tweaking Ubuntu to only use swapd and not have a dedicated swap partition. Furthermore, there is no guarantee that VM-Ware will use it correctly, so I opted for another approach.

Somewhere it was suggested that in a one hard drive setup, the best place for the swapfile should be in the middle of the disk. So I made three partitions with the swap partition being the second or middle one. The logic is that the head moves over that part of the disk frequently between the data (part 3) and the system partition (part 1), so having swap there, makes it accessible in the fastest manner.

So far so good. The machine does not imitate the Wallowing Walrus any more.

From experiences in the database world I know that having data spread over many spindles allows increased concurrent access and speeds things up tremendously, so here, without extra hard disk spindles, is a way to speed up access by placing the data where the disk head on average needs to travel the least distance to write or read swapped memory.

… and one day, hopefully sooner than later, I’ll replace the machine with a new AMD 6 core Phenom or Intel I5 or i7 based system with lots of RAM and a few hard disks!

Creating a SQL Proper Case (propercase) user function

I’m working on a database project and had to revisit a user function that I had created a long time ago.  After evaluation the various changes and having a look at code from Tim Raster here and more from Richard McCutchen aka PsycoCoder here, I decided to combine the various features in my own code.

The code below features conversion of a string, with or without spaces and punctuation marks, to proper case.

It also understands how to spell MacIntosh, MacDonalds, et al, and features an exception list which prevents names like Maces to be written as MacEs.

The code below can be pasted straight into a SQL Code window (SQL 2008 Management Studio or and older version) to create the user defined function.

-- ==============================================
-- Author:         Roland Giesler
-- Create date:    3 May 2010
-- Description:    Change a string to proper case
-- ==============================================
 CREATE FUNCTION Proper(@value VARCHAR(8000))
    DECLARE @MAC_EXCEPTIONS varchar(255), @APPENDICES varchar(50), @final  VARCHAR(8000), @MyLoop int, @CharToFind varchar(1)
    -- set the Mac exeptions
    SET @MAC_EXCEPTIONS = ',Maceo,Mackinac,Mackinac  Island,Mackinaw,Mackinaw City,Macks Creek,Macks  Inn,Macom,Macomb,Macombtownship,Macon,Macy' 

    --set the initial string to lowercase and append the first separator to  be searched for
    -- this prevents a "not found" condition when searching for the first  separator
    -- and returns the whole input string unchanged when the separator is  not present in the original @value
    SET @value = LOWER(@value) + '/'
    --set the final result variable to the same as @value
    -- This is done to accomodate the loop set statements in the main loop
    SET @final = @value

    -- Repeat the whole procedure for each separator list below
    SET @MyLoop = 0
    WHILE @MyLoop < 4
       BEGIN -- Main Loop
       SET @MyLoop = @MyLoop + 1
       SET @CharToFind =
          CASE @MyLoop
             WHEN 1 THEN '/'
             WHEN 2 THEN '-'
             WHEN 3 THEN ''''
             WHEN 4 THEN ' ' -- space has to be last, to have it auto removed at ***
       --set the working string to the result of the previous pass
       -- strip the appended previous separator and add the current one
       SET @value = LEFT(@final,LEN(@final)-1) + @CharToFind
       --set the final result variable to empty
       SET @final = ''

       --this ensures a loop
       WHILE 1=1
          --check if "mac" appears just after a separator AND
          --the string does not appear in the MAC_EXCEPTIONS with or without  trailing punctuation
          -- TO DO:
          -- NOTE: This caters for only one character like and "!" for example  trailing after the "mac" word.
          -- A beter way would be to strip all characters in a predefined  punctuation list and then lookup the
          -- word in @MAC_EXCEPTIONS.
          IF PATINDEX('%mac%',@value) = 1 AND  CHARINDEX(SUBSTRING(@value,1,CHARINDEX(@CharToFind,@value)-1),@MAC_EXCEPTIONS)  = 0 AND  CHARINDEX(SUBSTRING(@value,1,CHARINDEX(@CharToFind,@value)-2),@MAC_EXCEPTIONS)  = 0
             SET @final = @final + 'Mac' + UPPER(SUBSTRING(@value,4,1)) +  SUBSTRING(@value,5,CHARINDEX(@CharToFind,@value)-4)

          --check if "mc" appears just after a separator AND
          --the string does not appear in the MAC_EXCEPTIONS with or without  trailing punctuation
             IF PATINDEX('%mc%',@value) = 1 AND  CHARINDEX(SUBSTRING(@value,1,CHARINDEX(@CharToFind,@value)-1),@MAC_EXCEPTIONS)  = 0 AND  CHARINDEX(SUBSTRING(@value,1,CHARINDEX(@CharToFind,@value)-2),@MAC_EXCEPTIONS)  = 0
                SET @final = @final + 'Mc' + UPPER(SUBSTRING(@value,3,1)) +  SUBSTRING(@value,4,CHARINDEX(@CharToFind,@value)-3)
             --if there are no more separators then exit the loop
                IF PATINDEX('%'+@CharToFind+'%',@value) = 0
                   --now we loop through each character and uppercase letters after a  separator
                   --or at the beginning of the string
                   SET @final = @final + UPPER(LEFT(@value,1)) +  SUBSTRING(@value,2,CHARINDEX(@CharToFind,@value)-1)
          SET @value =  SUBSTRING(@value,CHARINDEX(@CharToFind,@value)+1,LEN(@value))
    END -- Main Loop
 -- *** The LEN function seems to ignore trailing spaces, so we don't  have to remove the last space
 SET @final = LEFT(@final,LEN(@final))
 --return the final string
 RETURN @final

 --Sample Usage
 -- SELECT dbo.Proper('mAke tHIS PRopER-CASE, MacKinaW!')