In version 4.0, the InfinityDB Java embedded Database introduced database access via the standard Java Map interface. It is possible entirely to bypass all of the now lower-level access via the ItemSpace, and instead to use only nested Maps. InfinityDBMap and InfinityDBSet can simply be constructed as wrappers around a normal InfinityDB file, and thereafter the usual put(), get(), iterators, and all the rest are available. The interface is actually more capable than the simple java.util.Map, because it further implements java.util.NavigableMap for advanced sorted access and java.util.concurrent.ConcurrentMap for overlapping thread access. The multi-core performance of InfinityDB is supported, and Map-based access is completely compatible with the engine-level access in existing applications. The entire Map-based access source is available in src/com/infinitydb/map/**.
Use is as simple as this
Map<String, String> map = new InfinityDBMap<String, String>(db); map.put("key", "hello world!"); System.out.println("value=" + map.get("key")); for (String key : map.keySet()) System.out.println("key=" + key);
The extensibility comes from the ‘nested Map’ mode, in which a new Map is constructed inside another using getMap(k):
Map<String, String> nestedMap = map.getMap("key"); nestedMap.put("sub_key", "hello world!"); System.out.println("nestedMap: " + nestedMap.get("sub_key"));
The nestedMaps are created as needed, possibly rapidly and dynamically, and they are thread-safe and immutable. They are not actually stored, because the database is actually organized as a single sorted set of variable-length ‘tuples’ (which are ‘Items’ at the engine level), and each nested Map corresponds to a prefix that selects a subset of tuples. Doing a put(k, v) on a nested Map having prefix p creates and stores tuple (p, k, v), and deletes any tuples (p, k, v, …). Because the prefix may be long with deeply nested Maps, structures can be very complex. Creativity with the nesting – hence with the prefixes – is very powerful. Here is how to store a ‘relation’ called GREETING (which is a long along with HELLO and GOODBYE for efficiency and speed):
InfinityDBMap rootMap = new InfinityDBMap<String, String>(db); InfinityDBMap greeting = rootMap.getMap(GREETINGS); InfinityDBMap alden = greeting.getMap("Alden"); alden.put(HELLO, "hello world!"); alden.put(GOODBYE, "later");
Which means “Alden” says “hello world!” as his greeting. More complex structures are easy. If we want a complex structure like a street address inside ADDRESS:
alden.getMap(ADDRESS).put(STREET, "243 my street"e); alden.getMap(ADDRESS).put(STATE, "my state");
Better yet, we can use multi-value Maps and Sets interchangeably either designed-in initially or as a future extension:
alden.getSet(CREDIT_CARD).add(12345); alden.getSet(CREDIT_CARD).add(54321); for (Object card : alden.getSet(CREDIT_CARD)) System.out.println("card: " + card);
It is possible to extend a Set to become a Map if further structure is desired for future-proofing.
Look into src/com/infinitydb/map/db/MapHelloWorld.java for the basics and much more, including demos of hierarchical, JSON, and XML printers.
For licensing, see firstname.lastname@example.org.