A few days ago I fired one of my programmers. It's one of the parts of my "job" that I could do without. Thankfully, I've only had to do it a few times. He's been with us quite a while, and although I was never quite happy with his work, there were alway extenuating circumstances and I kept hoping things would turn around. Eventually, I had to admit that it probably wasn't going to get any better.
It went about as well as these things can. No arguments, no tears. He actually admitted he really hadn't been very interested in the work. I hope he can find work that does motivate him. We all spend too much of our lives at work to waste it doing stuff we don't enjoy.
Despite being a partner in a small business with 40 employees I'm not much of a "business man" or manager. I've learnt enough to get by and I do as little as I can responsibly get away with. If it starts to take too much of my time I get unhappy. I'm still a programmer at heart, and if I spend a day at the office without writing a line of code I get grouchy. And no, answering coding questions and reviewing code doesn't count!
I'm lucky to have a partner who's happy (or at least willing) to look after the business and marketing and sales side. And lucky to have programmers (and a customer support team) who do a great job without a great manager.
Saturday, January 15, 2011
Sunday, January 09, 2011
I Give Up
I spoke too soon with my Hamcrest post. I was getting a clean compile and build, but when I ran the tests I got a security exception!
Based on what I found on the internet, this is because the hamcrest-core supplied by Eclipse is signed, but the hamcrest-library I downloaded separately isn't.
The suggested solutions is to make sure the unsigned one is first on the Eclipse build path. But mine was already first. I tried playing around with the order but it didn't help.
So I gave up and removed hamcrest-library. I'll just live with the matchers in the hamcrest-core supplied by Eclipse. I've wasted enough time and mental energy already.
Sometimes this stuff is just not as easy as it should be :-(
It's a good reminder of how much using Suneido simplifies life for my developers. (Not that they would agree that their life is simple!) The downside is that we don't have access to all these third party tools and libraries. But the huge upside is that we don't have to fight to integrate all those disparate pieces.
Based on what I found on the internet, this is because the hamcrest-core supplied by Eclipse is signed, but the hamcrest-library I downloaded separately isn't.
The suggested solutions is to make sure the unsigned one is first on the Eclipse build path. But mine was already first. I tried playing around with the order but it didn't help.
So I gave up and removed hamcrest-library. I'll just live with the matchers in the hamcrest-core supplied by Eclipse. I've wasted enough time and mental energy already.
Sometimes this stuff is just not as easy as it should be :-(
It's a good reminder of how much using Suneido simplifies life for my developers. (Not that they would agree that their life is simple!) The downside is that we don't have access to all these third party tools and libraries. But the huge upside is that we don't have to fight to integrate all those disparate pieces.
Saturday, January 08, 2011
Eclipse Hamcrest Runaround
I started reading Growing Object-Oriented Software and it talked about using the Hamcrest matchers with jUnit. It sounded like a good idea so the next time I was writing a test I tried using them.
The first problem is where to import assertThat from. That turned out to be easy, it's in org.junit.Assert along with the normal assertEquals etc.
The next question is where to import the matchers like equalTo. I found that in org.hamcrest.Matchers.
Next I wanted a lessThan matcher but I couldn't find it.
It turns out jUnit only includes Hamcrest core which doesn't have lessThan. I searched on the internet and didn't find a lot of help. I found a question on StackOverflow that suggested replacing the Eclipse supplied junit and hamcrest-core with junit-dep and hamcrest-all
I tried this and at first it seemed to work ok. But then I went to build my jars and Proguard gave all kinds of errors about missing dependencies.
I've been meaning to look into Maven and it's supposed to handle dependencies, so I thought I'd give it a try. Since I'm using Eclipse I looked for an Eclipse add-on for Maven. I found one and installed it. Big mistake. Not only did it not help with the dependency problems (at least I couldn't figure out how) but it also messed up my project. No problem, I thought, I'll just uninstall it. Except it left a mess behind. I ended up restoring my Eclipse install, but I still had problems. I kept getting errors referencing maven but I couldn't find any references to maven in my project. Eventually I found that the launch configurations for your project are stored in the workspace, not in the project. (That doesn't make much sense to me, but I'm sure there's some good reason.) After I deleted those (easier than trying to fix them) things were back to before the Maven detour.
It said I was missing jMock and EasyMock so I went and found those jars and added them. But it still wanted some kind of Ant jar. That seemed like a little much.
I saw there were various other jars for Hamcrest but frustratingly, no explanation of them. (I did find someone had filed an issue that there should be an explanation, but no one had responded.) I downloaded the complete package and it contained a readme that gave some explanation. It looked like I wanted hamcrest-core and hamcrest-library rather than hamcrest-all.
That eliminated the dependencies on jMock and EasyMock and Ant. But I still got an error that junit was referencing something that was missing from hamcrest. I thought maybe it was a version issue, so I tried multiple versions of junit and multiple versions of hamcrest but no luck.
Then I realized that the junit supplied by Eclipse includes hamcrest-core. So maybe all I needed to do was go back to that, and then add hamcrest-library. Sure enough, that did the trick.
No doubt the junit and hamcrest and eclipse folks would say, of course, it's obvious. But it sure wasn't obvious to me.
The first problem is where to import assertThat from. That turned out to be easy, it's in org.junit.Assert along with the normal assertEquals etc.
The next question is where to import the matchers like equalTo. I found that in org.hamcrest.Matchers.
Next I wanted a lessThan matcher but I couldn't find it.
It turns out jUnit only includes Hamcrest core which doesn't have lessThan. I searched on the internet and didn't find a lot of help. I found a question on StackOverflow that suggested replacing the Eclipse supplied junit and hamcrest-core with junit-dep and hamcrest-all
I tried this and at first it seemed to work ok. But then I went to build my jars and Proguard gave all kinds of errors about missing dependencies.
I've been meaning to look into Maven and it's supposed to handle dependencies, so I thought I'd give it a try. Since I'm using Eclipse I looked for an Eclipse add-on for Maven. I found one and installed it. Big mistake. Not only did it not help with the dependency problems (at least I couldn't figure out how) but it also messed up my project. No problem, I thought, I'll just uninstall it. Except it left a mess behind. I ended up restoring my Eclipse install, but I still had problems. I kept getting errors referencing maven but I couldn't find any references to maven in my project. Eventually I found that the launch configurations for your project are stored in the workspace, not in the project. (That doesn't make much sense to me, but I'm sure there's some good reason.) After I deleted those (easier than trying to fix them) things were back to before the Maven detour.
It said I was missing jMock and EasyMock so I went and found those jars and added them. But it still wanted some kind of Ant jar. That seemed like a little much.
I saw there were various other jars for Hamcrest but frustratingly, no explanation of them. (I did find someone had filed an issue that there should be an explanation, but no one had responded.) I downloaded the complete package and it contained a readme that gave some explanation. It looked like I wanted hamcrest-core and hamcrest-library rather than hamcrest-all.
That eliminated the dependencies on jMock and EasyMock and Ant. But I still got an error that junit was referencing something that was missing from hamcrest. I thought maybe it was a version issue, so I tried multiple versions of junit and multiple versions of hamcrest but no luck.
Then I realized that the junit supplied by Eclipse includes hamcrest-core. So maybe all I needed to do was go back to that, and then add hamcrest-library. Sure enough, that did the trick.
No doubt the junit and hamcrest and eclipse folks would say, of course, it's obvious. But it sure wasn't obvious to me.
jSuneido Immutable Database
I've made a good start on rewriting the jSuneido database as an immutable persistent data structure.
It's hard to know what to call it. Overall, it's not immutable, since you can add, update, and delete like any database. The "immutable" part is that once data is written to the database file it's never updated.
You could call it "append only" because you only ever append to the database file, never update. But again, that sounds like you can't update or delete, which you can.
I started bottom up, writing a persistent hash trie to store the redirections. This is similar to my persistent hash map but designed to be stored in the database file. I also rewrote my memory mapped file access, simplifying it a lot. Now I'm working on the btree code.
The code seems a lot cleaner this time. Of course, it always does at the beginning of a rewrite because you haven't handled all the details yet. But I'm still optimistic.
As usual I'm struggling with how much to optimize. The conventional wisdom is that you write the code and then if it's too slow you profile it and optimize the problem areas. But what is "too slow" in a language or a database? You always want as much speed as you can get (without sacrificing robustness and maintainability). And that wisdom assumes that speed problems will be localized. But if the slowness is spread diffusely through the code, then it's not so easy to optimize after the fact. It's a bit like saying you can add good design after the fact.
A big part of performance is the right algorithms. Another part is implementing those algorithms efficiently on your platform. If I can "cut with the grain" of Java I think I can do more with less.
I have a lot better handle on Java and the JVM than I did when I did the first implementation. And at that point I was simply trying to port the cSuneido code, not redesign it. Now that I have a working implementation I have the freedom to explore alternatives. And I'll have something to compare performance to.
It won't be till I get to the transaction code that I'll really see how this redesign will work out. I'm hoping that the immutability of the database will simplify transaction handling. We'll see.
It's hard to know what to call it. Overall, it's not immutable, since you can add, update, and delete like any database. The "immutable" part is that once data is written to the database file it's never updated.
You could call it "append only" because you only ever append to the database file, never update. But again, that sounds like you can't update or delete, which you can.
I started bottom up, writing a persistent hash trie to store the redirections. This is similar to my persistent hash map but designed to be stored in the database file. I also rewrote my memory mapped file access, simplifying it a lot. Now I'm working on the btree code.
The code seems a lot cleaner this time. Of course, it always does at the beginning of a rewrite because you haven't handled all the details yet. But I'm still optimistic.
As usual I'm struggling with how much to optimize. The conventional wisdom is that you write the code and then if it's too slow you profile it and optimize the problem areas. But what is "too slow" in a language or a database? You always want as much speed as you can get (without sacrificing robustness and maintainability). And that wisdom assumes that speed problems will be localized. But if the slowness is spread diffusely through the code, then it's not so easy to optimize after the fact. It's a bit like saying you can add good design after the fact.
A big part of performance is the right algorithms. Another part is implementing those algorithms efficiently on your platform. If I can "cut with the grain" of Java I think I can do more with less.
I have a lot better handle on Java and the JVM than I did when I did the first implementation. And at that point I was simply trying to port the cSuneido code, not redesign it. Now that I have a working implementation I have the freedom to explore alternatives. And I'll have something to compare performance to.
It won't be till I get to the transaction code that I'll really see how this redesign will work out. I'm hoping that the immutability of the database will simplify transaction handling. We'll see.
Subscribe to:
Posts (Atom)