Skip to content

Commit

Permalink
Add support for -metadata / -pages VFS root attrs
Browse files Browse the repository at this point in the history
  • Loading branch information
chpock committed Oct 16, 2024
1 parent a965a4b commit cf2ee99
Show file tree
Hide file tree
Showing 20 changed files with 1,543 additions and 289 deletions.
6 changes: 6 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
2024-10-16 Konstantin Kushnir <[email protected]>
* Add support for -metadata for VFS root attributes
* Add support for -pages for VFS root attributes
* Store pagesize/smallfilesize/smallfilebuffer properties as fsindex
metadata and use these values after reopening

2024-10-13 Konstantin Kushnir <[email protected]>
* Cleanup sources

Expand Down
2 changes: 1 addition & 1 deletion configure
Original file line number Diff line number Diff line change
Expand Up @@ -9822,7 +9822,7 @@ then

COOKFS_PKGCONFIG_USECVFS=1

vars="vfsDriver.c vfsVfs.c vfs.c vfsCmd.c"
vars="vfsDriver.c vfsVfs.c vfs.c vfsCmd.c vfsAttributes.c"
for i in $vars; do
case $i in
\$*)
Expand Down
2 changes: 1 addition & 1 deletion configure.in
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ then

AC_DEFINE(COOKFS_USECVFS)
COOKFS_PKGCONFIG_USECVFS=1
TEA_ADD_SOURCES([vfsDriver.c vfsVfs.c vfs.c vfsCmd.c])
TEA_ADD_SOURCES([vfsDriver.c vfsVfs.c vfs.c vfsCmd.c vfsAttributes.c])

else
COOKFS_PKGCONFIG_USECWRITER=0
Expand Down
33 changes: 33 additions & 0 deletions generic/cookfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,34 @@
#include "cryptoCmd.h"
#endif /* COOKFS_USECCRYPTO */

#if defined(TCL_MEM_DEBUG)

#ifdef COOKFS_USECVFS
#include "vfsAttributes.h"
#endif /* COOKFS_USECVFS */
#ifdef COOKFS_USECPAGES
#include "pgindex.h"
#endif /* COOKFS_USECPAGES */

static int CookfsResetCacheCmd(ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj * const objv[])
{

UNUSED(clientData);
UNUSED(interp);
UNUSED(objc);
UNUSED(objv);
#ifdef COOKFS_USECVFS
CookfsVfsAttributesThreadExit(NULL);
#endif /* COOKFS_USECVFS */
#ifdef COOKFS_USECPAGES
CookfsPgIndexThreadExit(NULL);
#endif /* COOKFS_USECPAGES */
return TCL_OK;
}

#endif /* defined(TCL_MEM_DEBUG) */

/*
*----------------------------------------------------------------------
*
Expand Down Expand Up @@ -146,6 +174,11 @@ Cookfs_Init(Tcl_Interp *interp) // cppcheck-suppress unusedFunction
}
#endif

#if defined(TCL_MEM_DEBUG)
Tcl_CreateObjCommand(interp, "::cookfs::c::reset_cache",
CookfsResetCacheCmd, (ClientData) NULL, NULL);
#endif /* defined(TCL_MEM_DEBUG) */

if (Tcl_PkgProvide(interp, PACKAGE_NAME "::c", PACKAGE_VERSION) != TCL_OK) {
return TCL_ERROR;
}
Expand Down
50 changes: 50 additions & 0 deletions generic/fsindex.c
Original file line number Diff line number Diff line change
Expand Up @@ -1632,6 +1632,56 @@ Tcl_Obj *Cookfs_FsindexGetMetadata(Cookfs_Fsindex *i, const char *paramName) {
}
}

/*
Tcl_Obj *Cookfs_FsindexGetMetadataAll(Cookfs_Fsindex *i) {
Cookfs_FsindexWantRead(i);
Tcl_Obj *result = Tcl_NewDictObj();
Tcl_HashSearch hSearch;
for (Tcl_HashEntry *hPtr = Tcl_FirstHashEntry(&i->metadataHash, &hSearch);
hPtr != NULL; hPtr = Tcl_NextHashEntry(&hSearch))
{
Tcl_Obj *keyObj = Tcl_NewStringObj((const char *)Tcl_GetHashKey(
&i->metadataHash, hPtr), -1);
unsigned char *valueStr = Tcl_GetHashValue(hPtr);
Tcl_Obj *valueObj = Tcl_NewByteArrayObj(valueStr + sizeof(Tcl_Size),
*((Tcl_Size *)valueStr));
Tcl_DictObjPut(NULL, result, keyObj, valueObj);
}
return result;
}
*/

