text:
package com.github.ambry.store;

import com.github.ambry.config.StoreConfig;
import com.github.ambry.config.VerifiableProperties;
import com.github.ambry.utils.MockTime;
import com.github.ambry.utils.Pair;
import com.github.ambry.utils.TestUtils;
import com.github.ambry.utils.Utils;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.Properties;
import java.util.Set;
import java.util.SortedMap;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;

import static com.github.ambry.store.StoreFindToken.*;
import static org.junit.Assert.*;

/**
 * Tests for {@link CompactionLog}.
 */
public class CompactionLogTest {
  private static final StoreKeyFactory STORE_KEY_FACTORY;

  static {
    try {
      STORE_KEY_FACTORY = new MockIdFactory();
    } catch (Exception e) {
      throw new IllegalStateException(e);
    }
  }

  // Variables that represent the folder where the data resides
  private final File tempDir;
  private final String tempDirStr;
  private final StoreConfig config;
  // the time instance that will be used in the index
  private final MockTime time = new MockTime();
  private final Set<LogSegmentName> generatedSegmentNames = new HashSet<>();

  /**
   * Creates a temporary directory for the compaction log file.
   * @throws IOException
   */
  public CompactionLogTest() throws IOException {
    tempDir = StoreTestUtils.createTempDirectory("storeDir-" + TestUtils.getRandomString(10));
    tempDirStr = tempDir.getAbsolutePath();
    config = new StoreConfig(new VerifiableProperties(new Properties()));
  }

  /**
   * Deletes the temporary directory.
   * @throws IOException
   */
  @After
  public void cleanup() throws IOException {
    assertTrue(tempDir.getAbsolutePath() + " could not be deleted", StoreTestUtils.cleanDirectory(tempDir, true));
  }

  /**
   * Tests the use of {@link CompactionLog} when it is used without closing b/w operations and compaction cycles.
   * @throws IOException
   */
  @Test
  public void iterationWithoutReloadTest() throws IOException {
    String storeName = "store";
    List<CompactionDetails> detailsList = getCompactionDetailsList(5);
    CompactionDetails combined = combineListOfDetails(detailsList);
    assertFalse("Compaction should not be in progress", CompactionLog.isCompactionInProgress(tempDirStr, storeName));
    CompactionLog cLog = new CompactionLog(tempDirStr, storeName, time, combined, config);
    assertTrue("Compaction should be in progress", CompactionLog.isCompactionInProgress(tempDirStr, storeName));
    int currentIdx = 0;
    Iterator<CompactionDetails> detailsIterator = detailsList.iterator();
    CompactionDetails currDetails = detailsIterator.next();
    while (currDetails != null) {
      detailsIterator.remove();
      assertEquals("CurrentIdx not as expected", currentIdx, cLog.getCurrentIdx());
      verifyEquality(combined, cLog.getCompactionDetails());
      assertEquals("Should be in the PREPARE phase", CompactionLog.Phase.PREPARE, cLog.getCompactionPhase());
      cLog.markCopyStart();
      assertEquals("Should be in the COPY phase", CompactionLog.Phase.COPY, cLog.getCompactionPhase());
      Offset offset = new Offset(LogSegmentName.generateFirstSegmentName(true),
          Utils.getRandomLong(TestUtils.RANDOM, Long.MAX_VALUE));
      cLog.setStartOffsetOfLastIndexSegmentForDeleteCheck(offset);
      assertEquals("Offset that was set was not the one returned", offset,
          cLog.getStartOffsetOfLastIndexSegmentForDeleteCheck());
      StoreFindToken safeToken =
          new StoreFindToken(new MockId("dummy"), new Offset(LogSegmentName.generateFirstSegmentName(true), 0),
              new UUID(1, 1), new UUID(1, 1), null, null, UNINITIALIZED_RESET_KEY_VERSION);
      cLog.setSafeToken(safeToken);
      assertEquals("Returned token not the same as the one that was set", safeToken, cLog.getSafeToken());
      assertTrue(cLog.isIndexSegmentOffsetsPersisted());
      int sizeBefore = cLog.getBeforeAndAfterIndexSegmentOffsets().size();
      Pair<Offset, Offset> pair = addOneIndexSegmentOffsetPair(cLog);
      cLog.addBeforeAndAfterIndexSegmentOffsetPair(pair.getFirst(), pair.getSecond());
      assertEquals(sizeBefore + 1, cLog.getBeforeAndAfterIndexSegmentOffsets().size());
      try {
        LogSegmentName logSegmentName = StoreTestUtils.getRandomLogSegmentName(generatedSegmentNames);
        Offset before = new Offset(logSegmentName, LogSegment.HEADER_SIZE);
        Offset after = new Offset(logSegmentName.getNextGenerationName(), LogSegment.HEADER_SIZE);
        cLog.addBeforeAndAfterIndexSegmentOffsetPair(before, after);
        fail("Offset " + before + " doesn't belong to under compaction log segment, should fail");
      } catch (Exception e) {
        // Expect to see exception
      }
      CompactionDetails nextDetails = detailsIterator.hasNext() ? detailsIterator.next() : null;
      if (nextDetails != null) {
        cLog.splitCurrentCycle(nextDetails.getLogSegmentsUnderCompaction().get(0));
        verifyEquality(currDetails, cLog.getCompactionDetails());
      }
      cLog.markCommitStart();
      assertEquals("Should be in the SWITCH phase", CompactionLog.Phase.COMMIT, cLog.getCompactionPhase());
      cLog.markCleanupStart();
      assertEquals("Should be in the CLEANUP phase", CompactionLog.Phase.CLEANUP, cLog.getCompactionPhase());
      cLog.markCycleComplete();
      currentIdx++;
      currDetails = nextDetails;
      if (nextDetails != null) {
        combined = combineListOfDetails(detailsList);
      }
    }
    assertEquals("CurrentIdx not as expected", -1, cLog.getCurrentIdx());
    assertEquals("Should be in the DONE phase", CompactionLog.Phase.DONE, cLog.getCompactionPhase());
    cLog.close();
    assertFalse("Compaction should not be in progress", CompactionLog.isCompactionInProgress(tempDirStr, storeName));
  }

  /**
   * Tests the use of {@link CompactionLog} when it is closed and reloaded b/w operations and compaction cycles.
   * @throws IOException
   */
  @Test
  public void iterationWithReloadTest() throws IOException {
    String storeName = "store";
    List<CompactionDetails> detailsList = getCompactionDetailsList(5);
    CompactionDetails combined = combineListOfDetails(detailsList);
    assertFalse("Compaction should not be in progress", CompactionLog.isCompactionInProgress(tempDirStr, storeName));
    CompactionLog cLog = new CompactionLog(tempDirStr, storeName, time, combined, config);
    assertTrue("Compaction should should be in progress", CompactionLog.isCompactionInProgress(tempDirStr, storeName));
    int currentIdx = 0;
    Iterator<CompactionDetails> detailsIterator = detailsList.iterator();
    CompactionDetails currDetails = detailsIterator.next();
    while (currDetails != null) {
      detailsIterator.remove();
      assertEquals("CurrentIdx not as expected", currentIdx, cLog.getCurrentIdx());

      cLog.close();
      cLog = new CompactionLog(tempDirStr, storeName, STORE_KEY_FACTORY, time, config);
      verifyEquality(combined, cLog.getCompactionDetails());
      assertEquals("Should be in the PREPARE phase", CompactionLog.Phase.PREPARE, cLog.getCompactionPhase());
      cLog.markCopyStart();

      cLog.close();
      cLog = new CompactionLog(tempDirStr, storeName, STORE_KEY_FACTORY, time, config);
      assertEquals("Should be in the COPY phase", CompactionLog.Phase.COPY, cLog.getCompactionPhase());
      Offset offset = new Offset(LogSegmentName.generateFirstSegmentName(true),
          Utils.getRandomLong(TestUtils.RANDOM, Long.MAX_VALUE));
      cLog.setStartOffsetOfLastIndexSegmentForDeleteCheck(offset);

      cLog.close();
      cLog = new CompactionLog(tempDirStr, storeName, STORE_KEY_FACTORY, time, config);
      assertEquals("Offset that was set was not the one returned", offset,
          cLog.getStartOffsetOfLastIndexSegmentForDeleteCheck());
      StoreFindToken safeToken =
          new StoreFindToken(new MockId("dummy"), new Offset(LogSegmentName.generateFirstSegmentName(true), 0),
              new UUID(1, 1), new UUID(1, 1), null, null, UNINITIALIZED_RESET_KEY_VERSION);
      cLog.setSafeToken(safeToken);

      cLog.close();
      cLog = new CompactionLog(tempDirStr, storeName, STORE_KEY_FACTORY, time, config);
      assertEquals("Returned token not the same as the one that was set", safeToken, cLog.getSafeToken());
      assertTrue(cLog.isIndexSegmentOffsetsPersisted());
      int sizeBefore = cLog.getBeforeAndAfterIndexSegmentOffsets().size();
      Pair<Offset, Offset> pair = addOneIndexSegmentOffsetPair(cLog);
      assertEquals(sizeBefore + 1, cLog.getBeforeAndAfterIndexSegmentOffsets().size());
      cLog.addBeforeAndAfterIndexSegmentOffsetPair(pair.getFirst(), pair.getSecond());
      assertEquals(sizeBefore + 1, cLog.getBeforeAndAfterIndexSegmentOffsets().size());
      try {
        LogSegmentName logSegmentName = StoreTestUtils.getRandomLogSegmentName(generatedSegmentNames);
        Offset before = new Offset(logSegmentName, LogSegment.HEADER_SIZE);
        Offset after = new Offset(logSegmentName.getNextGenerationName(), LogSegment.HEADER_SIZE);
        cLog.addBeforeAndAfterIndexSegmentOffsetPair(before, after);
        fail("Offset " + before + " doesn't belong to under compaction log seegment, should fail");
      } catch (Exception e) {
        // Expect to see exception
      }

      cLog.close();
      cLog = new CompactionLog(tempDirStr, storeName, STORE_KEY_FACTORY, time, config);
      assertTrue(cLog.isIndexSegmentOffsetsPersisted());
      assertEquals(sizeBefore + 1, cLog.getBeforeAndAfterIndexSegmentOffsets().size());
      CompactionDetails nextDetails = detailsIterator.hasNext() ? detailsIterator.next() : null;
      if (nextDetails != null) {
        cLog.splitCurrentCycle(nextDetails.getLogSegmentsUnderCompaction().get(0));
        verifyEquality(currDetails, cLog.getCompactionDetails());
        cLog.close();
        cLog = new CompactionLog(tempDirStr, storeName, STORE_KEY_FACTORY, time, config);
        verifyEquality(currDetails, cLog.getCompactionDetails());
      }
      cLog.markCommitStart();

      cLog.close();
      cLog = new CompactionLog(tempDirStr, storeName, STORE_KEY_FACTORY, time, config);
      assertEquals("Should be in the SWITCH phase", CompactionLog.Phase.COMMIT, cLog.getCompactionPhase());
      cLog.markCleanupStart();

      cLog.close();
      cLog = new CompactionLog(tempDirStr, storeName, STORE_KEY_FACTORY, time, config);
      assertEquals("Should be in the CLEANUP phase", CompactionLog.Phase.CLEANUP, cLog.getCompactionPhase());
      cLog.markCycleComplete();

      currentIdx++;
      currDetails = nextDetails;
      if (nextDetails != null) {
        combined = combineListOfDetails(detailsList);
      }
    }
    assertEquals("CurrentIdx not as expected", -1, cLog.getCurrentIdx());
    assertEquals("Should be in the DONE phase", CompactionLog.Phase.DONE, cLog.getCompactionPhase());
    cLog.close();
    assertFalse("Compaction should not be in progress", CompactionLog.isCompactionInProgress(tempDirStr, storeName));
  }

  /**
   * Tests phase transition order is enforced during phase transitions
   */
  @Test
  public void phaseTransitionEnforcementTest() throws IOException {
    String storeName = "store";
    CompactionLog cLog = new CompactionLog(tempDirStr, storeName, time, getCompactionDetails(), config);

    assertEquals("Should be in the PREPARE phase", CompactionLog.Phase.PREPARE, cLog.getCompactionPhase());
    checkTransitionFailure(cLog, CompactionLog.Phase.COMMIT, CompactionLog.Phase.CLEANUP, CompactionLog.Phase.DONE);

    cLog.markCopyStart();
    assertEquals("Should be in the COPY phase", CompactionLog.Phase.COPY, cLog.getCompactionPhase());
    checkTransitionFailure(cLog, CompactionLog.Phase.COPY, CompactionLog.Phase.CLEANUP, CompactionLog.Phase.DONE);

    cLog.markCommitStart();
    assertEquals("Should be in the SWITCH phase", CompactionLog.Phase.COMMIT, cLog.getCompactionPhase());
    checkTransitionFailure(cLog, CompactionLog.Phase.COPY, CompactionLog.Phase.COMMIT, CompactionLog.Phase.DONE);

    cLog.markCleanupStart();
    assertEquals("Should be in the CLEANUP phase", CompactionLog.Phase.CLEANUP, cLog.getCompactionPhase());
    checkTransitionFailure(cLog, CompactionLog.Phase.COPY, CompactionLog.Phase.COMMIT, CompactionLog.Phase.CLEANUP);

    cLog.markCycleComplete();
    assertEquals("Should be in the DONE phase", CompactionLog.Phase.DONE, cLog.getCompactionPhase());
    checkTransitionFailure(cLog, CompactionLog.Phase.COPY, CompactionLog.Phase.COMMIT, CompactionLog.Phase.CLEANUP,
        CompactionLog.Phase.DONE);
    cLog.close();
  }

  /**
   * Tests for construction of {@link CompactionLog} with bad arguments/state.
   * @throws IOException
   */
  @Test
  public void constructionBadArgsTest() throws IOException {
    String storeName = "store";
    CompactionLog cLog = new CompactionLog(tempDirStr, storeName, time, getCompactionDetails(), config);
    cLog.close();
    // log file already exists
    try {
      new CompactionLog(tempDirStr, storeName, time, getCompactionDetails(), config);
      fail("Construction should have failed because compaction log file already exists");
    } catch (IllegalArgumentException e) {
      // expected. Nothing to do.
    }

    // make sure file disappears
    cLog = new CompactionLog(tempDirStr, storeName, STORE_KEY_FACTORY, time, config);
    cLog.markCopyStart();
    cLog.markCommitStart();
    cLog.markCleanupStart();
    cLog.markCycleComplete();
    cLog.close();
    assertFalse("Compaction should not be in progress", CompactionLog.isCompactionInProgress(tempDirStr, storeName));

    // log file does not exist
    try {
      new CompactionLog(tempDirStr, storeName, STORE_KEY_FACTORY, time, config);
      fail("Construction should have failed because compaction log file does not exist");
    } catch (IllegalArgumentException e) {
      // expected. Nothing to do.
    }
  }

  /**
   * Tests the reading of version 0
   * @throws IOException
   */
  @Test
  public void versionZeroReadTest() throws IOException {
    String storeName = "store";
    long referenceTimeMs = Utils.getRandomLong(TestUtils.RANDOM, Long.MAX_VALUE);
    CompactionDetails details = getCompactionDetails(referenceTimeMs);
    CompactionLog cLog = new CompactionLog(tempDirStr, storeName, CompactionLog.VERSION_0, time, details, config);
    cLog.close();
    cLog = new CompactionLog(tempDirStr, storeName, STORE_KEY_FACTORY, time, config);
    verifyEquality(details, cLog.getCompactionDetails());
    assertEquals("Current Idx not as expected", 0, cLog.getCurrentIdx());
  }

  /**
   * Tests the reading of version 1
   * @throws IOException
   */
  @Test
  public void versionOneReadTest() throws IOException {
    String storeName = "store";
    long referenceTimeMs = Utils.getRandomLong(TestUtils.RANDOM, Long.MAX_VALUE);
    CompactionDetails details = getCompactionDetails(referenceTimeMs);
    CompactionLog cLog = new CompactionLog(tempDirStr, storeName, CompactionLog.VERSION_1, time, details, config);
    LogSegmentName logSegmentName = details.getLogSegmentsUnderCompaction().get(0);
    Offset before = new Offset(logSegmentName, LogSegment.HEADER_SIZE);
    Offset after = new Offset(logSegmentName.getNextGenerationName(), LogSegment.HEADER_SIZE);
    cLog.addBeforeAndAfterIndexSegmentOffsetPair(before, after);
    Assert.assertFalse(cLog.isIndexSegmentOffsetsPersisted());
    Assert.assertEquals(0, cLog.getBeforeAndAfterIndexSegmentOffsets().size());
    cLog.close();
    // Adding index segment offset pair shouldn't change any of the version 1 compaction log
    cLog = new CompactionLog(tempDirStr, storeName, STORE_KEY_FACTORY, time, config);
    Assert.assertFalse(cLog.isIndexSegmentOffsetsPersisted());
    Assert.assertEquals(0, cLog.getBeforeAndAfterIndexSegmentOffsets().size());
    verifyEquality(details, cLog.getCompactionDetails());
    assertEquals("Current Idx not as expected", 0, cLog.getCurrentIdx());
  }

  /**
   * Testing the methods to get the before and after index segment maps
   * @throws IOException
   */
  @Test
  public void testIndexSegmentOffsetsMethods() throws IOException {
    String storeName = "store";
    CompactionDetails details = getCompactionDetails(0);
    List<LogSegmentName> segmentsUnderCompaction = details.getLogSegmentsUnderCompaction();
    segmentsUnderCompaction.sort(LogSegmentName::compareTo);
    details = new CompactionDetails(0, segmentsUnderCompaction, null);

    CompactionLog cLog = new CompactionLog(tempDirStr, storeName, time, details, config);
    for (LogSegmentName name : segmentsUnderCompaction) {
      addOneIndexSegmentOffsetPair(name, cLog);
    }
    NavigableMap<Offset, Offset> indexSegmentOffsets = cLog.getBeforeAndAfterIndexSegmentOffsets();
    for (LogSegmentName name : segmentsUnderCompaction) {
      Offset before = new Offset(name, LogSegment.HEADER_SIZE);
      Offset expectedAfter = new Offset(name.getNextGenerationName(), LogSegment.HEADER_SIZE);
      Assert.assertEquals(expectedAfter, indexSegmentOffsets.get(before));
    }
    SortedMap<Offset, Offset> indexSegmentOffsetsCompleted =
        cLog.getBeforeAndAfterIndexSegmentOffsetsForCompletedCycles();
    // There is no completedCycle yet
    Assert.assertEquals(0, indexSegmentOffsetsCompleted.size());
    // All log segments are under compaction at current cycle.
    SortedMap<Offset, Offset> indexSegmentOffsetsCurrent = cLog.getBeforeAndAfterIndexSegmentOffsetsForCurrentCycle();
    Assert.assertEquals(segmentsUnderCompaction.size(), indexSegmentOffsetsCurrent.size());

    for (int i = 0; i < segmentsUnderCompaction.size(); i++) {
      LogSegmentName name = segmentsUnderCompaction.get(i);
      cLog.markCopyStart();
      if (i != segmentsUnderCompaction.size() - 1) {
        cLog.splitCurrentCycle(segmentsUnderCompaction.get(i + 1));
      }
      cLog.markCommitStart();
      cLog.markCleanupStart();

      indexSegmentOffsetsCurrent = cLog.getBeforeAndAfterIndexSegmentOffsetsForCurrentCycle();
      Assert.assertEquals(1, indexSegmentOffsetsCurrent.size());
      Assert.assertEquals(new Offset(name, LogSegment.HEADER_SIZE),
          indexSegmentOffsetsCurrent.keySet().iterator().next());

      cLog.close();
      cLog = new CompactionLog(tempDirStr, storeName, STORE_KEY_FACTORY, time, config);

      // Before completing this cycle, get the
      indexSegmentOffsetsCompleted = cLog.getBeforeAndAfterIndexSegmentOffsetsForCompletedCycles();
      Assert.assertEquals(i, indexSegmentOffsetsCompleted.size());
      for (int idx = 0; idx < i; idx++) {
        LogSegmentName sname = segmentsUnderCompaction.get(idx);
        Assert.assertTrue(indexSegmentOffsetsCompleted.containsKey(new Offset(sname, LogSegment.HEADER_SIZE)));
      }
      cLog.markCycleComplete();
      indexSegmentOffsetsCompleted = cLog.getBeforeAndAfterIndexSegmentOffsetsForCompletedCycles();
      Assert.assertEquals(i + 1, indexSegmentOffsetsCompleted.size());
      for (int idx = 0; idx < i + 1; idx++) {
        LogSegmentName sname = segmentsUnderCompaction.get(idx);
        Assert.assertTrue(indexSegmentOffsetsCompleted.containsKey(new Offset(sname, LogSegment.HEADER_SIZE)));
      }

      cLog.close();
      if (i != segmentsUnderCompaction.size() - 1) {
        cLog = new CompactionLog(tempDirStr, storeName, STORE_KEY_FACTORY, time, config);
      } else {
        AtomicReference<CompactionLog> compactionLogRef = new AtomicReference<>();
        CompactionLog.processCompactionLogs(tempDirStr, storeName, STORE_KEY_FACTORY, time, config, compactionLog -> {
          compactionLogRef.set(compactionLog);
          return false;
        });
        cLog = compactionLogRef.get();
      }
      indexSegmentOffsetsCompleted = cLog.getBeforeAndAfterIndexSegmentOffsetsForCompletedCycles();
      Assert.assertEquals(i + 1, indexSegmentOffsetsCompleted.size());
      for (int idx = 0; idx < i + 1; idx++) {
        LogSegmentName sname = segmentsUnderCompaction.get(idx);
        Assert.assertTrue(indexSegmentOffsetsCompleted.containsKey(new Offset(sname, LogSegment.HEADER_SIZE)));
      }
    }
  }

  /**
   * Test {@link CompactionLog#processCompactionLogs}.
   * @throws Exception
   */
  @Test
  public void testProcessCompactionLogs() throws Exception {
    // First create some compaction logs
    time.setCurrentMilliseconds(System.currentTimeMillis());
    String storeName = "store";
    List<CompactionDetails> detailsList = getCompactionDetailsList(10);
    List<Long> expectedStartTimes = new ArrayList<>();
    Map<Offset, Offset> expectedIndexSegmentOffsets = new HashMap<>();
    for (CompactionDetails details : detailsList) {
      CompactionLog cLog = new CompactionLog(tempDirStr, storeName, time, details, config);
      Pair<Offset, Offset> pair = addOneIndexSegmentOffsetPair(cLog);
      expectedIndexSegmentOffsets.put(pair.getFirst(), pair.getSecond());
      expectedStartTimes.add(0, time.milliseconds());
      cLog.markCopyStart();
      cLog.markCommitStart();
      cLog.markCleanupStart();
      cLog.markCycleComplete();
      cLog.close();
      Assert.assertFalse(CompactionLog.isCompactionInProgress(tempDirStr, storeName));
      long sleepTime = 3 * Integer.MAX_VALUE;
      time.sleep(sleepTime);
    }

    CompactionDetails details = getCompactionDetailsList(1).get(0);
    CompactionLog cLog = new CompactionLog(tempDirStr, storeName, time, details, config);
    Pair<Offset, Offset> pair = addOneIndexSegmentOffsetPair(cLog);
    expectedIndexSegmentOffsets.put(pair.getFirst(), pair.getSecond());
    expectedStartTimes.add(0, time.milliseconds());
    cLog.close();
    Assert.assertTrue(CompactionLog.isCompactionInProgress(tempDirStr, storeName));

    // Now we have 10 completed compaction logs and one in progress compaction log
    List<Long> obtainedStartTimes = new ArrayList<>();
    Map<Offset, Offset> obtainedIndexSegmentOffsets = new HashMap<>();
    CompactionLog.processCompactionLogs(tempDirStr, storeName, STORE_KEY_FACTORY, time, config, log -> {
      obtainedStartTimes.add(log.getStartTime());
      obtainedIndexSegmentOffsets.putAll(log.getBeforeAndAfterIndexSegmentOffsets());
      return true;
    });

    Assert.assertEquals(11, obtainedStartTimes.size());
    Assert.assertEquals(11, obtainedIndexSegmentOffsets.size());

    Assert.assertEquals(expectedIndexSegmentOffsets, obtainedIndexSegmentOffsets);
    Assert.assertEquals(expectedStartTimes, obtainedStartTimes);
  }

  // helpers
  // general

  /**
   * @return a {@link CompactionDetails} with random data.
   */
  private CompactionDetails getCompactionDetails() {
    long referenceTime = Utils.getRandomLong(TestUtils.RANDOM, 1000);
    return getCompactionDetails(referenceTime);
  }

  /**
   * A {@link CompactionDetails} with random data.
   * @param referenceTime the reference time to use to generate the {@link CompactionDetails}
   * @return {@link CompactionDetails} with random data.
   */
  private CompactionDetails getCompactionDetails(long referenceTime) {
    int segmentCount = TestUtils.RANDOM.nextInt(10) + 1;
    List<LogSegmentName> segmentsUnderCompaction = new ArrayList<>();
    for (int j = 0; j < segmentCount; j++) {
      LogSegmentName segmentName = StoreTestUtils.getRandomLogSegmentName(generatedSegmentNames);
      generatedSegmentNames.add(segmentName);
      segmentsUnderCompaction.add(segmentName);
    }
    return new CompactionDetails(referenceTime, segmentsUnderCompaction, null);
  }

  /**
   * Verifies that two {@link CompactionDetails} instances are equal.
   * @param original the expected {@link CompactionDetails}.
   * @param toCheck the {@link CompactionDetails} that needs to be checked.
   */
  private void verifyEquality(CompactionDetails original, CompactionDetails toCheck) {
    assertEquals("Reference time does not match", original.getReferenceTimeMs(), toCheck.getReferenceTimeMs());
    assertEquals("Segments under compaction don't match", original.getLogSegmentsUnderCompaction(),
        toCheck.getLogSegmentsUnderCompaction());
  }

  // iteration tests helpers

  /**
   * Gets a {@link List<CompactionDetails>} of size {@code size} with random {@link CompactionDetails}.
   * @param size the number of {@link CompactionDetails} required.
   * @return a {@link List<CompactionDetails>} of size {@code size} with random {@link CompactionDetails}.
   */
  private List<CompactionDetails> getCompactionDetailsList(int size) {
    List<CompactionDetails> detailsList = new ArrayList<>();
    long referenceTime = Utils.getRandomLong(TestUtils.RANDOM, 1000);
    for (int i = 0; i < size; i++) {
      CompactionDetails details = getCompactionDetails(referenceTime);
      detailsList.add(details);
    }
    return detailsList;
  }

  /**
   * Combines a {@link List<CompactionDetails>} into one {@link CompactionDetails} instance. Uses the reference time
   * of the first entry in the list.
   * @param detailsList the {@link List<CompactionDetails>} to combine.
   * @return combines {@code detailsList} into a single {@link CompactionDetails}.
   */
  private CompactionDetails combineListOfDetails(List<CompactionDetails> detailsList) {
    List<LogSegmentName> allSegmentNames = new ArrayList<>();
    for (CompactionDetails details : detailsList) {
      allSegmentNames.addAll(details.getLogSegmentsUnderCompaction());
    }
    return new CompactionDetails(detailsList.get(0).getReferenceTimeMs(), allSegmentNames, null);
  }

  // phaseTransitionEnforcementTest() helpers

  /**
   * Checks that transitions to phases in {@code transitionToFailures} fails.
   * @param cLog the {@link CompactionLog} being used.
   * @param transitionToFailures the list of phases, transition to which should fail.
   */
  private void checkTransitionFailure(CompactionLog cLog, CompactionLog.Phase... transitionToFailures) {
    for (CompactionLog.Phase transitionToFailure : transitionToFailures) {
      try {
        switch (transitionToFailure) {
          case COPY:
            cLog.markCopyStart();
            break;
          case COMMIT:
            cLog.markCommitStart();
            break;
          case CLEANUP:
            cLog.markCleanupStart();
            break;
          case DONE:
            cLog.markCycleComplete();
            break;
          default:
            throw new IllegalArgumentException("Unknown Phase: " + transitionToFailure);
        }
        fail("Transition should have failed");
      } catch (IllegalStateException e) {
        // expected. Nothing to do.
      }
    }

    if (!cLog.getCompactionPhase().equals(CompactionLog.Phase.COPY)) {
      StoreFindToken safeToken =
          new StoreFindToken(new MockId("dummy"), new Offset(LogSegmentName.generateFirstSegmentName(true), 0),
              new UUID(1, 1), new UUID(1, 1), null, null, UNINITIALIZED_RESET_KEY_VERSION);
      try {
        cLog.setSafeToken(safeToken);
        fail("Setting safe token should have failed");
      } catch (IllegalStateException e) {
        // expected. Nothing to do.
      }
    }
  }

  private Pair<Offset, Offset> addOneIndexSegmentOffsetPair(CompactionLog cLog) {
    LogSegmentName logSegmentName = cLog.getCompactionDetails().getLogSegmentsUnderCompaction().get(0);
    return addOneIndexSegmentOffsetPair(logSegmentName, cLog);
  }

  private Pair<Offset, Offset> addOneIndexSegmentOffsetPair(LogSegmentName logSegmentName, CompactionLog cLog) {
    Offset before = new Offset(logSegmentName, LogSegment.HEADER_SIZE);
    Offset after = new Offset(logSegmentName.getNextGenerationName(), LogSegment.HEADER_SIZE);
    cLog.addBeforeAndAfterIndexSegmentOffsetPair(before, after);
    return new Pair<>(before, after);
  }
}

redpajama_set_name: RedPajamaGithub


