/** * Remove an entry with the given key from the BTree. * * @param key Removal key * @return Value associated with the key, or null if no entry with given key existed in the BTree. */ public synchronized Object remove(Object key) throws IOException { if (key == null) { throw new IllegalArgumentException("Argument 'key' is null"); } BPage rootPage = getRoot(); if (rootPage == null) { return null; } boolean dirty = false; BPage.RemoveResult remove = rootPage.remove(_height, key); if (remove._underflow && rootPage.isEmpty()) { _height -= 1; dirty = true; // TODO: check contract for BPages to be removed from recman. if (_height == 0) { _root = 0; } else { _root = rootPage.childBPage(_pageSize - 1)._recid; } } if (remove._value != null) { _entries--; dirty = true; } if (dirty) { _recman.update(_recid, this); } return remove._value; }
/** * Insert an entry in the BTree. * * <p>The BTree cannot store duplicate entries. An existing entry can be replaced using the <code> * replace</code> flag. If an entry with the same key already exists in the BTree, its value is * returned. * * @param key Insert key * @param value Insert value * @param replace Set to true to replace an existing key-value pair. * @return Existing value, if any. */ public synchronized Object insert(Object key, Object value, boolean replace) throws IOException { if (key == null) { throw new IllegalArgumentException("Argument 'key' is null"); } if (value == null) { throw new IllegalArgumentException("Argument 'value' is null"); } BPage rootPage = getRoot(); if (rootPage == null) { // BTree is currently empty, create a new root BPage if (DEBUG) { System.out.println("BTree.insert() new root BPage"); } rootPage = new BPage(this, key, value); _root = rootPage._recid; _height = 1; _entries = 1; _recman.update(_recid, this); return null; } else { BPage.InsertResult insert = rootPage.insert(_height, key, value, replace); boolean dirty = false; if (insert._overflow != null) { // current root page overflowed, we replace with a new root page if (DEBUG) { System.out.println("BTree.insert() replace root BPage due to overflow"); } rootPage = new BPage(this, rootPage, insert._overflow); _root = rootPage._recid; _height += 1; dirty = true; } if (insert._existing == null) { _entries++; dirty = true; } if (dirty) { _recman.update(_recid, this); } // insert might have returned an existing value return insert._existing; } }