Archive for February, 2011

Gotta Be Careful With Static Instance Variables

Monday, February 7th, 2011

bug.gif

Today I got nailed by my own laziness - no two ways about it. I had built these pools of data containers - one was for simple time/date-stamped (char *) UDP datagrams, and the other was for std::string * containers. They were both similar in their execution - a single-consumer/single-producer lockless FIFO queue that would act as the pool, and a few methods that would return the next unused one, and recycle one into the pool (or delete it) based on the capacity of the pool.

Simple stuff, really. The problem was that I got a little lazy and made the alloc() and recycle() methods static methods with the actual pool a static ivar of the class. Bad idea.

When I started to use these pools in one of my servers that happened to use about 30 UDP exchange feeds, there was only the one static pool, and it wasn't a single-producer/single-consumer any more. Bad move.

The solution was simple - don't use the static ivar and don't cut corners. I made the pool a class, put the alloc() and recycle() on the class, had the UDP exchange feeds each have a pool, and all was well again. This was pretty easy for the string pool, but took just a little longer for the tagged datagrams. Still, not too bad.

In the end, I solved my nasty data problems because I went back to clean data container streams. Good enough.

When Getting “Help” is the Last Thing I Need

Monday, February 7th, 2011

I've written a replacement to an exchange data feed and now I'm trying to work with a few groups to see if it'll work for them. The original intention was not to include them, so if it works for them, so much the better. Still, I've expected more than a little resistance because these are developers that have clearly stated that they do not want this new exchange feed - that the one they have is just fine, thank you. I understand their position - I'm new, they don't want to change. They fear what might happen, so it's easiest to simply drag their feet or poke holes in the project to say why they can't use it.

This is easily solved in one of three ways: fire people, force people, or give up. I'm not in a position to do any of these, but if I had my choice, I think I'd favor the ultimatum angle: force, then fire. This industry is paid far too well to put up with unnecessary crud from prima donnas thinking they know better.

Be that as it may... something struck me as quite odd, and made me lean towards the "firing" angle for one developer when he mentioned today that he took my code, replaced spinlocks with pthread locks and saw an amazing jump in performance. That makes no sense, as I moved from pthreads to spinlocks long ago for this exact reason. Still, I was willing to say I'd try it.

And I did.

Amazing. I got literally thousands of messages a second less using pthreads than using spinlocks - exactly what I expected. So much for the brilliant developer that thinks he's found the silver bullet to all problems.

Yup. For that developer, I'd give them a nice severance bonus and show them the door. Being reluctant is one thing. Being a bad developer is another.

It’s Amazing Where a Week Goes

Saturday, February 5th, 2011

cubeLifeView.gif

This week has gone very fast. I haven't been able to really even keep up on what's happening day-to-day here. The middle of the week was a blur with the work on the infix-to-prefix parser, and a ton of help to some folks trying to use my ticker plants at The Shop. Given that they aren't really excited about the change, I'm really not at all shocked that they are being a bit high maintenance about this.

So it goes... but the fact of the matter was that I was feverishly trying to add and fix things for them while trying to get the infix parser working while trying to get home at reasonable hours. It's a job, and I knew there were going to be days like this, but it was a real trial.

One of the real kickers that happened was that my manager gave me a bit of a scare when he pointed out that the reputation of my work was a very big deal. The way The Shop deals with bonuses and such is just a reality of life that we have to deal with. No two ways about it.

So I'm going to have to push harder, and that means I'm liable to step on a few toes. But I'm going to be very up-front about it, and let the management know what I'm doing and why. But in the end, it's going to get a little more uncomfortable for those that are dragging their feet.

So it goes... I've been more than a little uncomfortable this week for sure.

Slick Infix to Prefix Algorithm

Friday, February 4th, 2011

I've been slugging out this idea of infix to prefix conversion and this afternoon I finally cracked it. Well, to be fair, I cracked it on paper this morning and I got it all coded up this afternoon. This comes about because the lisp-like language that I put together for a project at The Shop would require that all arithmetic expressions be written in prefix. Seems obvious, but a lot of the users weren't really excited about the difficulties in putting together prefix expressions.

They seem to be pretty content to say:

  (and (condition 1)
       (condition 2)
       (condition 3))

as they like the short-hand it gives them, but when they need to do something with more than simple addition, like, say the quadratic equation, then things get a little more difficult, and they start to get confused:

  (set a 1)
  (set b -7)
  (set c 12)
  (set x1 (/ (+ (-b) (sqrt (- (* b b) (* 4 a c)))) (* 2 a)))
  (set x2 (/ (- (-b) (sqrt (- (* b b) (* 4 a c)))) (* 2 a)))

and while I can agree it's not trivial, the infix representation isn't all that easy, either:

  (set x1 (/ ((-b) + (sqrt (b * b - 4 * a * c)))/(2 * a)))
  (set x2 (/ ((-b) - (sqrt (b * b - 4 * a * c)))/(2 * a)))

