简体   繁体   English

在J2ME中,如何在删除任何记录后重新索引记录库中的记录

[英]In J2ME, How to re-index records in recordstore after deleting any record

I am developing a Location-based J2ME app & in that I'm using RMS to store data. 我正在开发基于位置的J2ME应用程序,因为我正在使用RMS来存储数据。

In RecordStore when I delete any record, the underlying records doesn't get re-indexed. RecordStore当我删除任何记录时,底层记录不会被重新编入索引。 For example, if I have 5 records & I delete record no.2 then record ids will be {1, 3, 4, 5}. 例如,如果我有5条记录并删除了第2条记录,则记录ID将为{1,3,4,5}。 But I want record ids after deletion to be {1, 2, 3, 4}. 但我希望删除后的记录ID为{1,2,3,4}。 How should I do this??? 我该怎么办? Because recordId is playing an important role in my app to retrieve & update the record. 因为recordId在我的应用程序中扮演重要角色来检索和更新记录。

You need to change your application logic. 您需要更改应用程序逻辑。 ID is just for identification, and not for sorting. ID仅用于标识,而不用于排序。 Because it is for identification, it must remains the same. 因为它是用于识别,它必须保持不变。

Very often the easiest thing to do is to read and write the whole recordstore at once. 通常最简单的方法是立即读取和写入整个记录库。

So, since you've said that your record store is basically small (not that much data), I would recommend simply adding your own custom id field to each record. 所以,既然你已经说过你的唱片商店基本上很小(不是那么多的数据),我建议你只需要为每条记录添加你自己的自定义id字段。 As Meier said , the RMS record id is not really meant to be recalculated, and changed, once a record has been created. 正如Meier所说 ,一旦创建了一条记录,RMS记录ID并不是真的要重新计算和更改。 So, I would use your own. 所以,我会用你自己的。

If each of your records contain: 如果您的每条记录包含:

boolean isMale
int age
String firstName

then, I would simply add another field at the start of each record: 那么,我只想在每条记录的开头添加另一个字段:

int id

It makes your records a little bigger, but not much (4 bytes/record). 它使你的记录更大,但不多(4字节/记录)。 If you'll have less than 64k records, then you could also use a short for the id , and save a couple bytes. 如果你的记录少于64k,那么你也可以使用short作为id ,并保存几个字节。