Tcl_Obj *Cookfs_FsindexGetMetadataAllKeys(Cookfs_Fsindex *i) {

Cookfs_FsindexWantRead(i);

Tcl_Obj *result = Tcl_NewListObj(0, NULL);
Tcl_HashSearch hSearch;

for (Tcl_HashEntry *hPtr = Tcl_FirstHashEntry(&i->metadataHash, &hSearch);
hPtr != NULL; hPtr = Tcl_NextHashEntry(&hSearch))
{

Tcl_Obj *keyObj = Tcl_NewStringObj((const char *)Tcl_GetHashKey(
&i->metadataHash, hPtr), -1);

Tcl_ListObjAppendElement(NULL, result, keyObj);

}

return result;

}


/*
*----------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions generic/fsindex.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ Cookfs_FsindexEntry **Cookfs_FsindexList(Cookfs_Fsindex *i, Cookfs_PathObj *path
Cookfs_FsindexEntry **Cookfs_FsindexListEntry(Cookfs_FsindexEntry *dirNode, int *itemCountPtr);
void Cookfs_FsindexListFree(Cookfs_FsindexEntry **items);

// Tcl_Obj *Cookfs_FsindexGetMetadataAll(Cookfs_Fsindex *i);
Tcl_Obj *Cookfs_FsindexGetMetadataAllKeys(Cookfs_Fsindex *i);
Tcl_Obj *Cookfs_FsindexGetMetadata(Cookfs_Fsindex *i, const char *paramName);
void Cookfs_FsindexSetMetadata(Cookfs_Fsindex *i, const char *paramName, Tcl_Obj *data);
void Cookfs_FsindexSetMetadataRaw(Cookfs_Fsindex *i, const char *paramName,
Expand Down
62 changes: 42 additions & 20 deletions generic/pages.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,18 @@ int Cookfs_PagesIsEncryptionActive(Cookfs_Pages *p) {

#endif /* COOKFS_USECCRYPTO */

Tcl_Obj *Cookfs_PagesGetInfo(Cookfs_Pages *p, int num) {
Cookfs_PagesWantRead(p);
return Cookfs_PgIndexGetInfo(p->pagesIndex, num);
}

Tcl_Obj *Cookfs_PagesGetInfoSpecial(Cookfs_Pages *p,
Cookfs_PgIndexSpecialPageType type)
{
Cookfs_PagesWantRead(p);
return Cookfs_PgIndexGetInfoSpecial(p->pagesIndex, type);
}

