1. 07 10月, 2015 1 次提交
    • D
      Support for LevelDB SST with .ldb suffix · 02675026
      dyniusz 提交于
      Summary:
      	Handle SST files with both ".sst" and ".ldb" suffix.
      	This enables user to migrate from leveldb to rocksdb.
      
      Test Plan:
              Added unit test with DB operating on SSTs with names schema.
              See db/dc_test.cc:SSTsWithLdbSuffixHandling for details
      
      Reviewers: yhchiang, sdong, igor
      
      Reviewed By: igor
      
      Subscribers: dhruba, leveldb
      
      Differential Revision: https://reviews.facebook.net/D48003
      02675026
  2. 06 10月, 2015 1 次提交
  3. 03 10月, 2015 1 次提交
  4. 26 9月, 2015 3 次提交
  5. 24 9月, 2015 2 次提交
    • I
      Add experimental DB::AddFile() to plug sst files into empty DB · f03b5c98
      Islam AbdelRahman 提交于
      Summary:
      This is an initial version of bulk load feature
      
      This diff allow us to create sst files, and then bulk load them later, right now the restrictions for loading an sst file are
      (1) Memtables are empty
      (2) Added sst files have sequence number = 0, and existing values in database have sequence number = 0
      (3) Added sst files values are not overlapping
      
      Test Plan: unit testing
      
      Reviewers: igor, ott, sdong
      
      Reviewed By: sdong
      
      Subscribers: leveldb, ott, dhruba
      
      Differential Revision: https://reviews.facebook.net/D39081
      f03b5c98
    • S
      PlainTableReader to support non-mmap mode · df34aea3
      sdong 提交于
      Summary:
      PlainTableReader now only allows mmap-mode. Add the support to non-mmap mode for more flexibility.
      Refactor the codes to move all logic of reading data to PlainTableKeyDecoder, and consolidate the calls to Read() call and ReadVarint32() call. Implement the calls for both of mmap and non-mmap case seperately. For non-mmap mode, make copy of keys in several places when we need to move the buffer after reading the keys.
      
      Test Plan: Add the mode of non-mmap case in plain_table_db_test. Run it in valgrind mode too.
      
      Subscribers: leveldb, dhruba
      
      Differential Revision: https://reviews.facebook.net/D47187
      df34aea3
  6. 18 9月, 2015 1 次提交
    • A
      Support for SingleDelete() · 014fd55a
      Andres Noetzli 提交于
      Summary:
      This patch fixes #7460559. It introduces SingleDelete as a new database
      operation. This operation can be used to delete keys that were never
      overwritten (no put following another put of the same key). If an overwritten
      key is single deleted the behavior is undefined. Single deletion of a
      non-existent key has no effect but multiple consecutive single deletions are
      not allowed (see limitations).
      
      In contrast to the conventional Delete() operation, the deletion entry is
      removed along with the value when the two are lined up in a compaction. Note:
      The semantics are similar to @igor's prototype that allowed to have this
      behavior on the granularity of a column family (
      https://reviews.facebook.net/D42093 ). This new patch, however, is more
      aggressive when it comes to removing tombstones: It removes the SingleDelete
      together with the value whenever there is no snapshot between them while the
      older patch only did this when the sequence number of the deletion was older
      than the earliest snapshot.
      
      Most of the complex additions are in the Compaction Iterator, all other changes
      should be relatively straightforward. The patch also includes basic support for
      single deletions in db_stress and db_bench.
      
      Limitations:
      - Not compatible with cuckoo hash tables
      - Single deletions cannot be used in combination with merges and normal
        deletions on the same key (other keys are not affected by this)
      - Consecutive single deletions are currently not allowed (and older version of
        this patch supported this so it could be resurrected if needed)
      
      Test Plan: make all check
      
      Reviewers: yhchiang, sdong, rven, anthony, yoshinorim, igor
      
      Reviewed By: igor
      
      Subscribers: maykov, dhruba, leveldb
      
      Differential Revision: https://reviews.facebook.net/D43179
      014fd55a
  7. 16 9月, 2015 3 次提交
    • I
      Merge issue with D46773 · 0e50a3fc
      Igor Canadi 提交于
      Summary: There was a merge issue with SleepingBackgroundTask
      
      Test Plan: compiles now
      
      Reviewers: sdong
      
      Reviewed By: sdong
      
      Subscribers: dhruba, leveldb
      
      Differential Revision: https://reviews.facebook.net/D46977
      0e50a3fc
    • I
      LogAndApply() should fail if the column family has been dropped · a7e80379
      Igor Canadi 提交于
      Summary:
      This patch finally fixes the ColumnFamilyTest.ReadDroppedColumnFamily test. The test has been failing very sporadically and it was hard to repro. However, I managed to write a new tests that reproes the failure deterministically.
      
      Here's what happens:
      1. We start the flush for the column family
      2. We check if the column family was dropped here: https://github.com/facebook/rocksdb/blob/a3fc49bfddcdb1ff29409aacd06c04df56c7a1d7/db/flush_job.cc#L149
      3. This check goes through, ends up in InstallMemtableFlushResults() and it goes into LogAndApply()
      4. At about this time, we start dropping the column family. Dropping the column family process gets to LogAndApply() at about the same time as LogAndApply() from flush process
      5. Drop column family goes through LogAndApply() first, marking the column family as dropped.
      6. Flush process gets woken up and gets a chance to write to the MANIFEST. However, this is where it gets stuck: https://github.com/facebook/rocksdb/blob/a3fc49bfddcdb1ff29409aacd06c04df56c7a1d7/db/version_set.cc#L1975
      7. We see that the column family was dropped, so there is no need to write to the MANIFEST. We return OK.
      8. Flush gets OK back from LogAndApply() and it deletes the memtable, thinking that the data is now safely persisted to sst file.
      
      The fix is pretty simple. Instead of OK, we return ShutdownInProgress. This is not really true, but we have been using this status code to also mean "this operation was canceled because the column family has been dropped".
      
      The fix is only one LOC. All other code is related to tests. I added a new test that reproes the failure. I also moved SleepingBackgroundTask to util/testutil.h (because I needed it in column_family_test for my new test). There's plenty of other places where we reimplement SleepingBackgroundTask, but I'll address that in a separate commit.
      
      Test Plan:
      1. new test
      2. make check
      3. Make sure the ColumnFamilyTest.ReadDroppedColumnFamily doesn't fail on Travis: https://travis-ci.org/facebook/rocksdb/jobs/79952386
      
      Reviewers: yhchiang, anthony, IslamAbdelRahman, kradhakrishnan, rven, sdong
      
      Reviewed By: sdong
      
      Subscribers: dhruba, leveldb
      
      Differential Revision: https://reviews.facebook.net/D46773
      a7e80379
    • Y
      Adding Slice::difference_offset() function · 48860731
      Yoshinori Matsunobu 提交于
      Summary:
      There are some use cases in MyRocks to compare two slices
      and to return the first byte where they differ. It may be
      useful to add it as a RocksDB Slice function.
      
      Test Plan: db_test
      
      Reviewers: sdong, rven, igor
      
      Reviewed By: igor
      
      Subscribers: jkedgar, dhruba
      
      Differential Revision: https://reviews.facebook.net/D46935
      48860731
  8. 15 9月, 2015 1 次提交
  9. 11 9月, 2015 2 次提交
    • A
      Determine boundaries of subcompactions · 3c37b3cc
      Ari Ekmekji 提交于
      Summary:
      Up to this point, the subcompactions that make up a compaction
      job have been divided based on the key range of the L1 files, and each
      subcompaction has handled the key range of only one file. However
      DBOption.max_subcompactions allows the user to designate how many
      subcompactions at most to perform. This patch updates the
      CompactionJob::GetSubcompactionBoundaries() to determine these
      divisions accordingly based on that option and other input/system factors.
      
      The current approach orders the starting and/or ending keys of certain
      compaction input files and then generates a histogram to approximate the
      size covered by the key range between each consecutive pair of keys. Then
      it groups these ranges into groups so that the sizes are approximately equal
      to one another. The approach has also been adapted to work for universal
      compaction as well instead of just for level-based compaction as it was before.
      
      These subcompactions are then executed in parallel by locally spawning
      threads, one for each. The results are then aggregated and the compaction
      completed.
      
      Test Plan: make all && make check
      
      Reviewers: yhchiang, anthony, igor, noetzli, sdong
      
      Reviewed By: sdong
      
      Subscribers: MarkCallaghan, dhruba, leveldb
      
      Differential Revision: https://reviews.facebook.net/D43269
      3c37b3cc
    • S
      Make DBTest.ReadLatencyHistogramByLevel more robust · abc7f5fd
      sdong 提交于
      Summary: DBTest.ReadLatencyHistogramByLevel was not written as expected. After writes, reads aren't guaranteed to hit data written. It was not expected. Fix it.
      
      Test Plan: Run the test multiple times
      
      Reviewers: IslamAbdelRahman, rven, anthony, kradhakrishnan, yhchiang, igor
      
      Reviewed By: igor
      
      Subscribers: leveldb, dhruba
      
      Differential Revision: https://reviews.facebook.net/D46587
      abc7f5fd
  10. 09 9月, 2015 2 次提交
    • A
      better tuning of arena block size · b5b2b75e
      agiardullo 提交于
      Summary: Currently, if users didn't set options.arena_block_size, we set "result.arena_block_size = result.write_buffer_size / 10". It makes result.arena_block_size not a multiplier of 4KB, even if options.write_buffer_size is a multiplier of MBs. When calling malloc to arena_block_size, we may waste a small amount of memory for it. We now make the default to be /8 or /16 and align it to 4KB.
      
      Test Plan: unit tests
      
      Reviewers: sdong
      
      Reviewed By: sdong
      
      Subscribers: dhruba, leveldb
      
      Differential Revision: https://reviews.facebook.net/D46467
      b5b2b75e
    • S
      Make DBTest.OptimizeFiltersForHits more deterministic · 342ba808
      sdong 提交于
      Summary:
      This commit makes DBTest.OptimizeFiltersForHits more deterministic by:
      (1) make key inserts more random
      (2) make sure L0 has one file
      (3) make file size smaller compared to level target so L1 will cover more range.
      
      Test Plan: Run the test many times.
      
      Reviewers: rven, IslamAbdelRahman, kradhakrishnan, igor, anthony
      
      Reviewed By: anthony
      
      Subscribers: leveldb, dhruba
      
      Differential Revision: https://reviews.facebook.net/D46461
      342ba808
  11. 03 9月, 2015 2 次提交
  12. 01 9月, 2015 2 次提交
    • A
      Add Subcompactions to Universal Compaction Unit Tests · 8b689546
      Ari Ekmekji 提交于
      Summary:
      Now that the approach to parallelizing L0-L1 level-based
      compactions by breaking the compaction job into subcompactions is
      being extended to apply to universal compactions as well, the unit
      tests need to account for this and run the universal compaction
      tests with subcompactions both enabled and disabled.
      
      Test Plan: make all && make check
      
      Reviewers: sdong, igor, noetzli, anthony, yhchiang
      
      Reviewed By: yhchiang
      
      Subscribers: dhruba
      
      Differential Revision: https://reviews.facebook.net/D45657
      8b689546
    • S
      Arena usage to be calculated using malloc_usable_size() · 3d78eb66
      sdong 提交于
      Summary: malloc_usable_size() gets a better estimation of memory usage. It is already used to calculate block cache memory usage. Use it in arena too.
      
      Test Plan: Run all unit tests
      
      Reviewers: anthony, kradhakrishnan, rven, IslamAbdelRahman, yhchiang
      
      Reviewed By: yhchiang
      
      Subscribers: leveldb, dhruba
      
      Differential Revision: https://reviews.facebook.net/D43317
      3d78eb66
  13. 29 8月, 2015 2 次提交
    • A
      Fix deadlock in WAL sync · effd9dd1
      Andres Noetzli 提交于
      Summary:
      MarkLogsSynced() was doing `logs_.erase(it++);`. The standard is saying:
      
      ```
      all iterators and references are invalidated, unless the erased members are at an end (front or back) of the deque (in which case only iterators and references to the erased members are invalidated)
      ```
      
      Because `it` is an iterator to the first element of the container, it is
      invalidated, only one iteration is executed and `log.getting_synced = false;`
      is not being done, so `while (logs_.front().getting_synced)` in `WriteImpl()`
      is not terminating.
      
      Test Plan: make db_bench && ./db_bench --benchmarks=fillsync
      
      Reviewers: igor, rven, IslamAbdelRahman, anthony, kradhakrishnan, yhchiang, sdong, tnovak
      
      Reviewed By: tnovak
      
      Subscribers: kolmike, dhruba, leveldb
      
      Differential Revision: https://reviews.facebook.net/D45807
      effd9dd1
    • A
      Removed unnecessary checks in DBTest.ApproximateMemoryUsage · 72a9b73c
      Andres Noetzli 提交于
      Summary:
      Just realized that after D45675, part of the code in
      DBTest.ApproximateMemoryUsage, does not really test anything anymore, so I
      removed it.
      
      Test Plan: make clean all check
      
      Reviewers: rven, igor, sdong, anthony, yhchiang
      
      Reviewed By: yhchiang
      
      Subscribers: dhruba, leveldb
      
      Differential Revision: https://reviews.facebook.net/D45783
      72a9b73c
  14. 28 8月, 2015 1 次提交
    • A
      Fix DBTest.ApproximateMemoryUsage · e853191c
      Andres Noetzli 提交于
      Summary:
      This patch fixes two issues in DBTest.ApproximateMemoryUsage:
      - It was possible that a flush happened between getting the two properties in
        Phase 1, resulting in different numbers for the properties and failing the
        assertion. This is fixed by waiting for the flush to finish before getting
        the properties.
      - There was a similar issue in Phase 2 and additionally there was an issue that
        rocksdb.size-all-mem-tables was not monotonically increasing because it was
        possible that a flush happened just after getting the properties and then
        another flush just before getting the properties in the next round. In this
        situation, the reported memory usage decreased. This is fixed by forcing a
        flush before getting the properties.
      
      Note: during testing, I found that kFlushesPerRound does not seem very
      accurate. I added a TODO for this and it would be great to get some input on
      what to do there.
      
      Test Plan:
      The first issue can be made more likely to trigger by inserting a
      `usleep(10000);` between the calls to GetIntProperty() in Phase 1.
      The second issue can be made more likely to trigger by inserting a
      `if (r != 0) usleep(10000);` before the calls to GetIntProperty() and a
      `usleep(10000);` after the calls.
      Then execute make db_test && ./db_test --gtest_filter=DBTest.ApproximateMemoryUsage
      
      Reviewers: rven, yhchiang, igor, sdong, anthony
      
      Reviewed By: anthony
      
      Subscribers: dhruba, leveldb
      
      Differential Revision: https://reviews.facebook.net/D45675
      e853191c
  15. 27 8月, 2015 1 次提交
    • A
      Fix DBTest.GetProperty · 3795449c
      Andres Noetzli 提交于
      Summary:
      DBTest.GetProperty was failing occasionally (see task #8131266). The reason was
      that the test closed the database before the compaction was done. When the test
      reopened the database, RocksDB would schedule a compaction which in turn
      created table readers and lead the test to fail the assertion that
      rocksdb.estimate-table-readers-mem is 0. In most cases, GetIntProperty() of
      rocksdb.estimate-table-readers-mem happened before the compaction created the
      table readers, hiding the problem. This patch changes the
      WaitForFlushMemTable() to WaitForCompact(). WaitForFlushMemTable() is not
      necessary because it is already being called a couple of lines before without
      any insertions in-between.
      
      Test Plan:
      Insert `usleep(10000);` just after `Reopen(options);` on line 2333 to make the issue more likely, then run:
      make db_test && while ./db_test --gtest_filter=DBTest.GetProperty; do true; done
      
      Reviewers: rven, yhchiang, anthony, igor, sdong
      
      Reviewed By: sdong
      
      Subscribers: dhruba, leveldb
      
      Differential Revision: https://reviews.facebook.net/D45603
      3795449c
  16. 26 8月, 2015 2 次提交
  17. 25 8月, 2015 3 次提交
    • A
      Fixing race condition in DBTest.DynamicMemtableOptions · 20508329
      Andres Noetzli 提交于
      Summary:
      This patch fixes a race condition in DBTEst.DynamicMemtableOptions. In rare cases,
      it was possible that the main thread would fill up both memtables before the flush
      job acquired its work. Then, the flush job was flushing both memtables together,
      producing only one L0 file while the test expected two. Now, the test waits for
      flushes to finish earlier, to make sure that the memtables are flushed in separate
      flush jobs.
      
      Test Plan:
      Insert "usleep(10000);" after "IOSTATS_SET_THREAD_POOL_ID(Env::Priority::HIGH);" in BGWorkFlush()
      to make the issue more likely. Then test with:
      make db_test && time while ./db_test --gtest_filter=*DynamicMemtableOptions; do true; done
      
      Reviewers: rven, sdong, yhchiang, anthony, igor
      
      Reviewed By: igor
      
      Subscribers: dhruba, leveldb
      
      Differential Revision: https://reviews.facebook.net/D45429
      20508329
    • I
      Remove an extra 's' from cur-size-all-mem-tabless · e46bcc08
      Igor Canadi 提交于
      Summary: As title
      
      Test Plan: make check
      
      Reviewers: yhchiang
      
      Reviewed By: yhchiang
      
      Subscribers: dhruba, leveldb
      
      Differential Revision: https://reviews.facebook.net/D45447
      e46bcc08
    • I
      Smarter purging during flush · 4ab26c5a
      Igor Canadi 提交于
      Summary:
      Currently, we only purge duplicate keys and deletions during flush if `earliest_seqno_in_memtable <= newest_snapshot`. This means that the newest snapshot happened before we first created the memtable. This is almost never true for MyRocks and MongoRocks.
      
      This patch makes purging during flush able to understand snapshots. The main logic is copied from compaction_job.cc, although the logic over there is much more complicated and extensive. However, we should try to merge the common functionality at some point.
      
      I need this patch to implement no_overwrite_i_promise functionality for flush. We'll also need this to support SingleDelete() during Flush(). @yoshinorim requested the feature.
      
      Test Plan:
      make check
      I had to adjust some unit tests to understand this new behavior
      
      Reviewers: yhchiang, yoshinorim, anthony, sdong, noetzli
      
      Reviewed By: noetzli
      
      Subscribers: yoshinorim, dhruba, leveldb
      
      Differential Revision: https://reviews.facebook.net/D42087
      4ab26c5a
  18. 22 8月, 2015 1 次提交
    • A
      Changed 'num_subcompactions' to the more accurate 'max_subcompactions' · b6def58f
      Ari Ekmekji 提交于
      Summary:
      Up until this point we had DbOptions.num_subcompactions, but
      it is semantically more correct to call this max_subcompactions since
      we will schedule *up to* DbOptions.max_subcompactions smaller compactions
      at a time during a compaction job.
      
      I also added a --subcompactions option to db_bench
      
      Test Plan: make all   make check
      
      Reviewers: sdong, igor, anthony, yhchiang
      
      Reviewed By: yhchiang
      
      Subscribers: dhruba
      
      Differential Revision: https://reviews.facebook.net/D45069
      b6def58f
  19. 21 8月, 2015 3 次提交
    • S
      Add a counter about estimated pending compaction bytes · 07d2d341
      sdong 提交于
      Summary:
      Add a counter of estimated bytes the DB needs to compact for all the compactions to finish. Expose it as a DB Property.
      In the future, we can use threshold of this counter to replace soft rate limit and hard rate limit. A single threshold of estimated compaction debt in bytes will be easier for users to reason about when should slow down and stopping than more abstract soft and hard rate limits.
      
      Test Plan: Add unit tests
      
      Reviewers: IslamAbdelRahman, yhchiang, rven, kradhakrishnan, anthony, igor
      
      Reviewed By: igor
      
      Subscribers: leveldb, dhruba
      
      Differential Revision: https://reviews.facebook.net/D44205
      07d2d341
    • Y
      Fixed a rare deadlock in DBTest.ThreadStatusFlush · a203b913
      Yueh-Hsuan Chiang 提交于
      Summary:
      Currently, ThreadStatusFlush uses two sync-points to ensure
      there's a flush currently running when calling GetThreadList().
      However, one of the sync-point is inside db-mutex, which could
      cause deadlock in case there's a DB::Get() call.
      
      This patch fix this issue by moving the sync-point to a better
      place where the flush job does not hold the mutex.
      
      Test Plan: db_test
      
      Reviewers: igor, sdong, anthony, IslamAbdelRahman
      
      Reviewed By: IslamAbdelRahman
      
      Subscribers: dhruba, leveldb
      
      Differential Revision: https://reviews.facebook.net/D45045
      a203b913
    • I
      Total SST files size DB Property · 027ca5b2
      Islam AbdelRahman 提交于
      Summary: Add a new DB property that calculate the total size of files used by all RocksDB Versions
      
      Test Plan: Unittests for the new property
      
      Reviewers: igor, yhchiang, anthony, rven, kradhakrishnan, sdong
      
      Reviewed By: sdong
      
      Subscribers: dhruba
      
      Differential Revision: https://reviews.facebook.net/D44799
      027ca5b2
  20. 20 8月, 2015 3 次提交
    • I
      Rate limit deletes issued by DestroyDB · 3fd70b05
      Islam AbdelRahman 提交于
      Summary: Update DestroyDB so that all SST files in the first path id go through DeleteScheduler instead of being deleted immediately
      
      Test Plan: added a unittest
      
      Reviewers: igor, yhchiang, anthony, kradhakrishnan, rven, sdong
      
      Reviewed By: sdong
      
      Subscribers: jeanxu2012, dhruba
      
      Differential Revision: https://reviews.facebook.net/D44955
      3fd70b05
    • Y
      Introduce GetIntProperty("rocksdb.size-all-mem-tables") · df79eafc
      Yueh-Hsuan Chiang 提交于
      Summary:
      Currently, GetIntProperty("rocksdb.cur-size-all-mem-tables") only returns
      the memory usage by those memtables which have not yet been flushed.
      
      This patch introduces GetIntProperty("rocksdb.size-all-mem-tables"),
      which includes the memory usage by all the memtables, includes those
      have been flushed but pinned by iterators.
      
      Test Plan: Added a test in db_test
      
      Reviewers: igor, anthony, IslamAbdelRahman, sdong
      
      Reviewed By: sdong
      
      Subscribers: dhruba, leveldb
      
      Differential Revision: https://reviews.facebook.net/D44229
      df79eafc
    • S
      Remove the contstaint that iterator upper bound needs to be within a prefix · 888fbdc8
      sdong 提交于
      Summary: There is a check to fail the iterator if prefix extractor is specified but upper bound is out of the prefix for the seek key. Relax this constraint to allow users to set upper bound to the next prefix of the current one.
      
      Test Plan: make commit-prereq
      
      Reviewers: igor, anthony, kradhakrishnan, yhchiang, rven
      
      Reviewed By: rven
      
      Subscribers: tnovak, leveldb, dhruba
      
      Differential Revision: https://reviews.facebook.net/D44949
      888fbdc8
  21. 12 8月, 2015 2 次提交
    • I
      Parallelize LoadTableHandlers · cee1e8a0
      Islam AbdelRahman 提交于
      Summary: Add a new option that all LoadTableHandlers to use multiple threads to load files on DB Open and Recover
      
      Test Plan:
      make check -j64
      COMPILE_WITH_TSAN=1 make check -j64
      DISABLE_JEMALLOC=1 make all valgrind_check -j64 (still running)
      
      Reviewers: yhchiang, anthony, rven, kradhakrishnan, igor, sdong
      
      Reviewed By: sdong
      
      Subscribers: dhruba
      
      Differential Revision: https://reviews.facebook.net/D43755
      cee1e8a0
    • A
      Removing duplicate code in db_bench/db_stress, fixing typos · 4249f159
      Andres Notzli 提交于
      Summary:
      While working on single delete support for db_bench, I realized that
      db_bench/db_stress contain a bunch of duplicate code related to
      copmression and found some typos. This patch removes duplicate code,
      typos and a redundant #ifndef in internal_stats.cc.
      
      Test Plan: make db_stress && make db_bench && ./db_bench --benchmarks=compress,uncompress
      
      Reviewers: yhchiang, sdong, rven, anthony, igor
      
      Reviewed By: igor
      
      Subscribers: dhruba, leveldb
      
      Differential Revision: https://reviews.facebook.net/D43965
      4249f159
  22. 07 8月, 2015 1 次提交
    • A
      simple ManagedSnapshot wrapper · 16ea1c7d
      agiardullo 提交于
      Summary: Implemented this simple wrapper for something else I was working on.  Seemed like it makes sense to expose it instead of burying it in some random code.
      
      Test Plan: added test
      
      Reviewers: rven, kradhakrishnan, sdong, yhchiang
      
      Reviewed By: sdong
      
      Subscribers: dhruba, leveldb
      
      Differential Revision: https://reviews.facebook.net/D43293
      16ea1c7d