Here's an example ( adapted from this IBM tutorial ), of reading, writing, and deleting with this kind of record: 以下是使用此类记录进行读取,写入和删除的示例( 根据此IBM教程改编 ):

   private RecordStore _rs;

   // these next two methods are just small optimizations, to allow reading and 
   //  updating the ID field in a record without the overhead of creating a new
   //  stream to call readInt() on.  this assumes the id is a 4 byte int, written
   //  as the first field in each record.

   /** Update one record with a new id field */
   private static final void putIdIntoRecord(int id, byte[] record) {      
      // we assume the first 4 bytes are the id (int)
      record[0] = (byte)(id >> 24);
      record[1] = (byte)(id >> 16);
      record[2] = (byte)(id >> 8);
      record[3] = (byte)id;
   }

   /** Get the id field from one record */
   private static final int getIdFromRecord(byte[] record) {
      // we assume the first 4 bytes are the id (int)
      return ((0xFF & record[0]) << 24) | 
            ((0xFF & record[1]) << 16) | 
            ((0xFF & record[2]) << 8) | 
            (0xFF & record[3]);
   }

   /** delete a record with the given (custom) id, re-indexing records afterwards */
   private void delete(int idToDelete) {     
      try {
         RecordEnumeration enumerator = _rs.enumerateRecords(new IdEqualToFilter(idToDelete), 
               null, false);
         _rs.deleteRecord(enumerator.nextRecordId());

         // now, re-index records after 'idToDelete'
         enumerator = _rs.enumerateRecords(new IdGreaterThanFilter(idToDelete), null, true);
         while (enumerator.hasNextElement()) {
            int recordIdToUpdate = enumerator.nextRecordId();
            byte[] record = _rs.getRecord(recordIdToUpdate);
            // decrement the id by 1
            int newId = getIdFromRecord(record) - 1;
            // copy the new id back into the record
            putIdIntoRecord(newId, record);
            // update the record, which now has a lower id, in the store
            _rs.setRecord(recordIdToUpdate, record, 0, record.length);
         }
      } catch (RecordStoreNotOpenException e) {
         e.printStackTrace();
      } catch (InvalidRecordIDException e) {
         e.printStackTrace();
      } catch (RecordStoreException e) {
         e.printStackTrace();
      }               
   }

   /** generate some record store data ... example of writing to store */
   public void writeTestData()
   {
      // just put 20 random records into the record store
      boolean[] booleans = new boolean[20];
      int[] integers = new int[20];
      String[] strings = new String[20];
      for (int i = 0; i < 20; i++) {
         booleans[i] = (i % 2 == 1);
         integers[i] = i * 2;
         strings[i] = "string-" + i;
      }

      writeRecords(booleans, integers, strings);
   }

   /** take the supplied arrays of data, and save a record for each array index */
   public void writeRecords(boolean[] bData, int[] iData, String[] sData)
   {
      try
      {
         // Write data into an internal byte array
         ByteArrayOutputStream strmBytes = new ByteArrayOutputStream();

         // Write Java data types into the above byte array
         DataOutputStream strmDataType = new DataOutputStream(strmBytes);

         byte[] record;

         for (int i = 0; i < sData.length; i++)
         {
            // Write Java data types
            strmDataType.writeInt(i);               // this will be the ID field!
            strmDataType.writeBoolean(bData[i]);
            strmDataType.writeInt(iData[i]);
            strmDataType.writeUTF(sData[i]);

            // Clear any buffered data
            strmDataType.flush();

            // Get stream data into byte array and write record
            record = strmBytes.toByteArray();            
            _rs.addRecord(record, 0, record.length);           

            // Toss any data in the internal array so writes
            // starts at beginning (of the internal array)
            strmBytes.reset();
         }

         strmBytes.close();
         strmDataType.close();
      }
      catch (Exception e)
      {
         e.printStackTrace();
      }
   }

   /** read in all the records, and print them out */
   public void readRecords()
   {
      try
      {
         RecordEnumeration re = _rs.enumerateRecords(null, null, false);         
         while (re.hasNextElement())
         {    
            // Get next record
            byte[] recData = re.nextRecord(); 

            // Read from the specified byte array
            ByteArrayInputStream strmBytes = new ByteArrayInputStream(recData);

            // Read Java data types from the above byte array
            DataInputStream strmDataType = new DataInputStream(strmBytes);

            // Read back the data types
            System.out.println("Record ID=" + strmDataType.readInt());
            System.out.println("Boolean: " + strmDataType.readBoolean());
            System.out.println("Integer: " + strmDataType.readInt());
            System.out.println("String: " + strmDataType.readUTF());
            System.out.println("--------------------");

            strmBytes.close();
            strmDataType.close();        
         }
      }
      catch (Exception e)
      {
         e.printStackTrace();
      }
   }

Here, I make use of a couple small RecordFilter classes, to use when searching the record store: 在这里,我使用了几个小的RecordFilter类,在搜索记录存储时使用:

   /** helps filter out records greater than a certain id */
   private class IdGreaterThanFilter implements RecordFilter {
      private int _minimumId; 
      public IdGreaterThanFilter(int value) {
         _minimumId = value;
      }
      public boolean matches(byte[] candidate) {
         // return true if candidate record's id is greater than minimum value
         return (getIdFromRecord(candidate) > _minimumId);         
      }      
   }

   /** helps filter out records by id field (not "recordId"!) */
   private class IdEqualToFilter implements RecordFilter {
      private int _id; 
      public IdEqualToFilter(int value) {
         _id = value;
      }
      public boolean matches(byte[] candidate) {
         // return true if candidate record's id matches
         return (getIdFromRecord(candidate) == _id);         
      }      
   }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM