Три записи в одном и том же хранилище объектов необходимо обновить в одной и той же транзакции, и, хотя ключи каждый раз являются переменными и не соответствуют диапазону ключей, который определяет только три, они всегда следуют фиксированному шаблону [0,0,0]
а затем [n,0]
и [n,m]
, где n
и m
- целые числа. Они обеспечивают диапазон в том смысле, что [0,0,0]
всегда будет первым, за исключением n = 0
, который не используется, и [n,m]
всегда будет последним, потому что m
всегда больше, чем 0
.
Помимо того, какой подход завершается на моей машине быстрее, должен ли один из следующих двух методов быть предпочтительным по другим причинам и есть ли лучший метод?
Спасибо.
Подход 1 - это три get
запросов с put
запросом в событии onsuccess
; один пример ниже.
req = os.get( [ n, m ] ); // One each for [0,0,0], [n,0], [n,m].
req.onsuccess = function()
{
let r;
try
{
if ( req.result )
{
r = req.result;
// Update r.
os.put( r );
}
else
throw 'Record missing from database.';
}
catch( e )
{ /* Handle error. */ }
finally
{ r = null; }
}; // close req.onsuccess
Подход 2 состоит в том, чтобы открыть курсор, продолжая к нужным клавишам, вместо того, чтобы проходить и тестировать каждую из них.
keys = [ [ 0, 0, 0 ], [ n, 0 ], [ n, m ] ];
range = IDBKeyRange.bound( [ 0, 0, 0 ], [ n, m ], false, false );
i = 0;
os.openCursor( range ).onsuccess = ( e ) =>
{
try
{
cursor = e.target.result;
if ( cursor )
{
v = cursor.value;
if ( i === 0 )
// Update v.
else if ( i === 1 )
// Update v.
else // i === 2
// Update v.
cursor.update( v );
if ( i < 2 )
{
i = i + 1;
cursor.continue( keys[i] );
}; // end if
}; // end if cursor
}
catch( e )
{ /* Handle errors. */ }
}; // close cursor onsuccess
Я проделал еще кое-что над этим курсор намного медленнее; занимает как минимум вдвое больше времени, хотя для пользователя это не заметно.
Я не знаю, как на самом деле работает get
, например, он начинается сверху и ищет вниз. Если так, я ожидал, что три get/put
будут медленнее. Я полагаю, что индексирование клавиши ускоряет get
, и курсор ищет каждую запись от нижней границы до верхней, даже если в cursor.continue()
указана клавиша, и это делает курсор медленнее. Или, возможно, три get/put
могут происходить одновременно, и курсор должен завершить каждое отдельное обновление перед выполнением следующего cursor.continue()
и выполнением следующего.
Кроме того, я не вижу другого фактора в этом Случай для рассмотрения, кроме скорости. Три оператора get
легче кодировать, особенно в отношении обработки ошибок.
У меня есть другая операция, которая может или не может нуждаться в обновлении [0,0,0]
, но будет обновлять каждую запись с [n,0]
до [n,m]
, а не только конечные точки. Может быть второе обновление одной или нескольких из этих записей в зависимости от действия пользователя, которое его инициировало. Я обрабатывал вторые обновления за пределами курсора, так как они были условными, а затем переместил их в курсор, так как они будут обновлять записи в диапазоне клавиш курсора, когда это необходимо. В то время казалось глупым иметь курсор и затем небольшое количество дополнительных операций get / put для одних и тех же записей. Я не уверен, что быстрее, но может показаться проблематичным c обновить часть записи в курсоре, а затем другую часть в отдельном условном get/put
. Я не обнаружил ошибок, когда он был закодирован таким образом, но тестирование было ограничено.