The second patient to benefit from a full heart transplant in the UAE, Sultan Al Muhairi, has passed his three-month milestone and is currently doing well, the Cleveland Clinic Abu Dhabi announced on Sunday.
The 38-year-old Emirati was one of four patients who received organs in October 2018 from a single brain-dead patient at Mafraq Hospital in the capital. Al Muhairi's 12-hour transplant procedure was also particularly complicated because it marked the first heart transplant in the country for a patient with an assistance device, a left ventricular assistance device (LVAD) that pumped blood for Al Muhairi's failing heart.
"When we first saw Al Muhairi, he had been living with heart failure for about seven to eight years. His heart function had slowly dropped to 10 per cent, [measured in the amount of blood that leaves the left ventricular chamber of the heart with every heartbeat]. In comparison, most people have a heart function of about 65 per cent," Dr Gurjyot Bajwa, heart transplant surgeon at the hospital, told Gulf News.
Al Muhairi was having trouble with his daily activities, so he was fitted with an LVAD in February 2018. But when a clot developed in his LVAD, he was hospitalised in October 2018, and moved to the top of the hospital's transplant list.
A donor heart then became available, and on October 19 last year, Al Muhairi underwent a heart transplant. The donor's liver was also successfully transplanted into a 58-year-old woman; one kidney was given to a 31-year-old Yemeni man and another kidney to a nine-year-old Sudanese girl.
Compared to the first full transplant undertaken at the hospital in December 2017, Al Muhairi's was a longer and more complicated procedure.
"Al Muhairi had already had an open-heart surgery to have his LVAD fitted. This transplant was also an open-heart procedure, and it was performed just nine months after the first. This increased Al Muhairi's risk of infection and bleeding. In addition, we also had to carefully remove the LVAD before transplanting the donor heart," Dr Bajwa said.
To everyone's delight, Al Muhairi recovered well, and was discharged after two weeks.
"Before every transplant, we match the recipient with the donor's height and weight. Afterwards, we routinely perform biopsies to check for rejection, with about nine performed in the first year. The patient also has to be on immunosuppressant medication for the rest of his life, and therefore guard carefully against infection risk," Dr Bajwa explained.
She added that Al Muhairi can otherwise look forward to a regular life, with heart transplant patients living up to 15 years afterwards.
"This transplant, performed on a patient with an assistance device, marks the hospital's [graduation] to a complete heart failure centre. We treat patients with heart failure, bridge with assistance devices when required and offer transplants," Dr Bajwa said.
"During the time I waited for a heart to become available, I never lost hope. My family and doctors were by my side the entire time, and I had faith that my patience would be rewarded. I had lived with my condition for a long time and I was excited to get a second chance to live my life and be there for my family," Al Muhairi said.
"Every day I listen to my heart beat and I think of the people who made my life possible. I would like to thank the donor and their family. This is truly a great step in the development of our nation," he added.
Dr Bajwa said the next step, depending on patient need, is for Cleveland Clinic Abu Dhabi to offer multi-organ transplants to a single patient, such as heart-and-kidney or a heart-and-liver transplant.


