/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2002-2006 * Sleepycat Software. All rights reserved. * * $Id: DupCountLN.java,v 1.1 2006/05/06 09:00:12 ckaestne Exp $ */ package com.sleepycat.je.tree; import java.nio.ByteBuffer; import com.sleepycat.je.dbi.MemoryBudget; import com.sleepycat.je.log.LogEntryType; import com.sleepycat.je.log.LogException; import com.sleepycat.je.log.LogUtils; /** * A DupCountLN represents the transactional part of the root of a * duplicate tree, specifically the count of dupes in the tree. */ public final class DupCountLN extends LN { private static final String BEGIN_TAG = "<dupCountLN>"; private static final String END_TAG = "</dupCountLN>"; private int dupCount; /** * Create a new DupCountLn to hold a new DIN. */ public DupCountLN(int count) { super(new byte[0]); /* * This ctor is always called from Tree.createDuplicateEntry * where there will be one existing LN and a new dup LN being * inserted to create the new duplicate tree. So the minimum * starting point for a duplicate tree is 2 entries. */ this.dupCount = count; } /** * Create an empty DupCountLN, to be filled in from the log. */ public DupCountLN() { super(); dupCount = 0; } public int getDupCount() { return dupCount; } public int incDupCount() { dupCount++; assert dupCount >= 0; return dupCount; } public int decDupCount() { dupCount--; assert dupCount >= 0; return dupCount; } void setDupCount(int dupCount) { this.dupCount = dupCount; } /** * @return true if this node is a duplicate-bearing node type, false * if otherwise. */ public boolean containsDuplicates() { return true; } public boolean isDeleted() { return false; } /** * Compute the approximate size of this node in memory for evictor * invocation purposes. */ public long getMemorySizeIncludedByParent() { return MemoryBudget.DUPCOUNTLN_OVERHEAD; } /* * DbStat support. */ public void accumulateStats(TreeWalkerStatsAccumulator acc) { acc.processDupCountLN(this, new Long(getNodeId())); } /* * Dumping */ public String toString() { return dumpString(0, true); } public String beginTag() { return BEGIN_TAG; } public String endTag() { return END_TAG; } public String dumpString(int nSpaces, boolean dumpTags) { StringBuffer sb = new StringBuffer(); if (dumpTags) { sb.append(TreeUtils.indent(nSpaces)); sb.append(beginTag()); sb.append('\n'); } sb.append(TreeUtils.indent(nSpaces+2)); sb.append("<count v=\"").append(dupCount).append("\"/>").append('\n'); sb.append(super.dumpString(nSpaces, false)); if (dumpTags) { sb.append(TreeUtils.indent(nSpaces)); sb.append(endTag()); } return sb.toString(); } /* * Logging */ /** * Log type for transactional entries. */ protected LogEntryType getTransactionalLogType() { return LogEntryType.LOG_DUPCOUNTLN_TRANSACTIONAL; } /** * @see LN#getLogType */ public LogEntryType getLogType() { return LogEntryType.LOG_DUPCOUNTLN; } /** * @see LN#getLogSize */ public int getLogSize() { return super.getLogSize() + LogUtils.INT_BYTES; } /** * @see LN#writeToLog */ public void writeToLog(ByteBuffer logBuffer) { // Ask ancestors to write to log super.writeToLog(logBuffer); LogUtils.writeInt(logBuffer, dupCount); } /** * @see LN#readFromLog */ public void readFromLog(ByteBuffer itemBuffer, byte entryTypeVersion) throws LogException { super.readFromLog(itemBuffer, entryTypeVersion); dupCount = LogUtils.readInt(itemBuffer); } /** * Dump additional fields */ protected void dumpLogAdditional(StringBuffer sb, boolean verbose) { super.dumpLogAdditional(sb, verbose); sb.append("<count v=\"").append(dupCount).append("\"/>"); } }