The Storage Kit Table of Contents     The Storage Kit Index

Index C Functions

Declared in: be/kernel/fs_index.h

Library: libroot.so

Before a query can be performed on a file system, indices need to be established in which to search. An index contains a list of files that can be searched given a particular attribute and the desired value.

An index directory is, essentially, a list of the indices on a particular disk; it keeps track of the attributes that can be searched upon. Each disk has its own index directory. For instance, a disk might have the following indices in its index directory:

Each of these is the name of an index that can be queried using either the fs_query API or the BQuery class.

For example, if an e-mail program wishes to allow searching on the name of the sender of a message, it needs to create an index for the "sender" attribute. Once this index is established, any file that has the "sender" attribute added to it will be added to the "sender" index.

Files which had the "sender" attribute attached before the "sender" index was created, however, will not be in the index until their "sender" attribute is updated, at which time they will be added to the index. For this reason, you should consider installing your indices when your application is installed, or when it is initially launched.

Since each disk has its own index directory, if you want all disks to have your indices available, you need to create them on each device. You can do this by using the functions described here in conjunction with the fs_info functions.

There are three indices that are present on every disk:

Index Meaning
name The name of the file.
size The size, in bytes, of the file.
last_modified The date the file was last changed.

You can always perform queries in these indices. Their names are reserved; you can't create or remove indices by these names.


The Index Directory

The following sample function opens the index directory for a specified device and, in a loop, reads every entry, printing their names to standard output. This presents a list of each index available on the disk.

   void ListIndex(int32 device) 
   {
      DIR *d;
      index_info info;
      struct dirent *ent;
      
      d = fs_open_index_dir(device);
      if (!d) {
         fprintf(stderr, "Unable to open index.n");
         return;
      }
   
      while (ent = fs_read_index_dir(d)) {
         printf("%sn", ent->d_name);
      }
      fs_close_index_dir(d);
   }

After calling fs_open_index_dir() to open the index directory for the device passed into the function (and handling the error that might occur if that function fails), a while loop iterates through all the entries in the directory, calling fs_read_index_dir() to obtain the desired information, then printing that information to standard output.

When there are no indices left, fs_read_index_dir() returns NULL and the while loop exits. At this point, fs_close_index_dir() is called to close the index directory.


Installing and Removing Indices

To install a new index, use the fs_create_index() function. For example, to create an index for the attribute "GOLF:Handicap" on device 4 you would do this:

   fs_create_index(4, "GOLF:Handicap", B_INT16_TYPE, 0);

This creates an empty index for the golf handicap attribute, which is stored as a 16-bit integer. Once the index has been created, any file that gets a "GOLF:Handicap" attribute added or changed will be indexed.

(You usually shouldn't hard-code a device number, of course; you can obtain a device number for a specific disk by using the fs_info functions or stat().)

If you later need to remove the index, you can do so by calling fs_remove_index(), like this:

   fs_remove_index(4, "GOLF:Handicap");

You should be careful when deciding to delete an index. If the user still has files around that contain indexed attributes that they want to be able to search for—using the Find panel in the Tracker, for example—they will not be able to do so after the index has been removed. So you need to decide when it is appropriate to remove indices; the choice is yours, but choose wisely, or you might annoy users.


Index Functions


fs_close_index_dir()

                                                         
  

int fs_close_index_dir(DIR *dirp)

Closes the specified index directory and frees dirp. You should pass into this function the pointer returned from a previous fs_open_index_dir().

You should always use this function to close index directories after you finish using them.

If successful, this function returns 0; otherwise it returns -1and sets errno to one of the following codes.


fs_create_index()

                                                         
  

int fs_create_index(dev_t device,
      const char *name,
      int type,
      uint flags)

Creates a new index called name on the specified device. Once this has been done, adding an attribute named name to a file causes the file to be added to the name index, such that subsequent queries will be able to search for files that contain the name attribute.

type indicates the kind of data the attribute will contain. Standard types are defined in the be/support/TypeConstants.h header file. Different file systems may support different types. BFS supports the following types of attributes:

flags is currently unused and should always be 0.

If successful, this function returns 0; otherwise it returns -1and sets errno to one of the following codes.


fs_open_index_dir()

                                                         
  

DIR *fs_open_index_dir(dev_t device)

Opens the index directory for the volume identified by device. Once open, you can retrieve the names of the indices on the volume by calling fs_read_index_dir().

When you have finished using the index directory, call fs_close_index_dir() to close it.

If the index directory is opened successfully, a pointer to a directory structure is returned. This pointer should be passed to the other fs_index functions to read entries from the index directory, as well as to close the directory when you're finished with it.

If an error occurs while opening the index directory, this function returns NULL and sets errno to an appropriate value.


fs_read_index_dir()

                                                         
  

struct dirent *fs_read_index_dir(DIR *dirp)

Reads the current entry from the open index directory referenced by dirp, and bumps the pointer to point to the next entry. dirp should have been obtained through a previous call to fs_open_index_dir(). The returned dirent pointer contains information about the index entry, including the name of the attribute represented by the index. This pointer belongs to the system; you must not delete it.

Through repeated calls to fs_read_index_dir(), you can obtain a list of all the indices available on the device. When you reach the end of the list, errno is set to B_ENTRY_NOT_FOUND.

If an error occurs, this function returns NULL and sets errno to an appropriate value.


fs_remove_index()

                                                         
  

int fs_remove_index(dev_t device, const char *index_name)

Deletes the index named index_name from the specified device. Once the index is deleted, it will no longer be possible to use the query system to search for files with the corresponding attribute.

Use this function to remove an index that you no longer wish or need to be able to search upon. For example, if your application is being uninstalled by your user-friendly uninstaller program, and it's no longer meaningful to be able to search on a given attribute, you should use this function to delete the index for that attribute.

You should be careful when deciding whether or not to delete an index, however. If the user still has files around that they want to be able to search, using the Tracker's Find panel, for instance, and you've deleted the index for that attribute, they'll be most displeased. There's a grey area you need to wade through in determining whether or not to delete your indices; your decision needs to be based on the specifics of what your application does and how it will be used.

If the index is removed successfully, fs_remove_index() returns 0. Otherwise, it returns -1 and sets errno to an appropriate value.


fs_rewind_index_dir()

                                                         
  

int fs_rewind_index_dir(DIR *dirp)

Rewinds the specified index directory to the beginning of its list of indices. This allows you to start over again at the top of a device's index directory and make your way down toward the bottom.

Returns a result code specifying whether or not the operation was successful.

 
Unlike the most of the other file system functions, fs_rewind_index_dir() doesn't set errno.


RETURN CODES


fs_stat_index()

                                                         
  

int fs_stat_index(dev_t device,
      const char *index_name,
      struct index_info *info)

Returns, in the index_info structure pointed to by info, information about the index named index_name on the specified device.

The index_info structure is defined as follows:

   typedef struct index_info
   {
      uint32      type;
      off_t      size;
      time_t      modification_time;
      time_t      creation_time;
      uid_t      uid;
      gid_t      gid;
   }

type contains a code defining the format of the data contained by the attribute represented by the index; standard values for this field are defined in the be/support/TypeConstants.h header file.

If the function is successful, it returns 0; otherwise, it returns -1 and sets errno to an appropriate value


The Storage Kit Table of Contents     The Storage Kit Index


The Be Book,
...in lovely HTML...
for BeOS Release 5.

Copyright © 2000 Be, Inc. All rights reserved..