mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-22 21:32:31 +00:00
Rewrite ZipOS
This reduces the virtual memory usage of Emacs for me by 30%. We now have a simpler implementation that uses read(), rather mmap()ing the whole executable.
This commit is contained in:
parent
ff77f2a6af
commit
b01282e23e
21 changed files with 408 additions and 421 deletions
|
@ -77,8 +77,8 @@ struct dirstream {
|
|||
struct {
|
||||
struct Zipos *zipos;
|
||||
uint64_t inode;
|
||||
uint64_t offset;
|
||||
uint64_t records;
|
||||
int offset;
|
||||
int records;
|
||||
struct ZiposUri prefix;
|
||||
struct critbit0 found;
|
||||
} zip;
|
||||
|
@ -298,7 +298,7 @@ DIR *fdopendir(int fd) {
|
|||
// ensure open /zip/... file is a directory
|
||||
struct ZiposHandle *h = (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle;
|
||||
if (h->cfile != ZIPOS_SYNTHETIC_DIRECTORY &&
|
||||
!S_ISDIR(GetZipCfileMode(h->zipos->map + h->cfile))) {
|
||||
!S_ISDIR(GetZipCfileMode(h->zipos->cdir + h->cfile))) {
|
||||
free(dir);
|
||||
enotdir();
|
||||
return 0;
|
||||
|
@ -308,8 +308,8 @@ DIR *fdopendir(int fd) {
|
|||
size_t len;
|
||||
const char *name;
|
||||
if (h->cfile != ZIPOS_SYNTHETIC_DIRECTORY) {
|
||||
len = ZIP_CFILE_NAMESIZE(h->zipos->map + h->cfile);
|
||||
name = ZIP_CFILE_NAME(h->zipos->map + h->cfile);
|
||||
len = ZIP_CFILE_NAMESIZE(h->zipos->cdir + h->cfile);
|
||||
name = ZIP_CFILE_NAME(h->zipos->cdir + h->cfile);
|
||||
} else {
|
||||
len = h->size;
|
||||
name = (const char *)h->data;
|
||||
|
@ -328,8 +328,8 @@ DIR *fdopendir(int fd) {
|
|||
|
||||
// setup state values for directory iterator
|
||||
dir->zip.zipos = h->zipos;
|
||||
dir->zip.offset = GetZipCdirOffset(h->zipos->cdir);
|
||||
dir->zip.records = GetZipCdirRecords(h->zipos->cdir);
|
||||
dir->zip.offset = 0;
|
||||
dir->zip.records = h->zipos->cnt;
|
||||
dir->zip.inode = __zipos_inode(h->zipos, h->cfile, dir->zip.prefix.path,
|
||||
dir->zip.prefix.len);
|
||||
|
||||
|
@ -397,8 +397,8 @@ static struct dirent *readdir_zipos(DIR *dir) {
|
|||
ent->d_ino = __zipos_inode(
|
||||
dir->zip.zipos, __zipos_scan(dir->zip.zipos, &p), p.path, p.len);
|
||||
} else {
|
||||
const char *s = ZIP_CFILE_NAME(dir->zip.zipos->map + dir->zip.offset);
|
||||
size_t n = ZIP_CFILE_NAMESIZE(dir->zip.zipos->map + dir->zip.offset);
|
||||
const char *s = ZIP_CFILE_NAME(dir->zip.zipos->cdir + dir->zip.offset);
|
||||
size_t n = ZIP_CFILE_NAMESIZE(dir->zip.zipos->cdir + dir->zip.offset);
|
||||
if (n > dir->zip.prefix.len &&
|
||||
!memcmp(dir->zip.prefix.path, s, dir->zip.prefix.len)) {
|
||||
s += dir->zip.prefix.len;
|
||||
|
@ -408,7 +408,7 @@ static struct dirent *readdir_zipos(DIR *dir) {
|
|||
if (p) {
|
||||
n = p - s;
|
||||
d_type = DT_DIR;
|
||||
} else if (S_ISDIR(GetZipCfileMode(dir->zip.zipos->map +
|
||||
} else if (S_ISDIR(GetZipCfileMode(dir->zip.zipos->cdir +
|
||||
dir->zip.offset))) {
|
||||
d_type = DT_DIR;
|
||||
} else {
|
||||
|
@ -425,7 +425,7 @@ static struct dirent *readdir_zipos(DIR *dir) {
|
|||
}
|
||||
}
|
||||
dir->zip.offset +=
|
||||
ZIP_CFILE_HDRSIZE(dir->zip.zipos->map + dir->zip.offset);
|
||||
ZIP_CFILE_HDRSIZE(dir->zip.zipos->cdir + dir->zip.offset);
|
||||
}
|
||||
dir->tell++;
|
||||
}
|
||||
|
@ -611,7 +611,7 @@ void rewinddir(DIR *dir) {
|
|||
if (dir->iszip) {
|
||||
critbit0_clear(&dir->zip.found);
|
||||
dir->tell = 0;
|
||||
dir->zip.offset = GetZipCdirOffset(dir->zip.zipos->cdir);
|
||||
dir->zip.offset = 0;
|
||||
} else if (!IsWindows()) {
|
||||
if (!lseek(dir->fd, 0, SEEK_SET)) {
|
||||
dir->buf_pos = dir->buf_end = 0;
|
||||
|
@ -637,7 +637,7 @@ void seekdir(DIR *dir, long tell) {
|
|||
if (dir->iszip) {
|
||||
critbit0_clear(&dir->zip.found);
|
||||
dir->tell = 0;
|
||||
dir->zip.offset = GetZipCdirOffset(dir->zip.zipos->cdir);
|
||||
dir->zip.offset = 0;
|
||||
while (dir->tell < tell) {
|
||||
if (!readdir_zipos(dir)) {
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue