@Override int estimateSize(AnyObjectId noteOn, ObjectReader or) throws IOException { // If most of this fan-out is full, estimate it should still be split. if (LeafBucket.MAX_SIZE * 3 / 4 <= cnt) return 1 + LeafBucket.MAX_SIZE; // Due to the uniform distribution of ObjectIds, having less nodes full // indicates a good chance the total number of children below here // is less than the MAX_SIZE split point. Get a more accurate count. MutableObjectId id = new MutableObjectId(); id.fromObjectId(noteOn); int sz = 0; for (int cell = 0; cell < 256; cell++) { NoteBucket b = table[cell]; if (b == null) continue; id.setByte(prefixLen >> 1, cell); sz += b.estimateSize(id, or); if (LeafBucket.MAX_SIZE < sz) break; } return sz; }
@Override Note getNote(AnyObjectId objId, ObjectReader or) throws IOException { NoteBucket b = table[cell(objId)]; return b != null ? b.getNote(objId, or) : null; }
private TreeFormatter build(boolean insert, ObjectInserter inserter) throws IOException { byte[] nameBuf = new byte[2]; TreeFormatter fmt = new TreeFormatter(treeSize()); NonNoteEntry e = nonNotes; for (int cell = 0; cell < 256; cell++) { NoteBucket b = table[cell]; if (b == null) continue; nameBuf[0] = hexchar[cell >>> 4]; nameBuf[1] = hexchar[cell & 0x0f]; while (e != null && e.pathCompare(nameBuf, 0, 2, TREE) < 0) { e.format(fmt); e = e.next; } ObjectId id; if (insert) { id = b.writeTree(inserter); } else { id = b.getTreeId(); } fmt.append(nameBuf, 0, 2, TREE, id); } for (; e != null; e = e.next) e.format(fmt); return fmt; }
@Override public boolean hasNext() { if (itr != null && itr.hasNext()) return true; for (; cell < table.length; cell++) { NoteBucket b = table[cell]; if (b == null) continue; try { id.setByte(prefixLen >> 1, cell); itr = b.iterator(id, reader); } catch (IOException err) { throw new RuntimeException(err); } if (itr.hasNext()) { cell++; return true; } } return false; }
@Override InMemoryNoteBucket set(AnyObjectId noteOn, AnyObjectId noteData, ObjectReader or) throws IOException { int cell = cell(noteOn); NoteBucket b = table[cell]; if (b == null) { if (noteData == null) return this; LeafBucket n = new LeafBucket(prefixLen + 2); table[cell] = n.set(noteOn, noteData, or); cnt++; return this; } else { NoteBucket n = b.set(noteOn, noteData, or); if (n == null) { table[cell] = null; cnt--; if (cnt == 0) return null; return contractIfTooSmall(noteOn, or); } else if (n != b) { table[cell] = n; } return this; } }
private void addIfNotNull(FanoutBucket b, int cell, NoteBucket child) throws IOException { if (child == null) return; if (child instanceof InMemoryNoteBucket) b.setBucket(cell, ((InMemoryNoteBucket) child).writeTree(inserter)); else b.setBucket(cell, child.getTreeId()); }
public boolean hasNext() { if (itr != null && itr.hasNext()) return true; for (; cell < table.length; cell++) { NoteBucket b = table[cell]; if (b == null) continue; try { id.setByte(prefixLen >> 1, cell); itr = b.iterator(id, reader); } catch (IOException err) { throw new RuntimeException(err); } if (itr.hasNext()) { cell++; return true; } } return false; }
@Override InMemoryNoteBucket set(AnyObjectId noteOn, AnyObjectId noteData, ObjectReader or) throws IOException { int cell = cell(noteOn); NoteBucket b = table[cell]; if (b == null) { if (noteData == null) return this; LeafBucket n = new LeafBucket(prefixLen + 2); table[cell] = n.set(noteOn, noteData, or); cnt++; return this; } else { NoteBucket n = b.set(noteOn, noteData, or); if (n == null) { table[cell] = null; cnt--; if (cnt == 0) return null; return contractIfTooSmall(noteOn, or); } else if (n != b) { table[cell] = n; } return this; } }
private TreeFormatter build(boolean insert, ObjectInserter inserter) throws IOException { byte[] nameBuf = new byte[2]; TreeFormatter fmt = new TreeFormatter(treeSize()); NonNoteEntry e = nonNotes; for (int cell = 0; cell < 256; cell++) { NoteBucket b = table[cell]; if (b == null) continue; nameBuf[0] = hexchar[cell >>> 4]; nameBuf[1] = hexchar[cell & 0x0f]; while (e != null && e.pathCompare(nameBuf, 0, 2, TREE) < 0) { e.format(fmt); e = e.next; } ObjectId id; if (insert) { id = b.writeTree(inserter); } else { id = b.getTreeId(); } fmt.append(nameBuf, 0, 2, TREE, id); } for (; e != null; e = e.next) e.format(fmt); return fmt; }
@Override Note getNote(AnyObjectId objId, ObjectReader or) throws IOException { NoteBucket b = table[cell(objId)]; return b != null ? b.getNote(objId, or) : null; }
@Override public boolean hasNext() { if (itr != null && itr.hasNext()) return true; for (; cell < table.length; cell++) { NoteBucket b = table[cell]; if (b == null) continue; try { id.setByte(prefixLen >> 1, cell); itr = b.iterator(id, reader); } catch (IOException err) { throw new RuntimeException(err); } if (itr.hasNext()) { cell++; return true; } } return false; }
@Override int estimateSize(AnyObjectId noteOn, ObjectReader or) throws IOException { // If most of this fan-out is full, estimate it should still be split. if (LeafBucket.MAX_SIZE * 3 / 4 <= cnt) return 1 + LeafBucket.MAX_SIZE; // Due to the uniform distribution of ObjectIds, having less nodes full // indicates a good chance the total number of children below here // is less than the MAX_SIZE split point. Get a more accurate count. MutableObjectId id = new MutableObjectId(); id.fromObjectId(noteOn); int sz = 0; for (int cell = 0; cell < 256; cell++) { NoteBucket b = table[cell]; if (b == null) continue; id.setByte(prefixLen >> 1, cell); sz += b.estimateSize(id, or); if (LeafBucket.MAX_SIZE < sz) break; } return sz; }
@Override InMemoryNoteBucket set(AnyObjectId noteOn, AnyObjectId noteData, ObjectReader or) throws IOException { int cell = cell(noteOn); NoteBucket b = table[cell]; if (b == null) { if (noteData == null) return this; LeafBucket n = new LeafBucket(prefixLen + 2); table[cell] = n.set(noteOn, noteData, or); cnt++; return this; } else { NoteBucket n = b.set(noteOn, noteData, or); if (n == null) { table[cell] = null; cnt--; if (cnt == 0) return null; return contractIfTooSmall(noteOn, or); } else if (n != b) { table[cell] = n; } return this; } }
private TreeFormatter build(boolean insert, ObjectInserter inserter) throws IOException { byte[] nameBuf = new byte[2]; TreeFormatter fmt = new TreeFormatter(treeSize()); NonNoteEntry e = nonNotes; for (int cell = 0; cell < 256; cell++) { NoteBucket b = table[cell]; if (b == null) continue; nameBuf[0] = hexchar[cell >>> 4]; nameBuf[1] = hexchar[cell & 0x0f]; while (e != null && e.pathCompare(nameBuf, 0, 2, TREE) < 0) { e.format(fmt); e = e.next; } ObjectId id; if (insert) { id = b.writeTree(inserter); } else { id = b.getTreeId(); } fmt.append(nameBuf, 0, 2, TREE, id); } for (; e != null; e = e.next) e.format(fmt); return fmt; }
@Override Note getNote(AnyObjectId objId, ObjectReader or) throws IOException { NoteBucket b = table[cell(objId)]; return b != null ? b.getNote(objId, or) : null; }
@Override int estimateSize(AnyObjectId noteOn, ObjectReader or) throws IOException { // If most of this fan-out is full, estimate it should still be split. if (LeafBucket.MAX_SIZE * 3 / 4 <= cnt) return 1 + LeafBucket.MAX_SIZE; // Due to the uniform distribution of ObjectIds, having less nodes full // indicates a good chance the total number of children below here // is less than the MAX_SIZE split point. Get a more accurate count. MutableObjectId id = new MutableObjectId(); id.fromObjectId(noteOn); int sz = 0; for (int cell = 0; cell < 256; cell++) { NoteBucket b = table[cell]; if (b == null) continue; id.setByte(prefixLen >> 1, cell); sz += b.estimateSize(id, or); if (LeafBucket.MAX_SIZE < sz) break; } return sz; }
private void addIfNotNull(FanoutBucket b, int cell, NoteBucket child) throws IOException { if (child == null) return; if (child instanceof InMemoryNoteBucket) b.setBucket(cell, ((InMemoryNoteBucket) child).writeTree(inserter)); else b.setBucket(cell, child.getTreeId()); }