/*
*----------------------------------------------------------------------
*
Expand Down Expand Up @@ -3210,21 +3222,18 @@ skipEncryption: ; // empty statement
&pgindexSizeUncompressed, 1);
int pgindexCompression = buf[COOKFS_SUFFIX_OFFSET_PGINDEX_COMPRESSION]
& 0xff;
int pgindexCompressionLevel = buf[COOKFS_SUFFIX_OFFSET_PGINDEX_LEVEL]
& 0xff;
unsigned char *pgindexHashMD5 = &buf[COOKFS_SUFFIX_OFFSET_PGINDEX_HASH];

Tcl_Size pgindexOffset;
Tcl_Size pgindexOffset = p->foffset - COOKFS_SUFFIX_BYTES -
pgindexSizeCompressed - fsindexSizeCompressed;
// If we are using a memory-mapped file, calculate the pgindex offset.
// Otherwise, we use -1 as an offset to read subsequent data from the file.
if (p->fileChannel == NULL) {
pgindexOffset = p->foffset - COOKFS_SUFFIX_BYTES -
pgindexSizeCompressed - fsindexSizeCompressed;
} else {
pgindexOffset = -1;
}

Cookfs_PageObj pgindexDataObj = Cookfs_ReadPage(p, pgindexOffset,
pgindexCompression, pgindexSizeCompressed, pgindexSizeUncompressed,
pgindexHashMD5, 1, isIndexEncrypted, &local_error);
Cookfs_PageObj pgindexDataObj = Cookfs_ReadPage(p,
(p->fileChannel == NULL ? pgindexOffset : -1), pgindexCompression,
pgindexSizeCompressed, pgindexSizeUncompressed, pgindexHashMD5, 1,
isIndexEncrypted, &local_error);

if (pgindexDataObj == NULL) {
CookfsLog(printf("unable to read or decompress pgindex"));
Expand Down Expand Up @@ -3276,19 +3285,16 @@ skipEncryption: ; // empty statement
&fsindexSizeUncompressed, 1);
int fsindexCompression = buf[COOKFS_SUFFIX_OFFSET_FSINDEX_COMPRESSION]
& 0xff;
int fsindexCompressionLevel = buf[COOKFS_SUFFIX_OFFSET_FSINDEX_LEVEL]
& 0xff;
unsigned char *fsindexHashMD5 = &buf[COOKFS_SUFFIX_OFFSET_FSINDEX_HASH];

Tcl_Size fsindexOffset;
Tcl_Size fsindexOffset = p->foffset - COOKFS_SUFFIX_BYTES -
fsindexSizeCompressed;
// If we are using a memory-mapped file, calculate the pgindex offset.
// Otherwise, we use -1 as an offset to read subsequent data from the file.
if (p->fileChannel == NULL) {
fsindexOffset = p->foffset - COOKFS_SUFFIX_BYTES -
fsindexSizeCompressed;
} else {
fsindexOffset = -1;
}

p->dataIndex = Cookfs_ReadPage(p, fsindexOffset, fsindexCompression,
p->dataIndex = Cookfs_ReadPage(p,
(p->fileChannel == NULL ? fsindexOffset : -1), fsindexCompression,
fsindexSizeCompressed, fsindexSizeUncompressed, fsindexHashMD5, 1,
isIndexEncrypted, &local_error);

Expand Down Expand Up @@ -3331,6 +3337,22 @@ skipEncryption: ; // empty statement
if (p->pagesIndex != NULL) {
p->dataInitialOffset -= Cookfs_PgIndexGetStartOffset(p->pagesIndex,
Cookfs_PgIndexGetLength(p->pagesIndex));
} else {
p->pagesIndex = Cookfs_PgIndexInit(0);
}

if (fsindexSizeCompressed != 0) {
Cookfs_PgIndexAddPageSpecial(p->pagesIndex,
(Cookfs_CompressionType)fsindexCompression, fsindexCompressionLevel,
isIndexEncrypted, fsindexSizeCompressed, fsindexSizeUncompressed,
fsindexOffset, COOKFS_PGINDEX_SPECIAL_PAGE_TYPE_FSINDEX);
}

if (pgindexSizeCompressed != 0) {
Cookfs_PgIndexAddPageSpecial(p->pagesIndex,
(Cookfs_CompressionType)pgindexCompression, pgindexCompressionLevel,
isIndexEncrypted, pgindexSizeCompressed, pgindexSizeUncompressed,
pgindexOffset, COOKFS_PGINDEX_SPECIAL_PAGE_TYPE_PGINDEX);
}

if (p->dataInitialOffset < 0) {
Expand Down
5 changes: 5 additions & 0 deletions generic/pages.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define COOKFS_PAGES_H 1

#include "pageObj.h"
#include "pgindex.h"

typedef struct _Cookfs_Pages Cookfs_Pages;

Expand Down Expand Up @@ -79,6 +80,10 @@ void Cookfs_PagesCalculateHash(Cookfs_Pages *p, unsigned char *bytes,

int Cookfs_PageAddStamp(Cookfs_Pages *p, Tcl_WideInt size);

Tcl_Obj *Cookfs_PagesGetInfo(Cookfs_Pages *p, int num);
Tcl_Obj *Cookfs_PagesGetInfoSpecial(Cookfs_Pages *p,
Cookfs_PgIndexSpecialPageType type);

#ifdef COOKFS_USECCRYPTO
int Cookfs_PagesIsEncryptionActive(Cookfs_Pages *p);
#endif /* COOKFS_USECCRYPTO */
Expand Down
16 changes: 14 additions & 2 deletions generic/pagesCompr.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@
*/

#include "cookfs.h"
#include "pages.h"
#include "pagesInt.h"
#include "pagesCompr.h"
#include "pagesInt.h"
#include "pagesComprZlib.h"
#if defined(COOKFS_USECALLBACKS)
#include "pagesComprCustom.h"
Expand Down Expand Up @@ -130,6 +129,19 @@ static int Cookfs_CompressionGetDefaultLevel(Cookfs_CompressionType compression)
}
}

Tcl_Obj *Cookfs_CompressionToObj(Cookfs_CompressionType compression,
int compressionLevel)
{
if (compressionLevel == -1 || compressionLevel ==
Cookfs_CompressionGetDefaultLevel(compression))
{
return Tcl_NewStringObj(Cookfs_CompressionGetName(compression), -1);
} else {
return Tcl_ObjPrintf("%s:%d", Cookfs_CompressionGetName(compression),
compressionLevel);
}
}

/*
*----------------------------------------------------------------------
*
Expand Down
4 changes: 4 additions & 0 deletions generic/pagesCompr.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@
#ifndef COOKFS_PAGESCOMPR_H
#define COOKFS_PAGESCOMPR_H 1

#include "pages.h"

/* let's gain at least 16 bytes and/or 5% to compress it */
#define SHOULD_COMPRESS(p, origSize, size) ((p->alwaysCompress) || ((size < (origSize - 16)) && ((size) <= (origSize - (origSize / 20)))))

const char *Cookfs_CompressionGetName(Cookfs_CompressionType compression);

Tcl_Obj *Cookfs_CompressionToObj(Cookfs_CompressionType compression,
int compressionLevel);
int Cookfs_CompressionFromObj(Tcl_Interp *interp, Tcl_Obj *obj,
Cookfs_CompressionType *compressionPtr, int *compressionLevelPtr);

Expand Down
Loading

0 comments on commit cf2ee99

Please sign in to comment.