Oren Eini

aka Ayende Rahien

Oren Eini

CEO of RavenDB

a NoSQL Open Source Document Database

Get in touch with me:

oren@ravendb.net +972 52-548-6969

Posts: 7,575
|
Comments: 51,194

Copyright ©️ Ayende Rahien 2004 — 2025

Privacy Policy · Terms
filter by tags archive
stack view grid view
  • architecture (606) rss
  • bugs (450) rss
  • challanges (123) rss
  • community (377) rss
  • databases (481) rss
  • design (893) rss
  • development (640) rss
  • hibernating-practices (71) rss
  • miscellaneous (592) rss
  • performance (397) rss
  • programming (1085) rss
  • raven (1442) rss
  • ravendb.net (526) rss
  • reviews (184) rss
  • 2025
    • May (7)
    • April (10)
    • March (10)
    • February (7)
    • January (12)
  • 2024
    • December (3)
    • November (2)
    • October (1)
    • September (3)
    • August (5)
    • July (10)
    • June (4)
    • May (6)
    • April (2)
    • March (8)
    • February (2)
    • January (14)
  • 2023
    • December (4)
    • October (4)
    • September (6)
    • August (12)
    • July (5)
    • June (15)
    • May (3)
    • April (11)
    • March (5)
    • February (5)
    • January (8)
  • 2022
    • December (5)
    • November (7)
    • October (7)
    • September (9)
    • August (10)
    • July (15)
    • June (12)
    • May (9)
    • April (14)
    • March (15)
    • February (13)
    • January (16)
  • 2021
    • December (23)
    • November (20)
    • October (16)
    • September (6)
    • August (16)
    • July (11)
    • June (16)
    • May (4)
    • April (10)
    • March (11)
    • February (15)
    • January (14)
  • 2020
    • December (10)
    • November (13)
    • October (15)
    • September (6)
    • August (9)
    • July (9)
    • June (17)
    • May (15)
    • April (14)
    • March (21)
    • February (16)
    • January (13)
  • 2019
    • December (17)
    • November (14)
    • October (16)
    • September (10)
    • August (8)
    • July (16)
    • June (11)
    • May (13)
    • April (18)
    • March (12)
    • February (19)
    • January (23)
  • 2018
    • December (15)
    • November (14)
    • October (19)
    • September (18)
    • August (23)
    • July (20)
    • June (20)
    • May (23)
    • April (15)
    • March (23)
    • February (19)
    • January (23)
  • 2017
    • December (21)
    • November (24)
    • October (22)
    • September (21)
    • August (23)
    • July (21)
    • June (24)
    • May (21)
    • April (21)
    • March (23)
    • February (20)
    • January (23)
  • 2016
    • December (17)
    • November (18)
    • October (22)
    • September (18)
    • August (23)
    • July (22)
    • June (17)
    • May (24)
    • April (16)
    • March (16)
    • February (21)
    • January (21)
  • 2015
    • December (5)
    • November (10)
    • October (9)
    • September (17)
    • August (20)
    • July (17)
    • June (4)
    • May (12)
    • April (9)
    • March (8)
    • February (25)
    • January (17)
  • 2014
    • December (22)
    • November (19)
    • October (21)
    • September (37)
    • August (24)
    • July (23)
    • June (13)
    • May (19)
    • April (24)
    • March (23)
    • February (21)
    • January (24)
  • 2013
    • December (23)
    • November (29)
    • October (27)
    • September (26)
    • August (24)
    • July (24)
    • June (23)
    • May (25)
    • April (26)
    • March (24)
    • February (24)
    • January (21)
  • 2012
    • December (19)
    • November (22)
    • October (27)
    • September (24)
    • August (30)
    • July (23)
    • June (25)
    • May (23)
    • April (25)
    • March (25)
    • February (28)
    • January (24)
  • 2011
    • December (17)
    • November (14)
    • October (24)
    • September (28)
    • August (27)
    • July (30)
    • June (19)
    • May (16)
    • April (30)
    • March (23)
    • February (11)
    • January (26)
  • 2010
    • December (29)
    • November (28)
    • October (35)
    • September (33)
    • August (44)
    • July (17)
    • June (20)
    • May (53)
    • April (29)
    • March (35)
    • February (33)
    • January (36)
  • 2009
    • December (37)
    • November (35)
    • October (53)
    • September (60)
    • August (66)
    • July (29)
    • June (24)
    • May (52)
    • April (63)
    • March (35)
    • February (53)
    • January (50)
  • 2008
    • December (58)
    • November (65)
    • October (46)
    • September (48)
    • August (96)
    • July (87)
    • June (45)
    • May (51)
    • April (52)
    • March (70)
    • February (43)
    • January (49)
  • 2007
    • December (100)
    • November (52)
    • October (109)
    • September (68)
    • August (80)
    • July (56)
    • June (150)
    • May (115)
    • April (73)
    • March (124)
    • February (102)
    • January (68)
  • 2006
    • December (95)
    • November (53)
    • October (120)
    • September (57)
    • August (88)
    • July (54)
    • June (103)
    • May (89)
    • April (84)
    • March (143)
    • February (78)
    • January (64)
  • 2005
    • December (70)
    • November (97)
    • October (91)
    • September (61)
    • August (74)
    • July (92)
    • June (100)
    • May (53)
    • April (42)
    • March (41)
    • February (84)
    • January (31)
  • 2004
    • December (49)
    • November (26)
    • October (26)
    • September (6)
    • April (10)