But they wanted infix in their math expressions. But not pure infix - just selective infix to make decoding as hard as possible. In short, any expression (a section of code enclosed in parentheses) can be either prefix or infix, and it's up to the script parser to figure out which it is, and act accordingly.

Oh... and they also didn't like the required spaces.

This lead to something like this:

  (set x1 (/ ((-b) + (sqrt (b*b - 4*a*c))) (* 2 a)))
  (set x2 (/ ((-b) - (sqrt (b*b - 4*a*c))) (* 2 a)))

where there is infix in parts and prefix in other parts. Not ideal, to be sure, but it's the users that want this, so we need to find some way to make it happen.

Getting the Easy Stuff First

The easy stuff was missing spaces and operator ordering. The missing spaces simply meant that I had to have foreknowledge of the different operators that I could run into, and use them as separators. Not hard, but it was more time-consuming on the parsing, and made the code quite a bit uglier. Still, it was easy to make:

  (*5 2)

return 10.

The next easy one was the operator order. If you have:

  (10 = (* 5 2))

it's easy to see that the first token is not an operator, and to put the first token as the first argument to the expression. When you hit the second argument, it is an operator, and can be put in that place in the expression. In fact, it's easy to say:

  (10 5 3 2 1 *)

as there's only one operator in the mix.

Only slightly harder is to ignore duplicated operators:

  (10 + 5 + 3 + 2 + 1)

for I can look at the first operator for the expression, and if the next operator in the expression is the same, I just ignore it. We're getting pretty far, actually.

The last easy one was putting expressions before operators, but I already had that with the numbers before operators, so we get for free:

  ((5*2) = (2+2+2+2+2))

Now for the Hard Stuff

In truth, all that stuff only took me about an hour to figure out. The hard part is operator precedence. I struggled with operator precedence for several days until I happened to some across an idea stewing in my head. The basic problem is that I did not want to have a multi-pass parser where the first pass tokenizes the expression, the next orders the tokens based on their operator precedence, the next creates the prefix mode, the next makes the evaluation tree, etc. It's not hard to see that a multi-pass parser is a very good way to go, but I'd already put so much effort into my parser (it's a single-pass), that I didn't want to throw all that away if I didn't have to.

All I needed was to come up with a way to handle the operator precedence and I was golden. But it was a pain to come up with. In the end, I had something that worked, and it seemed to be pretty solid. I had a stack of expressions I was parsing into. I started with the top-level expression, and then when I hit a different operator of greater precedence, you pull the last argument off the expression, make a new expression, and put the new operator and argument in the new expression.

It's not really easy to see, and I'm not convinced that it's any really easier than a multi-pass parser, but it works. The reverse is to see the different, looser-binding operator, and enclose the expression in another expression and use the looser operator as the new 'main' operator. Again, not easy to see, but it's working and that's what really matters.

I'm ready to get on to something else.

VoodooPad 4.3.2 is Out

Friday, February 4th, 2011

This afternoon I saw a tweet that VoodooPad 4.3.2 was out, so I hopped right on that. The release notes are nice, but I also noticed that it's getting ready for the Mac App Store as it's now signed by Apple, which is a nice touch, I suppose.

I haven't had any problems with this guy, but it's nice to see the progress anyway.

Google Chrome dev 10.0.648.18 is Out

Friday, February 4th, 2011

This morning the Google Chrome team released 10.0.648.18 with a nice list of changes - including the latest version of their V8 javascript engine - 3.0.12.8. There were also a few Mac-specific fixes, and that's great, but they still have that new preferences 'page' that you can't resize the left-hand selector. Very odd, and even annoying as it's so bloody large.

So it goes... can't have it all, I suppose.

LaunchBar 5.0.4 is Out

Friday, February 4th, 2011

This is something you don't see even every month... LaunchBar 5.0.4 is out, and with an amazingly spare list of updates. It's just a solid app that I use every single day and deserves the kudos for being so solid and dependable that it's almost invisible. Amazing stuff.

Under Water with Reluctant Users and Infix Syntax (cont.)

Thursday, February 3rd, 2011

Today was a nasty nightmarish continuation of yesterday. I got a lot of stuff done, but I felt I was always a set behind. It'll change, I know, but while I'm in this "plate catching" phase it's not nearly as fun as it has been... or could be... or will be.

Under Water with Reluctant Users and Infix Syntax

Wednesday, February 2nd, 2011

Today I was totally under water with trying to get some reluctant developers using my exchange feeds and trying to get a new feature into my lisp-like parser: infix notation. I spent all day on these things and never had time to come up for air.

What a day.

Google Chrome dev 10.0.648.11 is Out

Tuesday, February 1st, 2011

GoogleChrome.jpg

This morning I saw that Google Chrome dev 10.0.648.11 is out, and the release notes indicate that it's really about bug fixes and enhancements to the new preferences pane. It's not a horrible idea - to make a cross-platform preferences pane, but it's going to be unlike every other preferences system the user is used to - on any platform.

Sure, most will get used to it, but I don't understand the need to have such a "one size fits all" attitude to software. The basic browser is cross-platform, but there's no reason to make every keystroke and button the same. Oh well... that's Google.