comparison src/org/tmatesoft/hg/internal/FNCacheFile.java @ 616:5e0313485eef

encode directories as demanded by fncache format
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Tue, 14 May 2013 17:31:35 +0200
parents 6ca3d0c5b4bc
children 507602cb4fb3
comparison
equal deleted inserted replaced
615:84104448a0bf 616:5e0313485eef
17 package org.tmatesoft.hg.internal; 17 package org.tmatesoft.hg.internal;
18 18
19 import java.io.File; 19 import java.io.File;
20 import java.io.FileOutputStream; 20 import java.io.FileOutputStream;
21 import java.io.IOException; 21 import java.io.IOException;
22 import java.nio.ByteBuffer;
23 import java.nio.CharBuffer;
24 import java.nio.channels.FileChannel;
22 import java.nio.charset.Charset; 25 import java.nio.charset.Charset;
23 import java.util.ArrayList; 26 import java.util.ArrayList;
24 import java.util.List; 27 import java.util.List;
25 28
26 import org.tmatesoft.hg.util.Path; 29 import org.tmatesoft.hg.util.Path;
39 */ 42 */
40 public class FNCacheFile { 43 public class FNCacheFile {
41 44
42 private final Internals repo; 45 private final Internals repo;
43 // private final List<Path> files; 46 // private final List<Path> files;
44 private List<Path> added; 47 private final List<Path> addedDotI;
48 private final List<Path> addedDotD;
49 private final FNCachePathHelper pathHelper;
45 50
46 public FNCacheFile(Internals internalRepo) { 51 public FNCacheFile(Internals internalRepo) {
47 repo = internalRepo; 52 repo = internalRepo;
48 // files = new ArrayList<Path>(); 53 // files = new ArrayList<Path>();
54 pathHelper = new FNCachePathHelper();
55 addedDotI = new ArrayList<Path>(5);
56 addedDotD = new ArrayList<Path>(5);
49 } 57 }
50 58
51 /* 59 /*
52 * For append-only option, we don't care reading the original content 60 * For append-only option, we don't care reading the original content
53 public void read(Path.Source pathFactory) throws IOException { 61 public void read(Path.Source pathFactory) throws IOException {
65 } 73 }
66 } 74 }
67 */ 75 */
68 76
69 public void write() throws IOException { 77 public void write() throws IOException {
70 if (added == null || added.isEmpty()) { 78 if (addedDotI.isEmpty() && addedDotD.isEmpty()) {
71 return; 79 return;
72 } 80 }
73 File f = fncacheFile(); 81 File f = fncacheFile();
74 f.getParentFile().mkdirs(); 82 f.getParentFile().mkdirs();
75 final Charset filenameEncoding = repo.getFilenameEncoding(); 83 final Charset filenameEncoding = repo.getFilenameEncoding();
76 FileOutputStream fncacheFile = new FileOutputStream(f, true); 84 ArrayList<CharBuffer> added = new ArrayList<CharBuffer>();
77 for (Path p : added) { 85 for (Path p : addedDotI) {
78 String s = "data/" + p.toString() + ".i"; // TODO post-1.0 this is plain wrong. (a) need .d files, too; (b) what about dh/ location? 86 added.add(CharBuffer.wrap(pathHelper.rewrite(p)));
79 fncacheFile.write(s.getBytes(filenameEncoding)); 87 }
80 fncacheFile.write(0x0A); // http://mercurial.selenic.com/wiki/fncacheRepoFormat 88 for (Path p : addedDotD) {
89 // XXX FNCachePathHelper always return name of an index file, need to change it into a name of data file,
90 // although the approach (to replace last char) is depressingly awful
91 CharSequence cs = pathHelper.rewrite(p);
92 CharBuffer cb = CharBuffer.allocate(cs.length());
93 cb.append(cs);
94 cb.put(cs.length()-1, 'd');
95 cb.flip();
96 added.add(cb);
97 }
98 FileChannel fncacheFile = new FileOutputStream(f, true).getChannel();
99 ByteBuffer lf = ByteBuffer.wrap(new byte[] { 0x0A });
100 for (CharBuffer b : added) {
101 fncacheFile.write(filenameEncoding.encode(b));
102 fncacheFile.write(lf);
103 lf.rewind();
81 } 104 }
82 fncacheFile.close(); 105 fncacheFile.close();
83 } 106 }
84 107
85 public void add(Path p) { 108 public void addIndex(Path p) {
86 if (added == null) { 109 addedDotI.add(p);
87 added = new ArrayList<Path>(); 110 }
88 } 111
89 added.add(p); 112 public void addData(Path p) {
113 addedDotD.add(p);
90 } 114 }
91 115
92 private File fncacheFile() { 116 private File fncacheFile() {
93 return repo.getFileFromStoreDir("fncache"); 117 return repo.getFileFromStoreDir("fncache");
94 } 118 }