/** Add a snapshot. */ Snapshot addSnapshot(int id, String name) throws SnapshotException, QuotaExceededException { // check snapshot quota final int n = getNumSnapshots(); if (n + 1 > snapshotQuota) { throw new SnapshotException( "Failed to add snapshot: there are already " + n + " snapshot(s) and the snapshot quota is " + snapshotQuota); } final Snapshot s = new Snapshot(id, name, this); final byte[] nameBytes = s.getRoot().getLocalNameBytes(); final int i = searchSnapshot(nameBytes); if (i >= 0) { throw new SnapshotException( "Failed to add snapshot: there is already a " + "snapshot with the same name \"" + Snapshot.getSnapshotName(s) + "\"."); } final DirectoryDiff d = getDiffs().addDiff(s, this); d.snapshotINode = s.getRoot(); snapshotsByNames.add(-i - 1, s); // set modification time updateModificationTime(Time.now(), null, null); s.getRoot().setModificationTime(getModificationTime(), null, null); return s; }
@Override public void dumpTreeRecursively(PrintWriter out, StringBuilder prefix, Snapshot snapshot) { super.dumpTreeRecursively(out, prefix, snapshot); if (snapshot == null) { out.println(); out.print(prefix); out.print("Snapshot of "); final String name = getLocalName(); out.print(name.isEmpty() ? "/" : name); out.print(": quota="); out.print(getSnapshotQuota()); int n = 0; for (DirectoryDiff diff : getDiffs()) { if (diff.isSnapshotRoot()) { n++; } } Preconditions.checkState(n == snapshotsByNames.size()); out.print(", #snapshot="); out.println(n); dumpTreeRecursively( out, prefix, new Iterable<SnapshotAndINode>() { @Override public Iterator<SnapshotAndINode> iterator() { return new Iterator<SnapshotAndINode>() { final Iterator<DirectoryDiff> i = getDiffs().iterator(); private DirectoryDiff next = findNext(); private DirectoryDiff findNext() { for (; i.hasNext(); ) { final DirectoryDiff diff = i.next(); if (diff.isSnapshotRoot()) { return diff; } } return null; } @Override public boolean hasNext() { return next != null; } @Override public SnapshotAndINode next() { final Snapshot s = next.snapshot; final SnapshotAndINode pair = new SnapshotAndINode(s); next = findNext(); return pair; } @Override public void remove() { throw new UnsupportedOperationException(); } }; } }); } }