Deep Dive into RavenDB webinars
  previous post next post  
Jul 11 2010

Find the issue

time to read 1 min | 87 words

There is a design issue that is revealed in the following tests, can you figure out why I changed the behavior and removed the tests?

image

image

image

Tweet Share Share 15 comments

  previous post next post  

Comments

Ryan Schipper
11 Jul 2010
07:52 AM
Ryan Schipper

A couple of things that need consideration in my opinion.

1) in my opinion it is inappropriate to force your API consumer to use exception handlers for normal process flow as demonstrated in the first few tests

2) a dictionary is a reasonably established paradigm and standard practice (at least where I come from) would suggest that the add function should be add(key, value). Instead, you have an explicitly required container class.

One of these may even be what you are thinking of..

Anon
11 Jul 2010
08:32 AM
Anon

Issue is very simple. I am annoyed with you because you have not posted anything for 9 days. I hope all is well, but I'm annoyed anyway.

Kristof Claes
11 Jul 2010
09:05 AM
Kristof Claes

Did it have something to do with the fact that before you add an item, you have to check if it already exists or not and trying to get an unregistered item throws an exeption?

Thomas Eyde
11 Jul 2010
11:52 AM
Thomas Eyde

You found out that you wanted a set, not a dictionary?

More specifically, deleting a non existing item can be considered already deleted, adding an existing item can be considered as an overwrite, and retrieving a non existing item could return null.

I am not sure about the last one, but add and delete in this fashion should not throw.

fschwiet
11 Jul 2010
17:31 PM
fschwiet

Just yesterday I hit a bug where within one session I read an item (discarding the result) then wrote an item with the same key. This caused an exception, as would be expected by the last test. I would've preferred it would just overwrite. I assumed I was doing it wrong, maybe that will change.

The design problem may be that adding an item may throw an exception (if it has same key as existing), while the only way the caller can check if that will happen (by loading whatever has that key) could also throw an exception. So any typical use then involves handling an exception.

Just feedback on the last test... Its better to only have the one line that will throw an exception within the Assert.Throws() expression. Otherwise this test may pass for the wrong reason when an earlier line fails inappropriately.

Rik Hemsley
11 Jul 2010
17:51 PM
Rik Hemsley

Going by what I see in the tests, ApplicationInstanceDictionary is no different from Dictionary <guid,> , so you should use the .NET class and this means you don't need to test it.

Kevin McCormick
11 Jul 2010
19:32 PM
Kevin McCormick

Since this collection is tied to the class, the guid/key restrictions are kind of unnecessary. The dictionary class should manage duplicates, keys, etc. internally, and you should be able to manipulate the collection via index, linq, and provide indexing by guid only as an added bonus (ie, myColl.FindByGuid() ) if it's really necessary.

Rik Hemsley
11 Jul 2010
20:52 PM
Rik Hemsley

When I said Dictionary, the blog software ate my angle brackets, because it's rubbish (it still fails to 'remember me' despite offering to). So I meant a dictionary of Guid => string.

Steve Py
12 Jul 2010
01:29 AM
Steve Py

If ApplicationInstanceDictionary extends Dictionary, then it would appear that you are testing the default behaviour of a Dictionary, though the types of exceptions thrown might be different.

Andrey Titov
12 Jul 2010
05:34 AM
Andrey Titov

You changed them to TryRemove, TryAdd and TryGet to support concurrency?

Martin O'Keefe
12 Jul 2010
08:04 AM
Martin O'Keefe

'ApplicationInstance'

You need to maintain references to the GUID keys - the keys are required by consumers of values.

I would have suggested making the key the Type, but you are passing two strings as values - that's out.

