code: @Override
  	public void defineIndex(ZooClassDef def, ZooFieldDef field, boolean isUnique) {
  		SchemaIndexEntry se = schemaIndex.getSchema(def);
  		LongLongIndex fieldInd = se.defineIndex(field, isUnique);
  		
  		//fill index with existing objects
  		PagedPosIndex ind = se.getObjectIndexLatestSchemaVersion();
  		PagedPosIndex.ObjectPosIterator iter = ind.iteratorObjects();
          DataDeSerializerNoClass dds = new DataDeSerializerNoClass(fileInAP);
          if (field.isPrimitiveType()) {
  			while (iter.hasNext()) {
  				long pos = iter.nextPos();
  				dds.seekPos(pos);
  				//first read the key, then afterwards the field!
  				long key = dds.getAttrAsLong(def, field);
  				if (isUnique) {
  					if (!fieldInd.insertLongIfNotSet(key, dds.getLastOid())) {
  						throw DBLogger.newUser("Duplicate entry in unique index: " +
  								Util.oidToString(dds.getLastOid()) + "  v=" + key);
  					}
  				} else {
  					fieldInd.insertLong(key, dds.getLastOid());
  				}
  			}
          } else {
  			while (iter.hasNext()) {
  				long pos = iter.nextPos();
  				dds.seekPos(pos);
  				//first read the key, then afterwards the field!
  				long key = dds.getAttrAsLongObjectNotNull(def, field);
  				fieldInd.insertLong(key, dds.getLastOid());
  				//TODO handle null values:
  				//-ignore them?
  				//-use special value?
  			}
  			//DatabaseLogger.debugPrintln(0, "FIXME defineIndex()");
          }
          iter.close();
  	}
docs: Defines an index and populates it. All objects are put into the cache. This is not
  necessarily useful, but it is a one-off operation. Otherwise we would need a special
  purpose implementation of the deserializer, which would have the need for a cache removed.