KissDB developers: read this first; this package should contain the documentation you should need to modify the KissDB library for your needs.

See: Description

Package Description

KissDB developers: read this first; this package should contain the documentation you should need to modify the KissDB library for your needs.

This package is not needed for production use and may be omitted from the final build.

Depends on: com.kissdb.* (any kissdb package)

General assumptions

The database performance is optimized for a modern 64-bit server. Typically 4 to 16 cores. 1 to 2 CPUs. SSD or ordinary disk(s). But it should also run on very small devices with a unified source base.

There is only *one* DB stream format for all supported devices, operating systems and programming languages.

Logically, the database uses a single append-only stream (interface stream.AppendOnlyStream).

Serial writes. While many transactions (both read and write) may run in parallel, write transactions are serialized for storage and stored to permanent storage.

Anti-assumption: We DO NOT assume the system is running on a 64-bit server with atomic operations on "long" and "double".


* Use Java 1.5. Generics is allowed.
* Annotations are only allowed for non-production code (test-code).
* Do not use enums. (Issues with cross-compiling).
* Do not use weak references because of GCJ issues.
* Be careful with printf/String.format() because of GCJ issues. And to have one less IKVM DLL.
* Do not use resource files because of GCJ issues and complexity in general.

* Follow Sun's (Oracle's) Java code style (but allow some deviation if useful) unless otherwise
    specified here.
* Use 100 columns instead of 80 (same as Android).
* Treat acronyms as words. Eg.: getId(), getHtml(), setUrl() (same as Android).
* One-line if statements are allowed (no curlys).
    if (print) System.out.println("...");
* Android has a good code style almost identical to Sun's original at
* Use "public" in front of interface methods.

* Use Javadoc. Class comments, method comments. Use few tags: @deprecated, @param, @throws, @author.
* Use Javadoc "@author Frans Lundberg" for top-level classes/interfaces.
* ALL classes/interface/methods of the Pub API must be have Javadoc comments.
* ALL classes/interfaces must have Javadoc comments.
* See Oracle's: "How to Write Doc Comments for the Javadoc Tool".

Testing. Use Nanotest (com.kissdb.nanotest). Use it for unit tests (nanotest group unit), functional tests (f) and performance tests (perf). A major reason for using Nanotest is to be able to self-test easily (even when compiled with GCJ, IKVM, ..). Nanotest is very simple and small compare to JUnit and it allows test methods directly in the classes to be tested. I like when the test follows the testee with moves/renaming/deletion. A "unit" test should run within 0.1 s, an "f" test should run within 10 s. "perf" tests have no limit. The difference between "unit" tests and "f" tests is not strictly functional, but about execution time. Both of the test types, test that the code is working properly. All "unit" test are normally successful at commit. "f" tests are not necessarily run before every commit, but should be run at least once week and after larger modifications.

Use NOTE in addition to TODO and XXX. NOTE is used for something we may want to modify at in the future. Possible improvements, considerations. NOTEs can be kept in the code indefinitely, while XXX are temporary and should be gone before each commit. Most TODOs should be gone before a release. Use backlog for future tasks.

Access rules. "protected" keyword is not allowed and package access is seldom used. This is to keep things simple, and make it work with GCJ. We need more advanced access rules anyway; they cannot be enforced by the Java compiler. Instead, allowed access is determined by the allowed package dependencies.

package.html. Use Javadoc package.html files to document the Java packages. Each package should specify its allowed package dependencies with a statement like: Depends on: list-of-packages. kissdb/ is used to verify that these rules are followed.

Global stuff / static. Do not use JVM global stuff (non-final "static" fields). It should be possible to run multiple KissDB instances in one JVM. Easy testing, limited dependencies. KissDB should run well in the same JVM together with other software. So no global state is set by KissDB (for example: default exception handler, logging).

Logging. Do not use java.logging. This is global stuff, and its benefits does not outweigh the added complexity, especially when KissDB is used in-JVM with other applications and other KissDB instances.


With few exceptions, input and output is data read from / written to the database.

System.out is never used. System.err is never used. is never used.


The source is built with vastly different targets in mind. It is build to a Java jar with Java byte code, of course. Also it is build to native machine code and to .NET (IL).

Java JAR

The source is built to one jar: "kissdb.jar". Source files are not included in this jar.


The source also compiles to native machine code with GCJ. We should be able to compile it both to an executable and a library. Some restrictions when programming: not all "printf" statements work. For example: System.out.printf("%s: %.3f s\n", currentMethodName, exeTime); does not work. We avoid using "printf" all together as a work-around.

Resource files are problematic, should work, but I did not manage to get it to compile when compiling the project from source.

Other things to avoid: weak references.

Assertions can be tricky to disable when compiling from jar file (kissdb.jar) instead of from source.

In general, GCJ seems a bit old. Not much updated the last years. Lack of documentation. However, it does seem to work with a few limitiations on the Java coding.


Works well, no problems at all. See build/ikvm.

Versions and releases

Version. "2013.1" is used as the version ID of the first KissDB version in 2013. 2013.2, 2013.3, 2014.1, 2014.2 are used for the following public releases (assuming 3 releases in 2013). There must be no more than 9 versions for one specific year. The version int is 131, 132, 133, 141, 142 for the above example releases. The version int makes it simple to compare versions. It should be used internally only. The version ID and the version int are available from the class db.BuildInfo. The year (2013, 2014) is the major version number, and the second number if the minor version number. A change in minor version adds functionality, improves existing functionality and aims to be backward compatible with previous versions with the same major version number. When the major version changes, changes may be introduced that are not backward compatible.

New methods and features can be marked with "since" in Javadoc, example: "@since 2013.2".

Release. A KissDB software release is one single zip file made available from

Each release of a new zip file is given a release ID. A release ID contains the KissDB version plus the release date. Examples: "2013.1.130401", "2013.2.130301", "2013.1.130601", "2013.2.130610".Releases of old versions may be made, but should be avoided since newer minor versions should be backward compatible. But such releases are allowed. Simple mistakes, updates to documentation etc.

Build. Builds are used internally by KissDB developers (me only :-)). Build IDs has HHMM added to the build ID. Examples: "2013.1.130401.1330", "2013.2.130630.1500".


All documentation needed to use and modify KissDB should be included in the Javadoc files (possibly by including files in doc-files/ directories). HTML and TXT files are allowed. JPEG/PNG images are also allowed.

Avoid separate documentation. The website should mostly simply have links to Javadoc (

Known issues/limitations

-- Key replace --

1. If we have code:"/d/${transactionTime}/d2/myObject.obj", obj); 
We cannot check if directory is indexed. In theory the directory d/${transactionTime} could 
replace into an existing indexed directory.

Possible solution: We could disallow key replacement except in the last part of the key.

2. Consider: If there would be an indexed object with key "/d/1230.obj" and an KV 
with replace key "/d/${transactionTime}.obj" evaluates to the same key -> we have a problem!
The old index entries are then not removed!

Possible solution: Throw an exception if such a key already exists. Inform user that it is not
allowed to have a *.obj key with replacements to replace an existing KV. 
This may require a new setIfNotExisting (insert) feature in DB. We could disallow it only 
for indexed directories.

Link collection

Java 1.5 API, Source

ICU Demo: Locales/collations

KissDB release: 2013.1.130606. Copyright Frans Lundberg.