I'm assuming that you chose GUID because the values are not user configurable - otherwise const string keys would appear to be better.

If the key is to be dynamic it seems that you need to make the key deterministic based on the type and its scope etc.

Frank Quednau
12 Jul 2010
17:54 PM
Frank Quednau

Just from the API perspective I don't like the asymmetry of adding ApplicationInstances and removing Guids.

Jon Norton
12 Jul 2010
20:59 PM
Jon Norton

In CannotAddDuplicatedItems() the test could pass due to an InvalidOperationException being thown before the last Add where the test is actually expecting the exception to be thrown. The Arrange portion of the test is included in the Action and Assert section represented by the Assert.Throws.

meo
13 Jul 2010
14:50 PM
meo

TMM, it is strange design, when you have 'firstInstance' != 'secondInstance' due to same key and different values in it (in 3rd test), but adding second after the first one will fail with InvalidOperation. It's inconsistent

meisinger
15 Jul 2010
17:11 PM
meisinger

the exception type is wrong

either that or you have determined that writing unit tests are silly and not needed

Comment preview

Comments have been closed on this topic.

Markdown formatting

ESC to close

Markdown turns plain text formatting into fancy HTML formatting.

Phrase Emphasis

*italic*   **bold**
_italic_   __bold__

Links

Inline:

An [example](http://url.com/ "Title")

Reference-style labels (titles are optional):

An [example][id]. Then, anywhere
else in the doc, define the link:
  [id]: http://example.com/  "Title"

Images

Inline (titles are optional):

![alt text](/path/img.jpg "Title")

Reference-style:

![alt text][id]
[id]: /url/to/img.jpg "Title"

Headers

Setext-style:

Header 1
========
Header 2
--------

atx-style (closing #'s are optional):

# Header 1 #
## Header 2 ##
###### Header 6

Lists

Ordered, without paragraphs:

1.  Foo
2.  Bar

Unordered, with paragraphs:

*   A list item.
    With multiple paragraphs.
*   Bar

You can nest them:

*   Abacus
    * answer
*   Bubbles
    1.  bunk
    2.  bupkis
        * BELITTLER
    3. burper
*   Cunning

Blockquotes

> Email-style angle brackets
> are used for blockquotes.
> > And, they can be nested.
> #### Headers in blockquotes
> 
> * You can quote a list.
> * Etc.

Horizontal Rules

Three or more dashes or asterisks:

---
* * *
- - - - 

Manual Line Breaks

End a line with two or more spaces:

Roses are red,   
Violets are blue.

Fenced Code Blocks

Code blocks delimited by 3 or more backticks or tildas:

```
This is a preformatted
code block
```

Header IDs

Set the id of headings with {#<id>} at end of heading line:

## My Heading {#myheading}

Tables

Fruit    |Color
---------|----------
Apples   |Red
Pears	 |Green
Bananas  |Yellow

Definition Lists

Term 1
: Definition 1
Term 2
: Definition 2

Footnotes

Body text with a footnote [^1]
[^1]: Footnote text here

Abbreviations

MDD <- will have title
*[MDD]: MarkdownDeep

 

FUTURE POSTS

No future posts left, oh my!

RECENT SERIES

  1. RavenDB News (2):
    02 May 2025 - May 2025
  2. Recording (15):
    30 Apr 2025 - Practical AI Integration with RavenDB
  3. Production Postmortem (52):
    07 Apr 2025 - The race condition in the interlock
  4. RavenDB (13):
    02 Apr 2025 - .NET Aspire integration
  5. RavenDB 7.1 (6):
    18 Mar 2025 - One IO Ring to rule them all
View all series

RECENT COMMENTS

  • Scooletz, Yes, we look at other stuff. Most of those are _not_ allowing you to build themselves incrementally nor are they...
    By Oren Eini on Scaling HNSW in RavenDB: Optimizing for inadequate hardware
  • Have you considered other approaches, DiskSpan, Spann etc.? HNSW, as far as I know, is terrible in regards to updates and det...
    By Scooletz on Scaling HNSW in RavenDB: Optimizing for inadequate hardware
  • Steve, The check is for _equality_ - if the current version matches the value in the versions array. When the `_version` ...
    By Oren Eini on Optimizing the cost of clearing a set
  • I'm not following that part, the first 65K times (until ushort.MaxValue) it will be smaller so you'll enter the if/return, bu...
    By Steve on Optimizing the cost of clearing a set
  • Steve, No, I don't need to. It is going to wrap around anyway, after all
    By Oren Eini on Optimizing the cost of clearing a set

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats
}