Index: src/java/org/apache/lucene/store/RAMDirectory.java
===================================================================
--- src/java/org/apache/lucene/store/RAMDirectory.java	(revision 476181)
+++ src/java/org/apache/lucene/store/RAMDirectory.java	(working copy)
@@ -39,6 +39,7 @@
   private static final long serialVersionUID = 1l;
 
   Hashtable files = new Hashtable();
+  private long sizeInBytes;  // synchronized on this (use AtomicLong in Java5)
 
   /** Constructs an empty {@link Directory}. */
   public RAMDirectory() {
@@ -108,6 +109,8 @@
   public final String[] list() {
     String[] result = new String[files.size()];
     int i = 0;
+    // This isn't synchronized, but it uses an Enumeration which doesn't
+    // fail-fast on concurrent modification.
     Enumeration names = files.keys();
     while (names.hasMoreElements())
       result[i++] = (String)names.nextElement();
@@ -155,28 +158,58 @@
   }
 
   /** Removes an existing file in the directory. */
-  public final void deleteFile(String name) {
-    files.remove(name);
+  public final void deleteFile(String name) throws IOException {
+    RAMFile file = (RAMFile)files.remove(name);
+    if (file==null) throw new IOException("Cannot delete nonexistent "+name);
+
+    long fileSize = file.totalBufferSize();
+    synchronized(this) { sizeInBytes -= fileSize; }
   }
 
-  /** Removes an existing file in the directory. */
-  public final void renameFile(String from, String to) {
-    RAMFile file = (RAMFile)files.get(from);
-    files.remove(from);
-    files.put(to, file);
+  /** Renames an existing file in the directory. */
+  public final void renameFile(String from, String to) throws IOException {
+    synchronized (files) {
+      RAMFile file = (RAMFile)files.remove(from);
+      if (file==null) throw new IOException("Cannot rename nonexistent "+from);
+      RAMFile prev = (RAMFile)files.put(to, file);
+      if (prev!=null) {
+        // we are overwriting an existing file
+        long bufferSize = prev.totalBufferSize();
+        synchronized(this) { sizeInBytes -= bufferSize; }
+      }
+    }
   }
 
   /** Creates a new, empty file in the directory with the given name.
       Returns a stream writing this file. */
   public final IndexOutput createOutput(String name) {
     RAMFile file = new RAMFile();
-    files.put(name, file);
-    return new RAMOutputStream(file);
+
+    RAMFile prev = (RAMFile)files.put(name,file);
+    if (prev!=null) {
+      // we are overwriting an existing file
+      long bufferSize = prev.totalBufferSize();
+      synchronized(this) { sizeInBytes -= bufferSize; }
+    }
+
+    return new RAMOutputStream(file) {
+      void bufferAdded(int size) {
+        synchronized(RAMDirectory.this) { sizeInBytes += size; }
+      }
+    };
   }
 
+  /** Returns the size in bytes of all closed files.
+   * Files that are currently being written to are not included.
+   */
+  public long getSizeInBytes() {
+    synchronized(this) { return sizeInBytes; }
+  }
+
   /** Returns a stream reading an existing file. */
-  public final IndexInput openInput(String name) {
+  public final IndexInput openInput(String name) throws IOException {
     RAMFile file = (RAMFile)files.get(name);
+    if (file==null) throw new IOException("Cannot open nonexistent "+name);
     return new RAMInputStream(file);
   }
 
Index: src/java/org/apache/lucene/store/RAMOutputStream.java
===================================================================
--- src/java/org/apache/lucene/store/RAMOutputStream.java	(revision 476181)
+++ src/java/org/apache/lucene/store/RAMOutputStream.java	(working copy)
@@ -78,7 +78,10 @@
 
       if (bufferNumber == file.buffers.size()) {
         buffer = new byte[BUFFER_SIZE];
+        // NOTE: RAMFile.totalBufferSize() currently relies on all added buffers
+        // being of size BUFFER_SIZE
         file.buffers.addElement(buffer);
+        bufferAdded(buffer.length);
       } else {
         buffer = (byte[]) file.buffers.elementAt(bufferNumber);
       }
@@ -94,6 +97,12 @@
     file.lastModified = System.currentTimeMillis();
   }
 
+  /** called after a new buffer is added to the ramfile
+   * @param size the size of the added buffer
+   */
+  void bufferAdded(int size) {
+  }
+
   public void close() throws IOException {
     super.close();
   }
Index: src/java/org/apache/lucene/store/RAMFile.java
===================================================================
--- src/java/org/apache/lucene/store/RAMFile.java	(revision 476181)
+++ src/java/org/apache/lucene/store/RAMFile.java	(working copy)
@@ -27,4 +27,10 @@
   Vector buffers = new Vector();
   long length;
   long lastModified = System.currentTimeMillis();
+
+  /** return the amount of buffer space used by this RAMFile. */
+  long totalBufferSize() {
+    // NOTE: assumes that all buffers are of size BUFFER_SIZE
+    return buffers.size() * BufferedIndexOutput.BUFFER_SIZE;
+  }
 }