The Biltmore Forest area of Asheville NC is rich in history and one of the most sought after historic home areas of this region. See why George Vanderbilt moved here in the late 1800's to build his one of a kind summer estate, the Biltmore house, and then never wanted to leave. The Biltmore Forest area is where true Asheville NC natives are able to call home and where others are always hoping to find bargains on homes. Call us today at (828)-215-9064 or contact Green Mountain Realty for Biltmore Forest land, homes, condos or real estate.
I have a question about the property at 2 Cleftridge Court Asheville NC 28803 (#3466916).
I would like to schedule a visit for the property at 2 Cleftridge Court Asheville NC 28803 (#3466916).
**Accepting Backup Offers** Located in highly desirable Biltmore Forest, this is mid-century modern at its best. The thoughtful design + floorpan make for fantastic shared indoor/outdoor living. Three bedrooms with en-suite bathrooms are located on the main floor, with an additional office and bonus room located on the lower level. The open concept kitchen/dining area/family room allows for amazing entertaining and flow. Kitchen includes handmade custom tiles, butcher block island, bar area and wood-burning fireplace. The enclosed backyard has been thoughtfully redesigned with a new deck, paver patio and newly planted landscape. Conveniently located near Biltmore Village, and only minutes to downtown! Owner is licensed NC Broker.
I have a question about the property at 30 Forest Road Asheville NC 28803 (#3490853).
I would like to schedule a visit for the property at 30 Forest Road Asheville NC 28803 (#3490853).
I have a question about the property at 11 Light Cahill Court Biltmore Lake NC 28715 (#3483842).
I would like to schedule a visit for the property at 11 Light Cahill Court Biltmore Lake NC 28715 (#3483842).
I have a question about the property at 101 Orvis Stone Circle Biltmore Lake NC 28715 (#3453935).
I would like to schedule a visit for the property at 101 Orvis Stone Circle Biltmore Lake NC 28715 (#3453935).
Biltmore Forest living REDUCED and under a million! A memorable French Normandy country home sited on a level .5 acre lot in historic Biltmore Forest. Gracious living and dining rooms with access to the rear covered porch and terrace to the rolling back lawn. Full kitchen renovation with clean lines, top of the line appliances, and excellent granite selections. Just off the kitchen an expansive walk-in pantry. A simple but flowing floor plan in the not so big house offering three bedrooms, three-and-half fully renovated baths Master has steam shower, plus an amazing exercise/bonus space. Subtle historic architectural features and details are found throughout this home! Slate roof with copper accents, gutter and downspouts, a treasure in the forest with new HVAC systems for year-round comfort! Upstairs bonus space has full bathroom and nice window overlooking the rear lawn. A fabulous find in the forest!
I have a question about the property at 375 Vanderbilt Road Asheville NC 28803 (#3361468).
I would like to schedule a visit for the property at 375 Vanderbilt Road Asheville NC 28803 (#3361468).
I have a question about the property at 22 Orvis Stone Circle Biltmore Lake NC 28715 (#3307143).
I would like to schedule a visit for the property at 22 Orvis Stone Circle Biltmore Lake NC 28715 (#3307143).


text:
Laphroaig Tasting
With many hours of darkness and a definite chill in the air, November was calling for something to warm the cockles. There are lots of options when it comes to heavily peat influenced scotch, and all have their own characteristics and idiosyncrasies. Islay is the classic place to start with the big Kildalton bruisers on the south coast…
Macallan & Mortlach
Macallan. The heaviest hitting distillery of them all? Certainly the one that consistently pushes out increasingly old, limited and expensive releases, and one with an extensive and well-funded fan base and unbelievable auction results. Brilliantly marketed to the public, the distillery increasingly seems to suffer from an image problem amongst whisky aficionados…
Glen Scotia Tasting
Glen Scotia has a fair old pedigree, with the distillery having been founded all the way back in 1832, and is located square in the middle of the Victorian whisky capital of the world, Campbeltown. It's one of just three surviving distilleries in the region, when once there were more than ten times that number. I've heard numerous stories about why…
Buffalo Trace Tasting
Sattu Sarang
Since the late 1700's, Buffalo Trace (@buffalotrace) has survived the challenges of Mother Nature and those of politics alike, but has produced exquisite whisky without compromise. The timeless dedication of the people behind the scenes has been elemental in shaping the distillery to what it is today and with it, a splendid story that has…
Worm Tubs
July has started very well indeed. Not only are days warm and nights long but events at the club have been going from strength to strength. On Wednesday 10th July the club met once again at The Bottlescrue in St Pauls for a geeky night of whisky fun. The theme for the night was distilleries that use worm tub condensers…
Cotswolds Tasting
June is a time when the countryside starts to show off its beauty with lush green fields, colourful flowers and bright sunny days. It only seemed fitting therefore to host a tasting by a distillery that prides itself on creating a spirit that mirrors its magnificent country setting. The Cotswolds have to be one of the most beautiful areas in England…
Young Whisky
In the past a Whisky's reputation was built upon successful marketing and word of mouth. Age was but a number and many whiskies succeeded because companies were happy to push out solid whiskies where their age statement was a minimum assurance as opposed to a number to aim at. In the boom times after WW2 capacity increased dramatically…
Mackmyra Tasting
The first event in April saw the second distillery tasting for the club. Back in March we welcomed Ibon from the Loch Lomond Group and this time around we were able to host Shane from the up and coming Swedish distillery Mackmyra. Up and coming might be the wrong term as Mackmyra has been around for a good few years now…
Loch Lomond Tasting
March saw another first for The London Whisky Club, a hosted tasting by the good people at Loch Lomond Group. To be more specific by Ibon, the brand ambassador for the Loch Lomond Group. As a young club it is really exciting to see these events come together and provide even more opportunities to enjoy and share whisky…
Blind Tasting
February at the club saw a slightly different format to usual. We held the first blind tasting we've ever done. Blind tasting whisky is one of the best ways to learn about your palate, your likes/dislikes and the whisky itself. When all preconceived notions about brand, reputation, cask type, colour, marketing etc are stripped away and…

redpajama_set_name: RedPajamaCommonCrawl


text:
25 Jan Firefox 58 Includes Tracker Blocker, New Security Fixes
Mozilla announced that Firefox 58, which was released this week, was not only built with a number of performance enhancements, but also includes fixes for security flaws present in the previous version. Mozilla says that Firefox 58's Tracking Protection feature, which was first implemented in...
25 Jan Bell Canada Suffers Second Breach in Eight Months, 100,000 Customers Compromised
Last Tuesday, BCE Inc. admitted that hackers were able to breach their systems and had stolen the data of around 100,000 customers. The data includes information such as names and email addresses. Bell spokesperson Marc Choma assured that no credit card or banking information had been...
25 Jan Google Can Use Bluetooth to Track Phone Even When Turned Off
It was found through a recent investigation by a Quartz reporter that Google is still able to use an Android phone's Bluetooth to collect location-related data even if the user has turned it off. Quartz reported that Google is able to collect the unique identifier codes...
25 Jan South Korean Exchanges Fined for Privacy Issues
A fine totalling to 141 million won ($130,000) was handed down by the South Korean government to eight companies, namely Upbit, Ripple4y, Coinpia, Youbit, Korbit, Coinone and Coinplug, as well as cryptocurrency wallet service Eyalabs for not providing sufficient data protection for its users. The investigation,...
24 Jan DuckDuckGo Launches Revamped Mobile Apps, Includes Privacy Features Suite
Last Tuesday, DuckDuckGo announced that it has included a tracker blocker and a number of other privacy features in its revamped line of mobile apps and browser extensions for Android, iOS, Chrome, Firefox and Safari. CEO Gabe Weinberg says that the company's goal ever since...
24 Jan Hackers Can Intercept Tinder Photos and Swipes, Says Security Company
Security testing company Checkmarx recently revealed that a vulnerability on Tinder that could allow hackers to snoop on a user's photos and swipe activities. The bug, which is based on an HTTP connection and a predictable HTTPS response size, enables attackers to decode encryption signatures....
24 Jan Sega to Investigate Rumored Sonic Game Data Leak
A security company called Pradeo reported last week that several Sega games for Android: Sonic Dash, Sonic the Hedgehog Classic, and Sonic Dash 2: Sonic Boom had been leaking the sensitive data of around 120 million to 600 users who had downloaded it from Google's...
23 Jan Privacy International: Expect Global Risk if Microsoft Loses Data Access Appeal
UK charity Privacy International recently warned that the privacy rights of every person in the world will be endangered should Microsoft loses its appeal regarding the seizure of its data on its Ireland servers by US authorities. The statement was made in an amicus brief...
23 Jan Privacy Industry Booms with Advent of GDPR
It has been reported that companies are now spending millions to become compliant to EU's General Data Protection Regulation (GDPR), which is set to take effect in May this year. Companies who do not comply to the EU law, which has a number of technically...
23 Jan Irish High Court to Take Time With Questions on Schrems Privacy Case
Justice Caroline Costello of the Irish High Court recently announced that she will be taking time to determine what questions to present to the Court of Justice of the European Union (CJEU) with regards to the EU-US privacy case involving Facebook and activist Max Schrems. The...


In the 1940 film Foreign Correspondent, one of my favorites directed by Alfred Hitchcock, a New York City newspaper editor unexpectedly awards the choice European beat to Johnny Jones, a local news reporter who has never been overseas. Of course, that editor understands that it's far more difficult to master the art of reporting than to find one's way from London's Leicester Square to the Houses of Parliament.
In November we assigned our talented editorial resident Corrie Cutrer, a May 2000 graduate of Mississippi College, to cover Reinhard Bonnke's evangelistic crusade in Lagos, Nigeria. This event was expected to draw crowds in excess of one million people per night. Corrie is no slouch when it comes to overseas travel, having spent a summer in Gaza teaching English as a second language to mostly Muslim Palestinians in 1998. But among African nations, Nigeria is in a category by itself. With 124 million people, it has the continent's largest population. It has enormous crude-oil wealth and corruption to match. Religiously, Nigeria is almost evenly divided between Muslims and Christians and the nation is a lethal hotbed of political and religious conflict.


text:
Intentwise Ad Optimizer
Intentwise Analytics Cloud
Intentwise DSP
SQL Training
Data Strategy White Paper
Protect Your Brand Through Amazon Brand Registry
It's no news that the free availability of counterfeit products on online marketplaces is one of the top challenges that brands, consumers, and ecommerce companies themselves face today. In fact, a recent investigation by the U.S. Government Accountability Office (GOA) found that 43%—or nearly half—of the products bought from online marketplaces were fake. The infringement of intellectual property rights at this scale presents an existential threat to brands and ecommerce companies as it can destroy consumer trust and hurt a brand's reputation.
The good news is that Amazon recognizes the urgent need to help sellers protect their brands and prevent the sale of counterfeit goods. The Amazon Brand Registry is a concrete step toward doing that.
Amazon Brand Registry is a free service that allows sellers to enroll their brands with Amazon and easily track and resolve copyright infringements. According to Amazon's website, the registry currently protects more than 130,000 brands and investigates and resolves 95% of infringement complaints within 24 hours.
Amazon Brand Registry is global and contains:
Brand profile data (e.g., trademarks, logos)
Accounts that have roles (e.g., Rights Owner, Catalog Contributor) for that brand.
What is a Brand
A brand is a name that represents a product or set of products. Products with the same brand share a common name, logo, or other identifying marks that appear on the product or its packaging and distinguishes those products from similar products that do not belong to that brand. These brands will be stored in Amazon Brand Registry with a unique brand ID. Products without a brand are considered generic and will not be present in the Amazon Brand Registry.
Requirements for a Brand to Enroll in the Brand Registry
According to Amazon's website, to register your brand, you'll need:
A registered trademark for your brand that appears on your products or packaging.
The ability to verify yourself as the rights owner or the authorized agent for the trademark.
An Amazon account. You can use an existing Amazon account (credentials associated with Vendor or Seller Central) or create a new one for free.
How to Enroll Your Brand in the Brand Registry
Brands can enroll by visiting Brand Registry (or the respective international URL – e.g., .com, .co.uk, .in, .de, .fr, .it, .es, .co.jp, .com.mx, .ca, com.au, com.br. etc.), where they will:
If the user has an existing Vendor or Seller account, they can use their existing credentials and do not need to create new account credentials. If the user needs to create new account credentials, they will need to provide their name, company name, phone number, email address, and create a password.
Provide Brand data
To associate a brand with an account the rights owners will be needed to provide multiple pieces of data about the brand and your company, including the government-registered trademark registration(s) where Amazon Brand Registry is launched (US, BR, CA, MX, UK, ES, IT, FR, DE, AU JP, IN):
The brand name that has an active registered trademark; the trademark text must match the brand name on the application.
The associated government-registered trademark number.
A list of product categories (e.g., apparel, sporting goods, electronics) in which your brand should be listed.
A list of countries where your brand's products are manufactured and distributed.
Amazon will verify the brand profile data as part of the approval process as well as if the applicant is authorized to make decisions on behalf of the brand. As a result of the enrollment process, amazon will:
Determine whether to enrol the brand
Create a brand profile based on validated brand characteristics (e.g., intellectual property)
Assign the account that submitted the application to have a specific role(s) for that brand
Benefits for Sellers Enrolling in Amazon Brand Registry
Amazon Brand Registry enables you to better control how your brand is represented and helps you identify and report copyright infringements so that Amazon can quickly resolve complaints and stay ahead of attempted violations. Brand Registry does this by giving you more autonomy over your brand's Amazon product pages so that visitors see accurate brand information.
The service also gives sellers access to powerful search and report tools that make it easier to identify and flag copyright infringements. According to their website, the tools include:
"Global Search: Search for content in different Amazon stores from the same screen without ever having to navigate away
Image search: Find product listings on Amazon that match your product(s) or logo(s) using images
Bulk ASIN Search: Search for a list of ASINs or product URLs in bulk to explore and report potentially infringing content fast"
Brand Registry also provides clear workflows to report potential infringements.
In addition, Brand Registry uses information collected from brands to implement predictive protections that aim to zero in on and eliminate potentially bad listings. It uses AI, image recognition, and other deep technology to power text- and image-based search and flag incorrect use of trademarks and logos. The service also alerts Amazon when sellers ship products from locations where the brand does not have a presence or when a product listing is created outside of a brand's Amazon product catalogue.
Amazon claims that after deploying these tools "99% of all Amazon page views by our customers landed on pages that did not receive a notice of potential infringement." What's more, brands enrolled in the registry "report an average of 99% fewer suspected infringements than before the launch of Brand Registry."
This data suggests that every brand that cares about guarding its turf on Amazon should leverage this free service immediately. Enrolled brands also stand to gain from the new IP protection initiatives and experiments such as Transparency and Project Zero that Amazon is rolling out as we speak.
Read our post "Maximize Customer Engagement and Sales with Amazon Stores" to understand how you can leverage Amazon Stores to create an engaging shopping experience.
Amazon, Amazon Advertising, Retail Media
Three Use Cases for Amazon Marketing Cloud
Intentwise News
Welcome to Intentwise Analytics Cloud
Three Lessons From Building a Data Stack on Amazon's APIs
Subscribe to our Newsletter
Facebook-f Linkedin-in Youtube Twitter Instagram Amazon
Amazon Sponsored Ads


text:
Asia Week New York Breaks Record With $360M in Sales
Kumoi Cherry Trees, ca. 1926 Hiroshi Yoshida (1876-1950) Woodblock print
Scholten Japanese Art
The 2015 edition of Asia Week New York concluded its nine-day Asian art extravaganza with record-shattering sales totaling $360M, almost doubling last year's number with an 80% increase of $160M.
Said Carol Conover, chairman of Asia Week New York: "By all accounts, we have succeeded in making New York the destination for buying Asian art, not only for many of the great museums in the United States and abroad, but also for the leading international private collectors. Galleries saw steady and heavy traffic throughout the week, and sales for the four major auction houses reached new highs, making it a great success in terms of revenue in all areas across the board. With the influx of new buyers from China who came here for the sale of The Robert Hatfield Ellsworth Collection at Christies, the exuberance and excitement of the week was palpable."
New York was ablaze with excitement as the 42 international galleries of Asia Week New York simultaneously opened their doors for the Open-House Weekend on March 14-15. Enhancing the buzz was the magnificent reception at The Metropolitan Museum of Art that kicked-off the whirlwind of activities, with more than 650 collectors, curators and Asian art specialists in attendance. This evening was a prelude to Asia Week's specially curated exhibitions and packed auctions that were overflowing with international buyers from mainland China, Hong Kong, Taiwan, India, Japan, Korea, England, France, Switzerland and the United States.
Vajrapani Nepal, circa 1275 Gilt copper alloy inset with semi-precious stones Height 18 1/8 in. (46 cm.)
Carlton Rochell Asian Art
Museum curators, many of whom were accompanied by their donors, were seen trekking through galleries and auction houses throughout Asia Week New York representing a multitude of museums. Among them were: The Asian Art Museum in San Francisco, The Rubin Museum of Art, The Metropolitan Museum of Art, The Solomon R. Guggenheim Museum, Brooklyn Museum, Museum of Fine Arts, Boston, China Institute, Asia Society, The Art Institute of Chicago, The Minneapolis Institute of Art, The Portland Museum, The Philadelphia Museum of Art, The Honolulu Academy of Arts, The Norton Museum of Art, The Princeton University Art Museum, The Harvard Museums, Newark Museum, The Samuel P. Harn Museum—University of Florida, Japan Society, The Santa Barbara Museum of Art, The Indianapolis Museum of Art, The Burke Foundation, The Cleveland Museum, The Spencer Museum—University of Kansas, The Smart Museum—University of Chicago, The Nelson Atkins Museum of Art, the Yale University Art Gallery, the Berkeley Art Museum, The MacLean Collection, The Jordan Schnitzer Museum of Art, The Virginia Museum of Fine Art, the John and Mable Ringling Museum of Art, the British Museum and the Shanghai Museum.
Accolades abounded from the international specialists in all the collecting areas who participated in Asia Week New York.
Carol Conover, who in addition to her chairmanship of Asia Week New York, is the managing director of New York's Kaikodo LLC, "was thrilled to sell to Chinese museums for the first time, as well as to American institutions and private collectors." Among the works sold were a Longquan Lotus Shaped Celadon Bowl; a Pair of Famille Rose Saucers; a Bamboo Lotus Leaf Form Water Container; Calligraphy by Mei Qing (late 17-18th century); "Moment of Truth The Synergy of Ink," no. 32, by Wai Pongyu; and a 17th century ink and color hanging scroll, "Death of the Buddha."
Said James Lally of J.J. Lally & Co, in New York: "Asia Week New York 2015 was the biggest and busiest yet. Sales were strong throughout the week and we saw more new buyers than ever before." Lally sold four different Ming dynasty bronze incense burners to one collector; a rare Cloisonné Enamelled Scroll-Form Stand sold to an Asian Museum; and a very finely cast Bronze Rhinoceros-Form Waterdropper was acquired by The Metropolitan Museum of Art.
Gisèle Croës, who was here from Belgium, curated a dramatic exhibition at the Gagosian Gallery, where she had a very successful week. "Asia Week was a big success for us," said Ms. Croës. Among the sales she reported was a rare Archaic bronze vessel, from the Shang dynasty (1600 - 1050 BC).
"I was very pleased with the week, and delighted to work directly with so many overseas collectors," said Eric Zetterquist of his eponymous New York gallery, which specializes in Chinese works of art. Zetterquist reported that his star lot, a Splashed Junyao Barbed Small Plate, from the Jin-Yuan Dynasty, sold early in the week, while Nicholas Grindley, of Nicholas Grindley Works of Art, Ltd, another purveyor of traditional Chinese works of art, reported sales that included a late Ming Huanghuali corner leg table, as well as a large lacquer Ming dynasty circular box and cover depicting a dragon with five claws, dated 1619.
Chinese art specialist Erick Schiess, whose Jadestone Gallery is based in Portland, Oregon, reported a number of very good sales including a painting of Bodhidharma by Wang Zhen, a set of silver-lined Yixing teacups attributed to Chen Mingyuan, and an 18th Century black and white jade toggle with cats, a piece that once belonged to his father many years ago, and that he had only recently re-acquired. It sold it for 30 times its selling price in 1999.
Clare and Michael Chu, principals of the Los Angeles-based Asian Art Studio saw their prized scholars' desk objects purchased by more mainland China collectors, while their snuff bottles were snapped up by American collectors. "We were very happy to see more interested curators passing through our doors this year," said Ms. Chu.
Southeast Asian, Indian and Himalayan specialists echoed enthusiasm for this year's Asia Week New York.
"We are thrilled with the results of this year's Asia Week," said Carlton Rochell of his eponymous New York gallery. "We sold 25 works totaling over $8M." He reported that American buyers dominated this year with mainland Chinese buyers coming in a close second. The highlight of the week was in the fine group of Himalayan works of art, which included bronze sculpture and paintings from Tibet and Nepal. The top work sold was a sculpture of Vajrapani from Nepal, circa 1275, of gilt copper alloy inset with precious stones. "We were also pleased to present our first stand-alone exhibition of Classical Indian Paintings which drew a very enthusiastic response from museum curators and private collectors internationally," Rochell said.
Suneet Kapoor, principal of Kapoor Galleries in New York, reported increased traffic and interest from past years. "Though the majority of buyers were from the United States and Europe, we met many new collectors, dealers and curators from Asia." Mr. Kapoor's sales included a very important Jain marble sculpture, dated to 1028 AD, along with a few of the beautiful Indian Miniatures on display that was purchased by an American collector; The Illustration to a Gita Govinda series of paintings was snapped up by a prominent European collector; a very rare and important Nepalese bronze of Uma-Maheshvara was sold to a distinguished European collection; and a beautiful silvery portrait of Padmasambhava and a very fine gilt-bronze image of Kubera, from the Ming dynasty to went to an important American collection. "We are delighted by the continued interest and support of our clients and visitors and look forward to Asia Week New York 2016!"
Dr. Robert R. Bigler, here from Switzerland, had tremendous feedback from museum curators and private collectors for his exhibition titled Before Yongle-Chinese and Tibeto Chinese Buddhist Metal Images from the 13 and 14th century, the first exhibition of its kind devoted to the subject. "I sold my most important piece to an American collector and museums have expressed interest in several pieces," said Dr. Bigler.
"We had a very strong and positive response to our exhibition of Indian Painting, 1590-1870," said Brendan Forge of the London-based Oliver Forge & Brendan Lynch Ltd. Mr. Forge said he met several new private clients and museum curators, and reported that the painting of Emperor Akbar with his grandson, the future Emperor Shah Jahan, from Imperial Mughal, circa 1627-30, sold to a private collector in London, while his catalogue's cover painting, depicting the King of Afghanistan, was snapped up by an overseas collector. In addition, two important works were reserved by American institutions.
Shawn Gassemi, of the San Francisco-based Art Passages, sold paintings to the Asian Art Museum in San Francisco and to American and Chinese private collectors.
From Kuala Lumpur, Malaysia, first-time participant Shalini Ganendra, of her eponymous gallery, debuted a selection of cutting-edge contemporary Asian art that was met with enthusiasm from collectors and curators alike. "We were pleased to make our debut at Asia Week New York, with a view to developing a strong platform for quality Contemporary Asian Art," said Ms. Ganendra. "In addition to sales, we met curators from The Museum of Modern Art, The Metropolitan Museum of Art, The Rubin Museum of Art and the International Center of Photography."
In the Japanese art realm, dealers in ancient and contemporary also reported great enthusiasm with brisk buying among museums and private collectors.
"Old and new collectors alike contributed to a week of unprecedented sales in Japanese ceramics from our Madison Avenue gallery- making it one of the most successful Asia Week exhibitions to date," said Joan Mirviss, of her namesake gallery. "Not only did our current exhibition Tsubo: The Art of the Vessel, nearly sell out, but the gallery more than doubled these numbers in its additional sales of innovative, concept-driven works by several important young artists. The ethereal ribbon-like sculptures of Kino Satoshi proved wildly popular: museums and private collectors snapped up all six new works within 48 hours." Ms. Mirviss also reported that a selection of scenic sculptural vessels, by Hoshino Kayoko, with beaded metallic glaze quickly found homes with established collectors, as did Takemura Yuri's enchanting polychrome tea-bowls -- two pieces sold within seconds of each other to individual private collectors, and the twisted and collapsed forms of Yoshimura Toshiharu swiftly sold to first-time clients from both coasts.
Said Katherine Martin of Scholten Japanese Art: "Our exhibition, Kacho Fugetsu: Natural Beauty in Japanese Art, was devoted to the classic Japanese theme of 'the beauties' of nature (flowers, birds, wind and moon). The oversized woodblock print, Kumoi Cherry Trees, ca. 1926, by Hiroshi Yoshida (1876-1950), a breathtakingly beautiful view of two ladies beneath a weeping cherry under the moonlight, was one of our first works to sell, but many print collectors appreciated the opportunity to view in person a very fine impression of one of Yoshida's best and most sought-after prints." Ms. Martin was also pleased that several paintings sold, including a charming painting of a Playing Cat by Mochizuki Gyokkei (1874-1938), the buyer of which was directly inspired by the popular exhibition, Life of Cats, on view now at the Japan Society Gallery.
Carole Davenport, saw an influx of curators and private collectors who purchased a variety of works of art including the imposingly large scroll created in 1769 the revered artist Maruyama Okyo that shows a pair of dramatic tigers in a landscape setting. "I was very happy to welcome returning clients and meet new ones," said Ms. Davenport.
This year, Asia Week New York welcomed back Aman as their Presenting Sponsor. Aman was founded in 1988 with the vision of building a collection of intimate retreats with the unassuming, warm hospitality of a gracious private residence. The first, Amanpuri (place of peace) in Phuket, Thailand, introduced the concept, and since then, Aman has grown to encompass 26 resorts located in Bhutan, Cambodia, China, France, Greece, Indonesia, India, Japan (Aman Tokyo opening December 22, 2014), Laos, Montenegro, Morocco, the Philippines, Sri Lanka, Thailand, Turkey, the Turks & Caicos Islands, the USA and Vietnam.
Asia Week New York Association, Inc. is a 501(c)6 non-profit trade membership organization registered with the state of New York.
For more information visit www.AsiaWeekNewYork.com
Tags: Asian art asian antiques
Eclectism On Tap July 10 At Benefit Shop Foundation
The Art and Antique Dealers League Announces Exhibitor Line-up for October Fine Art & Antiques Show
R.J. Horner Dining Set, Qi Baishi To Lead Clarke Auction Gallery June 30
Fine artworks coexist in perfect harmony alongside Asian objects in Bruneau & Co.'s June 6th auction
Cai Guo-Qiang Brings His Gunpowder Art to Ohio in 'Cuyahoga River Lightning'
Striking screenprint by Mark Kostabi will be in Andrew Jones' next DTLA auction, June 16th
The Hermitage in Virginia Will Show Some of the Biggest Names in Contemporary Asian Art This Summer
Art-Competition.online opens new Art Contest, we Love our Pets 2019, closing on Jul 15.


Since 2016 you are obliged to report certain data breaches, in case you have had one. But when is a data breach really necessary to report? Find out in this article.
Other examples: cyber attacks (including DDos), email sent to wrong addresses, stolen laptops, discarded uncleaned computers and lost USB sticks.
Illegally obtained business data on a production process or market strategy concern valuable information, but do not fall under the common definition of data breach.
An employee has left his business laptop in his car and that laptop has been stolen from the car. That is, of course, a security incident, but is it also a data breach? That depends in the first place on what was on the laptop, of course, but for the example, let's assume that there were (financial) customer data on the laptop.
Several years ago, one of our partners received an employment agreement from another employee. He could see everything regarding salary, personal data etc. Thus, there may even be a data breach within a company when an employee's personal data is shared with another employee who is not allowed to inspect it.
A good way to secure data is to encrypt it. At that moment, the data becomes a series of numbers and letters that are meaningless. Only if you have the key you can view the data. However, if you lose the key, you will no longer be able to access the data. Others are not either, but the fact remains that the data is therefore unavailable, and that is also a data breach.
personal data of a sensitive nature have leaked. E.g. data on religion or belief, race, political persuasion, health, sexual life, trade union membership or criminal data.
the nature and extent of the breach lead to (a significant likelihood of) serious adverse consequences for the protection of personal data. You may still need to report the data breach if the nature and extent of the breach is such that it leads to (a considerable risk of) serious consequences for the protection of personal data. This will be the case, for example, where a particularly large amount of personal data of large groups of data subjects has leaked.
In both cases stated above, you have to report the data breach within 72 hours to the DPA. Some data breaches should be reported not only to the National DPA but also to the persons to whom the data leaked relate. This is the case if the data breach is likely to have an adverse impact on the privacy of the individuals concerned.
In our plugin, you can find a data breach inventory which will help you decide whether you need to report your data breach or not!


Tenkomori Ramen House is a fairly new ramen joint, they're run by the same menya chain that owns Oiden and Menya Mappen so perhaps our expectations were a bit high.
The first bowl above was the Karaage Shoyu Ramen. The soup was really delicious but I kind of expected something more, but why complain about the cheapest ramen you can find in Sydney?! The chicken pieces were large and the ramen noodles were chewy. Too be honest, tastes quite similar (not the best though) to other Karaage Ramen in Ichiban and Menya, but as I said, CHEAP RAMEN!
We've previously heard that Tenkomori uses milk in their Tonkotsu so I was a bit excited to try it out. However I was quite disappointed in as the milk didn't work too well as the soup and tasted slightly sour? Also the soup wasn't very thick, a bit watery with milk…O.O On the bright side, the pork katsu was great and wasn't too dry, decent and filling meal overall.
Tamago! Nothing much to comment besides the egg tasting good as per usual. 😛 Though perhaps a little bit overcooked. Overall, we may come here again, maybe if I'm feeling really cheap to buy lunch/dinner or they improve their menu and dishes.


Althea Kaminske is an Assistant Professor at St. Bonaventure University in Olean, NY, our newest member of the Learning Scientists, co-Director of CALM (the Center for Attention, Learning and Memory), and author of the book 5 Teaching and Learning Myths Debunked: A Guide for Teachers.
In this episode, Megan interviews Althea at the Psychonomic Society Conference in New Orleans, LA. (Note, we're in the conference hotel, and so you can sometimes hear some street noise!!) Althea is conducting research with students on learning and distractions of cell phones and exercise and learning.


text:
How old was Anna Chancellor in the movie Agent Cody Banks 2: Destination London?
Anna Chancellor was 37 in Agent Cody Banks 2: Destination London when she played the character 'Jo Kenworth'.
That was over 19 years ago in 2004.
Today she is 57, and has starred in 46 movies in total, 30 of those since Agent Cody Banks 2: Destination London was released.
How old do you think she looks in the movie?
In Agent Cody Banks 2: Destination London, I think Anna Chancellor looks:
👵 Older than 37
👩 About 37
👧 Younger than 37
Director Kevin Allen has worked with Anna Chancellor just once in her career.
Anna Chancellor's first movie was as 'Barmaid' in Killing Dad (Or How to Love Your Mother), released in 1989 when she was 23
Agent Cody Banks 2: Destination London scores 5.49 out of 10 on TMDB.
The cast of Agent Cody Banks 2: Destination London
Frankie Muniz
Paul Kaye
Alfie Allen
Anna Chancellor's other movies
Four Weddings and a Funeral
How I Live Now
Testament of Youth
Killing Dad (Or How to Love Your Mother)


text:
TED Books library
Asteroid Hunters
Broken Spaces & Outer Places
How to Fix a Broken Heart
How We'll Live on Mars
In Praise of Wasting Time
Judge This
Thanks A Thousand
The Art of Stillness
The Boiling River
The Future of Architecture
The Great Questions of Tomorrow
The Hot Young Widows Club
The Laws of Medicine
The Mathematics of Love
The Misfit's Manifesto
The Terrorist's Son
When Strangers Meet
Who Are You, Really?
Why Dinosaurs Matter
Why We Work
Read › TED Books › TED Books library ›
TED Book: Broken Spaces & Outer Places
Okorafor's gripping account of her recovery will inspire any reader.
Broken Spaces & Outer Places: Finding Creativity in the Unexpected
A powerful journey from star athlete to sudden paralysis to creative awakening, award-winning science fiction writer Nnedi Okorafor proves that what we think are our limitations have the potential to become our greatest strengths.
Available in hardcover, Kindle and audio
Available in hardcover, NOOK and audio
Download the eBook for your Google device
Available at your favorite indie bookseller
Nnedi Okorafor was never supposed to be paralyzed. A college track star and budding entomologist, Nnedi's lifelong battle with scoliosis was just a bump in her plan—something a simple operation would easily correct. But when Nnedi wakes from the surgery to find she can't move her legs, her entire sense of self begins to waver. Confined to a hospital bed for months, unusual things begin to happen. Psychedelic bugs crawl her hospital walls; strange dreams visit her nightly. Nnedi begins to put these experiences into writing, conjuring up strange, fantastical stories. What Nnedi discovers during her confinement would prove to be the key to her life as a successful science fiction author: In science fiction, when something breaks, something greater often emerges from the cracks.
In Broken Places & Outer Spaces, Nnedi takes the reader on a journey from her hospital bed deep into her memories, from her painful first experiences with racism as a child in Chicago to her powerful visits to her parents' hometown in Nigeria. From Frida Kahlo to Mary Shelly, she examines great artists and writers who have pushed through their limitations, using hardship to fuel their work. Through these compelling stories and her own, Nnedi reveals a universal truth: What we perceive as limitations have the potential to become our greatest strengths—far greater than when we were unbroken.
A guidebook for anyone eager to understand how their limitations might actually be used as a creative springboard, Broken Places & Outer Spaces is an inspiring look at how to open up new windows in your mind.
Growing up, most science fiction novels and films presented bold white male-dominated worlds where I knew I could never exist on my own terms.
Nnedi Okorafor is a Nigerian-American author of African-based science fiction, fantasy, and magical realism for children and adults. Her works include Who Fears Death (currently being developed by HBO into a TV series), the Binti novella trilogy (currently being developed by Hulu into a TV series), the Book of Phoenix, the Akata books, and Lagoon. She is the winner of Hugo, Nebula, World Fantasy, Locus, and Lodestar awards, and her debut novel Zahrah the Windseeker won the prestigious Wole Soyinka Prize for Literature.
Nnedi has also written comics for Marvel, including Black Panther: Long Live the King and Wakanda Forever, featuring the Dora Milaje and Shuri characters. She is also the writer of the science fiction comic series published by Dark Horse called LaGuardia. She lives with her daughter Anyaugo and family in Illinois. Follow Nnedi on twitter (as @Nnedi), Facebook, and Instagram. Learn more about Nnedi at Nnedi.com.
Illustration: Abdulkareem Baba Aminu


It's Friday and I'm exhausted.
It's Friday and I know the weekend will be busy so I'm fearful.
It's Friday and all I want to do is curl up in my bed and watch Harry Potter.
It's Friday and I'm on a bus heading to a state 4 hours from my bed.
It's Friday and I'm hopeful that one day I will shape all the Fridays in my life so that they end with movies and blankets.
I will fill my future with the guarantee of long naps on Fridays and restful weekends.
I believe I can create this future that I so desperately desire.
But here I am, on this bus…again.
With every passing second I feel the straining of my precious relationship with my own bed.
It's Friday and I have "Harry Potter and the Sorcerer's Stone" on audiobook so I'll make due with what I have.
So as I sit under this blanket with headphones perched on my head, listening to this book and fantasizing about the perfect Friday, I am grateful for the 24 hours I was given today.


text:
News Release No. 298 - 2018 TSX Venture Exchange - HGO
HAWKEYE TO CLOSE ITS NON-BROKERED PRIVATE PLACEMENT FOR TOTAL PROCEEDS OF $915,000
Vancouver, British Columbia, Canada – HAWKEYE Gold & Diamond Inc. (the "Company" or "HAWKEYE") (TSX.V-HAWK; Frankfurt Ticker: HGT; WKN: A12A61 ISIN: CA42016R3027): announces that subsequent to the Company's original news release dated June 27, 2018 (release No. 288 – 2018) whereby HAWKEYE announced a non-brokered flow-through and non-flow-through financing for total proceeds of $750,000 (CDN), and a succeeding news release dated September 24, 2018 (release No. 295 – 2018) whereby the Issuer announced it had closed the first tranche of this financing for total proceeds of $850,000 (CDN), HAWKEYE will be submitting final documentation to the TSX Venture Exchange to close the second tranche of the placement by issuing 1,300,000 Common Units (non-flow-through) at a price of 0.05 per unit for total proceeds of $65,000 (CDN). Upon closing of the second tranche the Company will have raised a total of $915,000 (CDN) relating to this placement. Proceeds from the Offering will be used for general working capital, trades, exploration expenditures and no finders' fee will be paid in connection with closing of the second tranche of this placement
Each Common Unit consists of one non-flow through common share of the Company and one transferable share purchase warrant, with each such warrant entitling the holder to acquire one common share at a price of $0.10 per common share for a period of twenty-four (24) months from closing. If the Issuer's common shareshave a closing price of $0.20 (CDN) or more per share for ten consecutive trading days on the TSX Venture Exchange (the "TSXV"), the Corporation shall be entitled to give notice to the holders of the warrants issued pursuant to the Common Units that such warrants will expire thirty days from the date of mailing of such notice or the news release of such notice, unless such warrants are exercised before the expiry of that period, and in such event all unexercised warrants will expire at 4:30 p.m. (Vancouver time) on the last day of such thirty day period. None of the warrants issued pursuant to the Offering will be listed for trading. The Common Units and the underlying securities issued pursuant to the second tranche of this private placement offering will be subject to a four month hold period from closing.
About HAWKEYE
HAWKEYE Gold & Diamond Inc. is a junior mineral exploration and development company based in Vancouver, British Columbia, Canada. The Company's precious and base metals properties are located in the prolific BC Golden Triangle, world-class Barkerville gold camp and Vancouver Island, BC, Canada. HAWKEYE's corporate mandate is to build strong asset growth and shareholder value through the acquisition of low-cost, high-potential cash flow and production opportunities with blue sky discovery potential, and to manage our business in an environmentally responsible manner while contributing to the local community and economy.


text:
Bahrain sees pre-VAT splurge while UAE and KSA companies can expect audits
Consumers in Bahrain have splurged on big-ticket items in the lead-up to the Kingdom's VAT roll-out, with car sales reportedly up by as much as 20 percent. Meanwhile, professional services firm EY says businesses in the UAE and Saudi Arabia can expect full-scale tax audits in the year ahead, as local authorities move more confidently beyond the implementation period.
Retailers in Bahrain have experienced an unprecedented sales surge in the final days of the year according to local reports, with luxury items such as jewelry together with everything from vehicles, furniture and home entertainment systems flying out the door ahead of the new 5 percent VAT tax which has been applied from the start of this year – the third GCC nation to implement the tax following the UAE and Saudi Arabia in 2018.
With car and jewelry sales said to be up by as much as 20 and 40 percent, EY MENA's VAT implementation lead and international expert David Stevens told the Gulf Daily News such a rush was expected – as had been witnessed in the UAE and Saudi Arabia to some extent before the VAT roll-out in those jurisdictions at the start of last year. Unfortunately for retailers, spending is likely to dip in the coming months as price inflation begins to kick in.
"From what we have observed in Saudi Arabia and the UAE, there is likely to be a pull forward of some discretionary spending ahead of the VAT commencement date that will then see a decline in such spending after the tax is introduced," Stevens forecast previously, despite the modest 5 percent VAT being applied for the time being. The standard average VAT rate across most of Europe for example currently stands at above 20 percent. Meanwhile, Stevens, who was a senior government advisor during the implementation of the tax in Australia, has warned taxpayers in the UAE and Saudi Arabia that they can expect official audits in the year ahead, as local authorities settle into the new system. "These businesses need to prepare themselves to be able to completely justify all of their numbers, all of their data, all of their statements, all of their payments, all of their invoices, all of their record-keeping, and all various other aspects of their VAT compliance that will come under increased scrutiny by the authorities as we go into the second year of operation."
Still, concerns remain that many businesses have yet to achieve compliance, while regulatory issues persist. "The authorities will be launching audit activity while there are some areas with unclarified rules, so they won't know how to enforce them," added Stevens. "The pressure falls on the authorities to resolve any unsettled, non-clarified or disputed areas of interpretation. They need those clarified so that auditors can do their job and taxpayers need that to make sure they are fully compliant."
Recently, EY MENA's Tax Services leader Sherif El-Kilany urged the states of the GCC to move toward automisation of the tax system, a move tipped by Stevens to occur in the near future, with local states not bogged down by legacy systems. "It wouldn't surprise me if over the next 12 months we start to see announcements about the future of the VAT regime in this part of the world going towards a world-class, more digitised, electronic-based approach to compliance as well… In many ways they can go to these cutting-edge developments quite quickly," Stephens stated.
On the flip-side, El-Kilany noted part way through last year that the implementation of VAT in the region was driving wider moves toward digital transformation, with almost all of the tax professionals surveyed by the firm stating that they were in the process of or had already digitalised operations – in anticipation of government movement. "So in addition to being a significant revenue stream, the roll out of VAT is now clearly seen as a means of modernising the economy and putting the digital journey on the speed track," El-Kilany said.
Related: Deloitte introduces Arabic-language version of VAT app for the GCC.
More Tax
IBM Consulting helping Egypt's government with tax system overhaul Egypt's government has selected IBM Consulting to support a large digital overhaul of its national tax system.
Al Tamimi & Co once again named Middle East's top tax firm Al Tamimi & Co, a full-service law firm with 16 offices across the Middle East, has yet again been named the region's top tax firm by a prestigious industry forum.
Deloitte named Middle East's top transfer pricing services provider Deloitte has been named the Middle East's top consulting firm for transfer pricing at an annual industry awards ceremony, taking over the crown from arch-rival PwC.
EY news
EY launches its legal practice (EY Law) in Saudi Arabia Big Four firm EY has expanded its legal offering in the Middle East with the launch of a new 10-strong team in Saudi Arabia.
EY Israel follows China in shunning global break-up plan As EY's global organisation considers separating its audit and advisory brands, partners of two countries have already made it clear which side of the debate they are on.
Abu Dhabi's Ma'an enjoys pro-bono support from consultancies Ma'an, one of Abu Dhabi's leading organisations for social and community impact, has completed its latest cycle of programs – with pro-bono support from consulting firms McKinsey & Company, Deloitte,
Bahrain news
Bahrain consulting news
KPMG delivers training to compliance officers of Bahraini banks Experts from KPMG have delivered a training program to compliance officers of Islamic banks in Bahrain.
Bahrain International Airport Services flies in Lufthansa Consulting To meet the growing number of passengers travelling to and from Bahrain International Airport, the airport's services company has flown in consultants from a German group to help with operational exc
KPMG's annual intern uptake in Bahrain surpasses 70 mark KPMG's 'Hussain Kasim Professional Internship Program' in Bahrain looks back at one of its most active years since its inception, having welcomed over 70 interns to its ranks over the past year.
Saudi Arabia news
Saudi Arabia consulting news
Saudi Arabia's 2023 economic outlook (in 7 charts by Strategic Gears) Strategic Gears has released its 2023 economic outlook for Saudi Arabia, with its report providing in-depth insight into the state of the Kingdom's economy across key aspects such as monetary, fiscal
Kearney leaders on the firm's growth and ambitions in Saudi Arabia The increasing emphasis on diversifying the economy in Saudi Arabia is seeing a high demand for strategic consultancy.


text:
Q: layout how to configure I'm having trouble with my Layout. I want a horizontal file, whith two lines each one:
this is kind similar to what I want to get:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:orientation="horizontal"
  android:gravity="center"

>

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:gravity="center">

    <ImageView android:id="@+id/takeBike"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dip"
        android:layout_marginBottom="8dip"
        android:layout_marginLeft="20dip"
        android:src="@drawable/flecha_1"
        android:background="@null"/>

    <ImageView android:id="@+id/returnBike"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dip"
        android:layout_marginBottom="8dip"
        android:layout_marginLeft="20dip"
        android:src="@drawable/flecha_2"
        android:background="@null"/>

</LinearLayout>

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:gravity="center">

    <TextView android:id="@+id/takeTime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dip"
        android:layout_marginBottom="8dip"
        android:layout_marginLeft="20dip"
    />

    <TextView android:id="@+id/returnTime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dip"
        android:layout_marginBottom="8dip"
        android:layout_marginLeft="20dip"
    />

</LinearLayout>

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:gravity="center">

    <TextView android:id="@+id/parkingTake"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dip"
        android:layout_marginBottom="8dip"
        android:layout_marginLeft="20dip"
    />

    <TextView android:id="@+id/parkingReturn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dip"
        android:layout_marginBottom="8dip"
        android:layout_marginLeft="20dip"
    />

</LinearLayout>

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:gravity="center">

    <TextView android:id="@+id/useTime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dip"
        android:layout_marginBottom="8dip"
        android:layout_marginLeft="20dip"
    />

    <TextView android:id="@+id/cost"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dip"
        android:layout_marginBottom="8dip"
        android:layout_marginLeft="20dip"
    />

</LinearLayout>

But what I get:

where is the mistake?

A: The Android plataform has a specific layout for this situation, TableLayout.
Your layout using TableLayout:
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:stretchColumns="1">

    <TableRow>

        <ImageView android:id="@+id/takeBike"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_marginTop="8dip"
               android:layout_marginBottom="8dip"
               android:layout_marginLeft="20dip"
               android:src="@drawable/flecha_1"
               android:background="@null"/>

         <TextView android:id="@+id/takeTime"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_marginTop="8dip"
               android:layout_marginBottom="8dip"
               android:layout_marginLeft="20dip"/>

         <TextView android:id="@+id/parkingTake"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_marginTop="8dip"
               android:layout_marginBottom="8dip"
               android:layout_marginLeft="20dip"/>

        <TextView android:id="@+id/useTime"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_marginTop="8dip"
               android:layout_marginBottom="8dip"
               android:layout_marginLeft="20dip"/>

    </TableRow>

    <TableRow>

        <ImageView android:id="@+id/returnBike"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dip"
            android:layout_marginBottom="8dip"
            android:layout_marginLeft="20dip"
            android:src="@drawable/flecha_2"
            android:background="@null"/>

        <TextView android:id="@+id/returnTime"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dip"
            android:layout_marginBottom="8dip"
            android:layout_marginLeft="20dip"/>

        <TextView android:id="@+id/parkingReturn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dip"
            android:layout_marginBottom="8dip"
            android:layout_marginLeft="20dip"/>

        <TextView android:id="@+id/cost"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dip"
            android:layout_marginBottom="8dip"
            android:layout_marginLeft="20dip"/>

    </TableRow>
</TableLayout>

A: Use nested layouts like
 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    >

 <LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:layout_weight=".25">

  <Button
        android:id="@+id/play_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="left" />

    <Button
        android:id="@+id/stop_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="right" />

</LinearLayout>

 <LinearLayout
   android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:layout_weight=".25">

  <TextView
        android:id="@+id/play_button"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:text="12 02 14:07"
        android:layout_weight=".5"/>

    <TextView
        android:id="@+id/stop_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="12 02 14:07" />

</LinearLayout>

 <LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:layout_weight=".25">

  <TextView
        android:id="@+id/play_button"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:text="12 02 14:07"
        android:layout_weight=".5"/>

    <TextView
        android:id="@+id/stop_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="12 02 14:07" />

</LinearLayout>
<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:layout_weight=".25">

  <TextView
        android:id="@+id/play_button"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:text="12 02 14:07"
        android:layout_weight=".5"/>

    <TextView
        android:id="@+id/stop_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="12 02 14:07" />

</LinearLayout>
</LinearLayout>

</LinearLayout>

A: Remove the tag android:gravity="center" in the layout it will be good i think so.

A: Sorry dude, i was feeling very lazy so did not try to find the issue in your code, but instead wrote the correct one for you. here you go:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="70dp"
    android:background="#1E90FF"
    android:orientation="horizontal" >

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_margin="5dp"
        android:background="#87CEFA"
        android:orientation="vertical" >

        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="wrap_content"
            android:layout_height="30dp"
            android:src="@android:drawable/ic_media_previous" />

        <ImageView
            android:id="@+id/imageView2"
            android:layout_width="wrap_content"
            android:layout_height="30dp"
            android:src="@android:drawable/ic_media_next" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_margin="5dp"
        android:background="#87CEFA"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="30dp"
            android:gravity="center_vertical"
            android:singleLine="true"
            android:text="Medium Text"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="30dp"
            android:gravity="center_vertical"
            android:singleLine="true"
            android:text="Medium Text"
            android:textAppearance="?android:attr/textAppearanceMedium" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_margin="5dp"
        android:background="#87CEFA"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/textView3"
            android:layout_width="wrap_content"
            android:layout_height="30dp"
            android:gravity="center_vertical"
            android:singleLine="true"
            android:text="Medium Text"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <TextView
            android:id="@+id/textView4"
            android:layout_width="wrap_content"
            android:layout_height="30dp"
            android:gravity="center_vertical"
            android:singleLine="true"
            android:text="Medium Text"
            android:textAppearance="?android:attr/textAppearanceMedium" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_margin="5dp"
        android:background="#87CEFA"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/textView5"
            android:layout_width="wrap_content"
            android:layout_height="30dp"
            android:gravity="center_vertical"
            android:singleLine="true"
            android:text="Medium Text"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <TextView
            android:id="@+id/textView6"
            android:layout_width="wrap_content"
            android:layout_height="30dp"
            android:gravity="center_vertical"
            android:singleLine="true"
            android:text="Medium Text"
            android:textAppearance="?android:attr/textAppearanceMedium" />
    </LinearLayout>

</LinearLayout>

Please see what went wrong with your piece of code. Just for the sake of replying faster, i copy pasted the styling over and over again, you should specify that in styles and use it instead, follow the guidelines, it'll help you in the long run.
PFB the screen shot from graphical layout:

redpajama_set_name: RedPajamaStackExchange