typedef struct node *Nptr;
typedef struct key {
- char *name;
+ normchar_t *name; /* Normalized name */
} keyT;
-
typedef struct dirdata {
cm_fid_t fid;
- char * longname;
+ int shortform; /* This is the short form entry. If
+ this value is non-zero, then there
+ is another entry in the B-Plus tree
+ corresponding to the long name of
+ this fid. */
+ clientchar_t *cname; /* Client name (long) */
+ fschar_t * fsname; /* FileServer name */
} dataT;
typedef struct entry {
unsigned int height; /* nodes traversed from root to leaves */
Nptr pool; /* list of all nodes */
Nptr empty; /* list of empty nodes */
- keyT theKey; /* the key value used in tree operations */
- dataT theData; /* data used for insertions/deletions */
union { /* nodes to change in insert and delete */
- Nptr split;
+ Nptr split; /* protected by scp->dirlock write-lock */
Nptr merge;
} branch;
KeyCmp keycmp; /* pointer to function comparing two keys */
Nptr lookup(Tree *B, keyT key);
/******************* cache manager directory operations ***************/
-int cm_BPlusDirLookup(cm_dirOp_t * op, char *entry, cm_fid_t * cfid);
-long cm_BPlusDirCreateEntry(cm_dirOp_t * op, char *entry, cm_fid_t * cfid);
-int cm_BPlusDirDeleteEntry(cm_dirOp_t * op, char *entry);
+
+int cm_BPlusCompareNormalizedKeys(keyT key1, keyT key2, int flags);
+int cm_BPlusDirLookup(cm_dirOp_t * op, clientchar_t *entry, cm_fid_t * cfid);
+int cm_BPlusDirLookupOriginalName(cm_dirOp_t * op, clientchar_t *entry, fschar_t **originalNameRetp);
+long cm_BPlusDirCreateEntry(cm_dirOp_t * op, clientchar_t *entry, cm_fid_t * cfid);
+int cm_BPlusDirDeleteEntry(cm_dirOp_t * op, clientchar_t *entry);
long cm_BPlusDirBuildTree(cm_scache_t *scp, cm_user_t *userp, cm_req_t* reqp);
void cm_BPlusDumpStats(void);
+int cm_MemDumpBPlusStats(FILE *outputFile, char *cookie, int lock);
+
+/******************* directory enumeration operations ****************/
+typedef struct cm_direnum_entry {
+ clientchar_t *name;
+ cm_fid_t fid;
+ normchar_t shortName[13];
+ afs_uint32 flags;
+} cm_direnum_entry_t;
+
+#define CM_DIRENUM_FLAG_GOT_STATUS 1
+
+typedef struct cm_direnum {
+ cm_scache_t *dscp;
+ cm_user_t *userp;
+ afs_uint32 reqFlags;
+ afs_uint32 count;
+ afs_uint32 next;
+ cm_direnum_entry_t entry[1];
+} cm_direnum_t;
+
+long cm_BPlusDirEnumerate(cm_scache_t *dscp, cm_user_t *userp, cm_req_t *reqp,
+ afs_uint32 locked, clientchar_t *maskp, cm_direnum_t **enumpp);
+long cm_BPlusDirNextEnumEntry(cm_direnum_t *enump, cm_direnum_entry_t **entrypp);
+long cm_BPlusDirFreeEnumeration(cm_direnum_t *enump);
+long cm_BPlusDirEnumTest(cm_scache_t * dscp, cm_user_t *userp, cm_req_t *reqp, afs_uint32 locked);
+long cm_BPlusDirEnumBulkStat(cm_direnum_t *enump);
+
+long cm_InitBPlusDir(void);
+
+/************ Statistic Counter ***************************************/
extern afs_uint32 bplus_free_tree;
extern afs_uint32 bplus_dv_error;
extern afs_uint64 bplus_free_time;
+
/************ Accessor Macros *****************************************/
/* low level definition of Nptr value usage */
/* access keys and pointers in a node */
#define getkey(j, q) (nAdr(j).e[(q)].key)
#define getnode(j, q) (nAdr(j).e[(q)].downNode)
-#define setkey(j, q, v) ((q > 0) ? nAdr(j).e[(q)].key.name = strdup((v).name) : NULL)
+#define setkey(j, q, v) ((q > 0) ? nAdr(j).e[(q)].key.name = cm_NormStrDup((v).name) : NULL)
#define setnode(j, q, v) (nAdr(j).e[(q)].downNode = (v))
/* access tree flag values */
#define xferentry(j, q, v, z) _xferentry(j, q, v, z)
#define setentry(j, q, v, z) _setentry(j, q, v, z)
-
-/* access key and data values for B+tree methods */
-/* pass values to getSlot(), descend...() */
-#define getfunkey(B) ((B)->theKey)
-#define getfundata(B) ((B)->theData)
-#define setfunkey(B,v) ((B)->theKey = (v))
-#define setfundata(B,v) ((B)->theData = (v))
-
/* define number of B+tree nodes for free node pool */
#define getpoolsize(B) ((B)->poolsize)
#define setpoolsize(B,v) ((B)->poolsize = (v))